LUIS Intent Score - azure-language-understanding

I am trying to built a sample using LUIS intents to call my API, but the intent score for "CharacterSearch" is something I am not able to understand.
Could anyone please look into below response and advise how the intent score is more than 1 or I am missing something here, intent score for "SearchSigil" is perfect.
My main concern is this a normal score ?
If needed I can post my intents and entities.
{
"query": "Which sigil displays three headed dragon",
"topScoringIntent": {
"intent": "SearchSigil",
"score": 0.9916578
},
"intents": [
{
"intent": "SearchSigil",
"score": 0.9916578
},
{
"intent": "SearchHouses",
"score": 0.0689159855
},
{
"intent": "None",
"score": 0.0170753412
},
{
"intent": "Help",
"score": 0.005770977
},
{
"intent": "Cancel",
"score": 0.00406856835
},
{
"intent": "Greeting",
"score": 0.00150005356
},
{
"intent": "CharacterSearch",
"score": 3.12414272E-08
}
],
"entities": [
{
"entity": "three headed dragon",
"type": "Sigil",
"startIndex": 21,
"endIndex": 39,
"resolution": {
"values": [
"three headed dragon"
]
}
}
]
}

Your score is not higher than 1.
The score 3.12414272E-08 equals 0.000000031241427
See: https://www.wolframalpha.com/input/?i=3.12414272E-08

Related

Elasticsearch Term suggester is not returning correct suggestions when one character is missing (instead of misspelling)

I'm using Elasticsearch term suggester for spell correction. my index contains huge list of ads. Each ad has subject and body fields. I've found a problematic example for which the suggester is not suggesting correct suggestions.
I have lots of ads whose subject contains word "soffa" and also 5 ads whose subject contain word "sofa". Ideally, when I send "sofa" (wrong spelling) as text to suggester, it should return "soffa" (correct spelling) as suggestions (since soffa is correct spell and most of ads contains "soffa" and only few ads contains "sofa" (wrong spell)).
Here is my suggester query body :
{
"suggest": {
"text": "sofa",
"subjectSuggester": {
"term": {
"field": "subject",
"suggest_mode": "popular",
"min_word_length": 1
}
}
}
}
When I send above query, I get below response :
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"suggest": {
"subjectSuggester": [
{
"text": "sof",
"offset": 0,
"length": 4,
"options": [
{
"text": "soff",
"score": 0.6666666,
"freq": 298
},
{
"text": "sol",
"score": 0.6666666,
"freq": 101
},
{
"text": "saf",
"score": 0.6666666,
"freq": 6
}
]
}
]
}
}
As you see in above response, it returned "soff" but not "soffa" although I have lots of docs whose subject contains "soffa".
I even played with parameters like suggest_mode and string_distance but still no luck.
I also used phrase suggester instead of term suggester but still same. Here is my phrase suggester query :
{
"suggest": {
"text": "sofa",
"subjectuggester": {
"phrase": {
"field": "subject",
"size": 10,
"gram_size": 3,
"direct_generator": [
{
"field": "subject.trigram",
"suggest_mode": "always",
"min_word_length":1
}
]
}
}
}
}
I somehow think it doesn't work when one character is missing instead of being misspelled. in the "soffa" example, one "f" is missing.
while it works fine for misspells e.g it works fine for "vovlo".
When I send "vovlo" it gives me "volvo".
Any help would be hugely appreciated.
Try changing the "string_distance".
{
"suggest": {
"text": "sof",
"subjectSuggester": {
"term": {
"field": "title",
"min_word_length":2,
"string_distance":"ngram"
}
}
}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#term-suggester
I've found the workaround myself.
I added ngram filter and analyzer with max_shingle_size 3 which means trigram, then added a subfield with that analyzer (trigram) and performed suggester query on that field (instead of actual field) and it worked.
Here is the mapping changes :
{
"settings": {
"analysis": {
"filter": {
"shingle": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 3
}
},
"analyzer": {
"trigram": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"shingle"
],
"char_filter": [
"diacritical_marks_filter"
]
}
}
}
},
"mappings": {
"properties": {
"subject": {
"type": "text",
"fields": {
"trigram": {
"type": "text",
"analyzer": "trigram"
}
}
}
}
}
}
And here is my corrected query :
{
"suggest": {
"text": "sofa",
"subjectSuggester": {
"term": {
"field": "subject.trigram",
"suggest_mode": "popular",
"min_word_length": 1,
"string_distance": "ngram"
}
}
}
}
Note that I'm performing suggester to subject.trigram instead of subject itself.
Here is the result :
{
"suggest": {
"subjectSuggester": [
{
"text": "sofa",
"offset": 0,
"length": 4,
"options": [
{
"text": "soffa",
"score": 0.8,
"freq": 282
},
{
"text": "soffan",
"score": 0.6666666,
"freq": 5
},
{
"text": "som",
"score": 0.625,
"freq": 102
},
{
"text": "sol",
"score": 0.625,
"freq": 82
},
{
"text": "sony",
"score": 0.625,
"freq": 50
}
]
}
]
}
}
As you can see above soffa appears as first suggestion.
There is sth weird in your result for the term suggester for the word sofa, take a look at the text that is being corrected:
"suggest": {
"subjectSuggester": [
{
"text": "sof",
"offset": 0,
"length": 4,
"options": [
{
"text": "soff",
"score": 0.6666666,
"freq": 298
},
{
"text": "sol",
"score": 0.6666666,
"freq": 101
},
{
"text": "saf",
"score": 0.6666666,
"freq": 6
}
]
}
]
}
As you can see it's sof and not sofa which means the correction is not for sofa but instead it's for sof, so I doubt that this issue is related to the analyzer you were using on this field, especially when looking at the results soff instead of soffa it's removing the last a

