import typing
from typing import Any, Optional, Text, Dict, List, Type
from rasa.nlu.components import Component
from rasa.nlu import utils
if typing.TYPE_CHECKING:
from rasa.nlu.model import Metadata
import rasa.utils.io as io_utils
from textblob import TextBlob
from rasa.nlu.config import RasaNLUModelConfig
from rasa.nlu.training_data import Message, TrainingData
from rasa.nlu.tokenizers.tokenizer import Tokenizer
class SentimentAnalyzer(Component):
"""A custom sentiment analysis component"""
"""A new component"""
@classmethod
def required_components(cls) -> List[Type[Component]]:
"""Specify which components need to be present in the pipeline."""
return [Tokenizer]
#language_list = ["en", "fr"]
language_list = None
defaults = {}
provides = ["entities"]
name = "sentiment"
def __init__(self, component_config: Optional[Dict[Text, Any]] = None) -> None:
super().__init__(component_config)
def train(
self,
training_data: TrainingData,
config: Optional[RasaNLUModelConfig] = None,
**kwargs: Any,
) -> None:
pass
def convert_to_rasa(self, sentiment, confidence):
"""Convert model output into the Rasa NLU compatible output format."""
entity = {"value": sentiment,
"entity": "sentiment",
"confidence":confidence,
"extractor": "sentiment_extractor"}
return entity
def preprocessing(self, tokens):
pass
def process(self, message: Message, **kwargs: Any) -> None:
testimonial = TextBlob(str(message.text))
if (testimonial.sentiment.polarity>0):
sentiment="pos"
elif (testimonial.sentiment.polarity<0):
sentiment="neg"
else:
sentiment="neu"
# To introduce confidence we can use and 'recenter' polarity (0 is neutral, 1 is positive, -1 is negative)
# It doesn't give very good confidence results though
confidence = (abs(abs(testimonial.sentiment.polarity)-0.5))/0.5
entity = self.convert_to_rasa(sentiment, confidence)
message.set("entities", [entity], add_to_output=True)
def persist(self, file_name: Text, model_dir: Text) -> Optional[Dict[Text, Any]]:
pass
@classmethod
def load(
cls,
meta: Dict[Text, Any],
model_dir: Optional[Text] = None,
model_metadata: Optional["Metadata"] = None,
cached_component: Optional["Component"] = None,
**kwargs: Any,
) -> "Component":
if cached_component:
return cached_component
else:
return cls(meta)