Issue with Entity Extraction using form, slots

Hi, I’m trying to create a basic data assistant chatbot which can extract country (country_name) & macro-economic indicator (macro) from an input text. Sharing below example for your reference -

Example Input – I need nominal_gdp for India Expected entities – country_name -> India, macro -> nominal_gdp

The list of values country_name & macro can take are in the actions.py file. And I am using forms, custom action to fill both the required slots/ entities. However, I am not able to extract the entity – macro correctly from unknow input sentence (By unknown - I mean those which are not there in the file -> data/nlu.md). Can you please guide what I am missing here which is not letting me extract the entity from unknown input sentence. I’m also using underscore in variable names (macro) which have more than one word.

You can have a look at my project folder from this link - Click to Retrieve File(s)

Please reach out If you need further information to be able to assist me. Also If I may request, can we get on a short call so I could demonstrate the issue & discuss the resolution? Would really appreciate it.

Waiting to hear from you at the earliest.

the ability to extract information from unseen examples depends on how well it is generalizable. Sorry, I cannot look into your project. Can you please post a couple of examples here

Sharing some examples - Input 1 -> Give me data for deposit_interest_rate for Germany Expected entities – country_name -> Germany, macro -> deposit_interest_rate (This works because it is present in data/nlu.md file under datarequest intent)

Input 1 -> I am looking for data of labour_force for Australia Expected entities – country_name -> Australia, macro -> labour_force (However in this case, macro is not extracted since ‘labour_force’ is not present in data/nlu.md datarequest intent examples). But, I do have the entire list of values ‘macro’ can take in the actions.py. I’m also pasting content from the actions file below.

I’m using country_name, macro as both entities, slots.

Also sharing the intent ‘datarequest’ from which these need to be extracted. /data/nlu.md

intent:datarequest


actions.py


from typing import Dict, Text, Any, List, Union, Optional

from rasa_sdk import Action, Tracker from rasa_sdk.executor import CollectingDispatcher from rasa_sdk import ActionExecutionRejection from rasa_sdk.events import SlotSet from rasa_sdk.forms import FormAction, REQUESTED_SLOT

class DataRequestForm(FormAction): “”“Example of a custom form action”""

def name(self):
# -> Text
    """Unique identifier of the form"""

    return "data_request_form"

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    """A list of required slots that the form has to fill"""

    return ["country_name", "macro"]

def slot_mappings(self):

-> Dict[Text,Union[Dict, List[Dict]]]:

    """A dictionary to map required slots to
        - an extracted entity
        - intent: value pairs
        - a whole message
        or a list of them, where a first match will be picked"""

    return {"country_name": self.from_entity(entity="country_name",intent="datarequest"),
            "macro": self.from_entity(entity="macro",intent="datarequest")}

@staticmethod
def country_name_db():

-> List[Text]

    """Database of supported country_names"""
    return ["australia",
            "germany",
            "india",
            "united_states"]

def validate_country_name(self,
                     value: Text,
                     dispatcher: CollectingDispatcher,
                     tracker: Tracker,
                     domain: Dict[Text, Any]) -> Optional[Text]:
    """Validate country_name value."""

    if value.lower() in self.country_name_db():
        # validation succeeded
        return {"country_name":value}
    else:
        dispatcher.utter_template('utter_wrong_country_name', tracker)
        # validation failed, set this slot to None, meaning the
        # user will be asked for the slot again
        return {"country_name": None}

@staticmethod
def macro_db():

-> List[Text]

    """Database of supported country_names"""
    return ["average_real_wage_index",
			"nominal_private_consumption",
			"net_financial_worth_of_households",
			"consumer_prices_real_percentage_change",
			"gdp_real_percentage_change",
			"personal_disposable_income",
			"nominal_domestic_demand",
			"average_real_wages_percentage_change",
			"nominal_exports_of_g&s",
			"nominal_gross_fixed_investment",
			"nominal_gdp",
			"households",
			"nominal_imports_of_g&s",
			"labour_force",
			"consumer_price_index",
			"lending_interest_rate",
			"passenger_car_registrations",
			"population",
			"deposit_interest_rate",
			"real_gdp"]

def validate_macro(self,
                     value: Text,
                     dispatcher: CollectingDispatcher,
                     tracker: Tracker,
                     domain: Dict[Text, Any]) -> Optional[Text]:
    """Validate country_name value."""

    if value.lower() in self.macro_db():
        # validation succeeded
        return {"macro":value}
    else:
        dispatcher.utter_template('utter_wrong_macro', tracker)
        # validation failed, set this slot to None, meaning the
        # user will be asked for the slot again
        return {"macro": None}	

def submit(self,
           dispatcher: CollectingDispatcher,
           tracker: Tracker,
           domain: Dict[Text, Any]) -> List[Dict]:
    """Define what the form has to do
        after all required slots are filled"""

    # utter submit template
    dispatcher.utter_template('utter_data_checking', tracker)
    return []

Do you mean, it cannot extract unseen country?