How to search multiple fields and aggregate scores?

I'm trying to figure out a solution to how I should structure my queries for finding answers to people's questions. For example, based off the dataset I will paste at the end of this post, I would like to query "Shows about romance", and maybe get results like so:
{
"hits": [
{
"_score": "31",
"_source": {
"anime": "Grisaia no Kajitsu"
}
},
{
"_score": "12",
"_source": {
"anime": "Mirai Nikki"
}
},
{
"_score": "7",
"_source": {
"anime": "Bakemonogatari"
}
}
]
}
Grisaia no Kajitsu shows up as the first result because it's shown in multiple relevant questions, and Mirai Nikki is second because it had a higher score than Bakemonogatari.
Basically I would like answers that are relevant based off the question, score, and tags field. Questions that have repeated answers should have a higher score. Any suggestions?
My dataset:
[
{
"question": "Looking for romance anime",
"score": 4,
"answers": [
{
"anime": "Mirai Nikki",
"score": 8,
"tags": ["action", "adventure", "death game", "romance"]
},
{
"anime": "Bakemonogatari",
"score": 3,
"tags": ["action", "comedy", "romance", "seinen"]
}
]
},
{
"question": "Survival Anime",
"score": 10,
"answers": [
{
"anime": "Grisaia no Kajitsu",
"score": 4,
"tags": ["school", "drama", "survival", "romance"]
},
{
"anime": "Kanata no Astra",
"score": 7,
"tags": ["action", "comedy", "drama", "space"]
}
]
},
{
"question": "Horror and romance anime?",
"score": 12,
"answers": [
{
"anime": "Grisaia no Kajitsu",
"score": 15,
"tags": ["school", "drama", "survival", "romance"]
}
]
}
]
This should work for you, you can tune various boost params around here and see how it affects your results
{
"_source": ["answers.anime"],
"query": {
"bool": {
"should": [
{
"term": {
"answers.tags": {
"value": "Shows about romance",
"boost": 2 //weight of tags field
}
}
},
{
"match": {
"question": {
"query": "Shows about romance",
"boost": 2 //weight of question field
}
}
},
{
"function_score": {
"min_score": 0.9,
"functions": [
{
"field_value_factor": {
"factor": 1, //weight of score field
"field": "answers.score",
"modifier": "log2p"
}
}
]
}
}
]
}
}
}

LuisIntent Attribute not being correctly recognised

