rasahq--rasa
dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
179 行
7.0 KiB
Python
179 行
7.0 KiB
Python
from __future__ import annotations
|
|
import os
|
|
from typing import Any, Dict, List, Optional, Text
|
|
import logging
|
|
|
|
from rasa.engine.graph import GraphComponent, ExecutionContext
|
|
from rasa.engine.recipes.default_recipe import DefaultV1Recipe
|
|
from rasa.shared.constants import DOCS_URL_TRAINING_DATA
|
|
from rasa.shared.nlu.constants import ENTITIES, TEXT
|
|
from rasa.shared.nlu.training_data.training_data import TrainingData
|
|
from rasa.shared.nlu.training_data.message import Message
|
|
from rasa.nlu.utils import write_json_to_file
|
|
from rasa.nlu.extractors.extractor import EntityExtractorMixin
|
|
import rasa.utils.io
|
|
import rasa.shared.utils.io
|
|
from rasa.engine.storage.resource import Resource
|
|
from rasa.engine.storage.storage import ModelStorage
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@DefaultV1Recipe.register(
|
|
DefaultV1Recipe.ComponentType.ENTITY_EXTRACTOR, is_trainable=True
|
|
)
|
|
class EntitySynonymMapper(GraphComponent, EntityExtractorMixin):
|
|
"""Maps entities to their synonyms if they appear in the training data."""
|
|
|
|
SYNONYM_FILENAME = "synonyms.json"
|
|
|
|
def __init__(
|
|
self,
|
|
config: Optional[Dict[Text, Any]],
|
|
model_storage: ModelStorage,
|
|
resource: Resource,
|
|
synonyms: Optional[Dict[Text, Any]] = None,
|
|
) -> None:
|
|
"""Creates the mapper.
|
|
|
|
Args:
|
|
config: The mapper's config.
|
|
model_storage: Storage which the component can use to persist and load
|
|
itself.
|
|
resource: Resource locator for this component which can be used to persist
|
|
and load itself from the `model_storage`.
|
|
synonyms: A dictionary of previously known synonyms.
|
|
"""
|
|
self._config = config
|
|
self._model_storage = model_storage
|
|
self._resource = resource
|
|
|
|
self.synonyms = synonyms if synonyms else {}
|
|
|
|
@classmethod
|
|
def create(
|
|
cls,
|
|
config: Dict[Text, Any],
|
|
model_storage: ModelStorage,
|
|
resource: Resource,
|
|
execution_context: ExecutionContext,
|
|
synonyms: Optional[Dict[Text, Any]] = None,
|
|
) -> EntitySynonymMapper:
|
|
"""Creates component (see parent class for full docstring)."""
|
|
return cls(config, model_storage, resource, synonyms)
|
|
|
|
def train(self, training_data: TrainingData) -> Resource:
|
|
"""Trains the synonym lookup table."""
|
|
for key, value in list(training_data.entity_synonyms.items()):
|
|
self._add_entities_if_synonyms(key, value)
|
|
|
|
for example in training_data.entity_examples:
|
|
for entity in example.get(ENTITIES, []):
|
|
entity_val = example.get(TEXT)[entity["start"] : entity["end"]]
|
|
self._add_entities_if_synonyms(entity_val, str(entity.get("value")))
|
|
|
|
self._persist()
|
|
return self._resource
|
|
|
|
def process(self, messages: List[Message]) -> List[Message]:
|
|
"""Modifies entities attached to message to resolve synonyms.
|
|
|
|
Args:
|
|
messages: List containing the latest user message
|
|
|
|
Returns:
|
|
List containing the latest user message with entities resolved to
|
|
synonyms if there is a match.
|
|
"""
|
|
for message in messages:
|
|
updated_entities = message.get(ENTITIES, [])[:]
|
|
self.replace_synonyms(updated_entities)
|
|
message.set(ENTITIES, updated_entities, add_to_output=True)
|
|
|
|
return messages
|
|
|
|
def _persist(self) -> None:
|
|
if self.synonyms:
|
|
with self._model_storage.write_to(self._resource) as storage:
|
|
entity_synonyms_file = storage / EntitySynonymMapper.SYNONYM_FILENAME
|
|
|
|
write_json_to_file(
|
|
entity_synonyms_file, self.synonyms, separators=(",", ": ")
|
|
)
|
|
|
|
# Adapt to get path from model storage and resource
|
|
@classmethod
|
|
def load(
|
|
cls,
|
|
config: Dict[Text, Any],
|
|
model_storage: ModelStorage,
|
|
resource: Resource,
|
|
execution_context: ExecutionContext,
|
|
**kwargs: Any,
|
|
) -> EntitySynonymMapper:
|
|
"""Loads trained component (see parent class for full docstring)."""
|
|
synonyms = None
|
|
try:
|
|
with model_storage.read_from(resource) as storage:
|
|
entity_synonyms_file = storage / EntitySynonymMapper.SYNONYM_FILENAME
|
|
|
|
if os.path.isfile(entity_synonyms_file):
|
|
synonyms = rasa.shared.utils.io.read_json_file(entity_synonyms_file)
|
|
else:
|
|
synonyms = None
|
|
rasa.shared.utils.io.raise_warning(
|
|
f"Failed to load synonyms file from '{entity_synonyms_file}'.",
|
|
docs=DOCS_URL_TRAINING_DATA + "#synonyms",
|
|
)
|
|
except ValueError:
|
|
logger.debug(
|
|
f"Failed to load {cls.__class__.__name__} from model storage. Resource "
|
|
f"'{resource.name}' doesn't exist."
|
|
)
|
|
|
|
return cls(config, model_storage, resource, synonyms)
|
|
|
|
def replace_synonyms(self, entities: List[Dict[Text, Any]]) -> None:
|
|
"""Replace any entities which match a synonym with the synonymous entity."""
|
|
for entity in entities:
|
|
# need to wrap in `str` to handle e.g. entity values of type int
|
|
entity_value = str(entity["value"])
|
|
if entity_value.lower() in self.synonyms:
|
|
entity["value"] = self.synonyms[entity_value.lower()]
|
|
self.add_processor_name(entity)
|
|
|
|
def _add_entities_if_synonyms(self, entity: Text, synonym: Optional[Text]) -> None:
|
|
"""Adds entities to the synonym lookup table.
|
|
|
|
Lowercase is used as keys to make the lookup case-insensitive.
|
|
"""
|
|
if synonym is not None:
|
|
entity = str(entity)
|
|
synonym = str(synonym)
|
|
if entity != synonym:
|
|
entity_lowercase = entity.lower()
|
|
if (
|
|
entity_lowercase in self.synonyms
|
|
and self.synonyms[entity_lowercase] != synonym
|
|
):
|
|
rasa.shared.utils.io.raise_warning(
|
|
f"Found conflicting synonym definitions "
|
|
f"for {repr(entity_lowercase)}. Overwriting target "
|
|
f"{repr(self.synonyms[entity_lowercase])} with "
|
|
f"{repr(synonym)}. "
|
|
f"Check your training data and remove "
|
|
f"conflicting synonym definitions to "
|
|
f"prevent this from happening.",
|
|
docs=DOCS_URL_TRAINING_DATA + "#synonyms",
|
|
)
|
|
|
|
self.synonyms[entity_lowercase] = synonym
|
|
|
|
# add a self-reference to handle entities extracted in alternate cases
|
|
# i.e. for a synonym Austria,
|
|
# entities extracted as AUSTRIA, austria, ausTRIA, etc
|
|
# should also have the value of `Austria`
|
|
synonym_lowercase = synonym.lower()
|
|
if synonym_lowercase not in self.synonyms:
|
|
self.synonyms[synonym_lowercase] = synonym
|