newbie
newbie

Reputation: 11

How to extract entity from Microsoft LUIS using python?

Following the example code in this link, I can extract the intent using "intent_result.intent_id", but how can I extract the entity/entities of the utterance?

'''

import azure.cognitiveservices.speech as speechsdk

print("Say something...")

intent_config = speechsdk.SpeechConfig(subscription="YourLanguageUnderstandingSubscriptionKey", region="YourLanguageUnderstandingServiceRegion")

intent_recognizer = speechsdk.intent.IntentRecognizer(speech_config=intent_config)

model = speechsdk.intent.LanguageUnderstandingModel(app_id="YourLanguageUnderstandingAppId")
intents = [
    (model, "HomeAutomation.TurnOn"),
    (model, "HomeAutomation.TurnOff")
]
intent_recognizer.add_intents(intents)

start_continuous_recognition() instead.
intent_result = intent_recognizer.recognize_once()

if intent_result.reason == speechsdk.ResultReason.RecognizedIntent:
    print("Recognized: \"{}\" with intent id `{}`".format(intent_result.text, intent_result.intent_id))
elif intent_result.reason == speechsdk.ResultReason.RecognizedSpeech:
    print("Recognized: {}".format(intent_result.text))
elif intent_result.reason == speechsdk.ResultReason.NoMatch:
    print("No speech could be recognized: {}".format(intent_result.no_match_details))
elif intent_result.reason == speechsdk.ResultReason.Canceled:
    print("Intent recognition canceled: {}".format(intent_result.cancellation_details.reason))
    if intent_result.cancellation_details.reason == speechsdk.CancellationReason.Error:
        print("Error details: {}".format(intent_result.cancellation_details.error_details))
# </IntentRecognitionOnceWithMic>

'''

Upvotes: 1

Views: 260

Answers (1)

KingKong BigBong
KingKong BigBong

Reputation: 313

from azure.cognitiveservices.language.luis.runtime import LUISRuntimeClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.language.luis.runtime.models import EntityModel
from collections import OrderedDict
from typing import Union


class LuisPredictionClass():
    def __init__(self, endpoint, appIdLUIS, predictionResourcePrimaryKey):
        self.endpoint = endpoint
        self.appIdLUIS = appIdLUIS
        self.predictionResourcePrimaryKey = predictionResourcePrimaryKey

        self.client = LUISRuntimeClient(self.endpoint, CognitiveServicesCredentials(self.predictionResourcePrimaryKey))
    
    def find_LUIS_result(self,Text):
        luis_result = self.client.prediction.resolve(self.appIdLUIS,Text)
        return luis_result


    def extract_entity_value(self,entity: EntityModel) -> object:
        if (entity.additional_properties is None or "resolution" not in entity.additional_properties ):
            return entity.entity

        resolution = entity.additional_properties["resolution"]
        if entity.type.startswith("builtin.datetime."):
            return resolution
        if entity.type.startswith("builtin.datetimeV2."):
            if not resolution["values"]:
                return resolution

            resolution_values = resolution["values"]
            val_type = resolution["values"][0]["type"]
            timexes = [val["timex"] for val in resolution_values]
            distinct_timexes = list(OrderedDict.fromkeys(timexes))
            return {"type": val_type, "timex": distinct_timexes}

        if entity.type in {"builtin.number", "builtin.ordinal"}:
            return self.number(resolution["value"])
        if entity.type == "builtin.percentage":
            svalue = str(resolution["value"])
            if svalue.endswith("%"):
                svalue = svalue[:-1]

            return self.number(svalue)
        if entity.type in {
            "builtin.age",
            "builtin.dimension",
            "builtin.currency",
            "builtin.temperature",
            }:
            units = resolution["unit"]
            val = self.number(resolution["value"])
            obj = {}
            if val is not None:
                obj["number"] = val

            obj["units"] = units
            return obj
        value = resolution.get("value")
        return value if value is not None else resolution.get("values")


    def extract_normalized_entity_name(self,entity: EntityModel) -> str:
        # Type::Role -> Role
        type = entity.type.split(":")[-1]
        if type.startswith("builtin.datetimeV2."):
            type = "datetime"

        if type.startswith("builtin.currency"):
            type = "money"

        if type.startswith("builtin."):
            type = type[8:]

        role = (
            entity.additional_properties["role"]
            if entity.additional_properties is not None
            and "role" in entity.additional_properties
            else ""
        )
        if role and not role.isspace():
            type = role

        return type.replace(".", "_").replace(" ", "_")

Now you can run it as:

LuisPrediction = LuisPredictionClass("<<endpoint>>", "<<appIdLUIS>>", "<<predictionResourcePrimaryKey>>")

luis_result = LuisPrediction.find_LUIS_result("<<YOUR STRING HERE>>")
if len(luis_result.entities) > 0:
    for i in luis_result.entities:
        print(LuisPrediction.extract_normalized_entity_name(i),' : ',LuisPrediction.extract_entity_value(i))

Upvotes: 1

Related Questions