I am working through a course Getting Started with Building Bots on the Microsoft Bot Framework and using some code from the course.
When I type "Hi" in the bot emulator, Luis realises that it is a Greeting Intent however the Bot catches it as a None Intent and says " I'm sorry I don't know what you mean"
[Serializable]
public class LUISDialog : LuisDialog<BugReport>
{
private readonly BuildFormDelegate<BugReport> NewBugReport;
public LUISDialog(BuildFormDelegate<BugReport> newBugReport)
{
this.NewBugReport = newBugReport;
}
[LuisIntent("Greeting")]
public async Task Greeting(IDialogContext context, LuisResult result)
{
context.Call(new GreetingDialog(), Callback);
}
[LuisIntent("")]
public async Task None(IDialogContext context, LuisResult result)
{
await context.PostAsync("I'm sorry I don't know what you mean.");
context.Wait(MessageReceived);
}
I have not set up any utterances for the None intent.
Below shows that the result is a Greeting Intent in the debugger:
The exported .json is as follows
{
"luis_schema_version": "3.0.0",
"versionId": "0.1",
"name": "sbdbotapp",
"desc": "",
"culture": "en-us",
"intents": [
{
"name": "GreetingIntent"
},
{
"name": "NewBugReportIntent"
},
{
"name": "None"
},
{
"name": "QueryBugType"
}
],
"entities": [
{
"name": "BugType",
"roles": []
}
],
"composites": [],
"closedLists": [],
"patternAnyEntities": [],
"regex_entities": [],
"prebuiltEntities": [
{
"name": "email",
"roles": []
}
],
"model_features": [],
"regex_features": [],
"patterns": [],
"utterances": [
{
"text": "bug report",
"intent": "NewBugReportIntent",
"entities": []
},
{
"text": "can you check whether foo is a bugtype?",
"intent": "QueryBugType",
"entities": [
{
"entity": "BugType",
"startPos": 22,
"endPos": 24
}
]
},
{
"text": "create bug",
"intent": "NewBugReportIntent",
"entities": []
},
{
"text": "good afternoon",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "good evening",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "good morning",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "hello",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "hey",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "hi",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "hi there",
"intent": "GreetingIntent",
"entities": []
},
{
"text": "i have a problem",
"intent": "NewBugReportIntent",
"entities": []
},
{
"text": "is security a bug type?",
"intent": "QueryBugType",
"entities": [
{
"entity": "BugType",
"startPos": 3,
"endPos": 10
}
]
},
{
"text": "something doesnt work",
"intent": "NewBugReportIntent",
"entities": []
},
{
"text": "yo",
"intent": "GreetingIntent",
"entities": []
}
]
}
[Update]
From DFBerry's help and re-looking at the course, I see the course is using the SDK, where as the Doc's tutorial uses a Web App Bot.
it's because the name of your intent is "greetingIntent" and in your code you have it labeled as just "greeting". Change your code to be "greetingIntent" and it should work.

LUIS is not updating the Intent "score" for one word

I am facing a weird issue with LUIS. I have a keyword "infopedia" which should fall in some other Intent but JSON is showing the Top Score for "None" Intent.
I tried to add the utterance, it's showing me fine when I am adding in utterance. But whenever I am querying that word, it's showing me "None" intent for the same.
Could you please help me how I can update the Score for particular intent? in order to get the correct result.
New utterances
Review labels
Query
Suggest:
{
"query": "infopedia",
"topScoringIntent": {
"intent": "None",
"score": 0.36293143
},
"intents": [
{
"intent": "None",
"score": 0.36293143
},
{
"intent": "TrendingItems",
"score": 0.262885571
},
{
"intent": "Thanks",
"score": 0.258188784
},
{
"intent": "Hi",
"score": 0.1920927
},
{
"intent": "WhatsUp",
"score": 0.08811139
},
{
"intent": "Bye",
"score": 0.006096343
}
],
"entities": [
{
"entity": "infopedia",
"type": "Keyword",
"startIndex": 0,
"endIndex": 8,
"score": 0.659655631
}
]
}

How to get parent objects and nested children objects by parent and children ids

I have a parent object (blogpost) and nested items (comments)
The parent and nested objects are both keyed by an id
So if I fetch the parent object, i will get all the children too
GET /my_index/blogpost/1
{
"id": 1,
"title": "Nest eggs",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"id": 2,
"comment": "Great article",
"age": 28,
"stars": 4,
"date": "2014-09-01"
},
{
"id": 4,
"comment": "More like this please",
"age": 31,
"stars": 5,
"date": "2014-10-22"
}
]
}
Question
However, I only want to fetch the parent and a subset of children based on children ids
e.g. My desired behaviour is this:
GET /my_index/blogpost/1?onlyGetCommentIds=4
{
"id": 1,
"title": "Nest eggs",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"id": 4,
"comment": "More like this please",
"age": 31,
"stars": 5,
"date": "2014-10-22"
}
]
}
See in the above example that only comment id == 4 is returned along with the parent object.
How do I construct this query?
You need to use nested inner_hits in order to achieve what you want
POST /my_index/blogpost/_search
{
"_source": {
"exclude": "comments"
},
"query": {
"bool": {
"filter": [
{
"term": {
"id": 1
}
},
{
"nested": {
"path": "comments",
"query": {
"term": {
"comments.id": 4
}
},
"inner_hits": {}
}
}
]
}
}
}
The response will include the parent object (without the comments nested objects) and another inner_hits section containing only the desired nested comment with id = 4.

Resources