@b4usat If what you want is the other intent (the non Non intent) to be the "real" winner, then the solution #816 still applies. Basically you inherit from LuisDialog and override BestResultFrom. The original implementation is:
protected virtual LuisServiceResult BestResultFrom(IEnumerable<LuisResult> results)
{
var winners = from result in results
let resultWinner = BestIntentFrom(result)
where resultWinner != null
select new LuisServiceResult(result, resultWinner);
return winners.MaxBy(i => i.BestIntent.Score ?? 0d);
}
you can change it into something like this:
protected override LuisServiceResult BestResultFrom(IEnumerable<LuisResult> results)
{
var winners = from result in results
let resultWinner = BestIntentFrom(result)
where resultWinner != null
select new LuisServiceResult(result, resultWinner);
var nonNoneWinner = winners.Where(i => i.BestIntent.Intent != "None").MaxBy(i => i.BestIntent.Score ?? 0d);
return nonNoneWinner?? winners.MaxBy(i => i.BestIntent.Score ?? 0d);
}
This helps in cases where at least one of your LUIS models returns a non None intent. Otherwise you need to also override BestIntentFrom.
@eydelrivero Thanks a lot for your reply. But unfortunately still the context redirects to None Intent. THe Override BestResultFrom gives the correct Intent, but the IntentHandler doesn't have the Intents of the first model. It only stores the intents of second referenced model. :(
GetHandlersByIntent method.
@b4usat the solution by @eydelrivero looks correct to me. Are you using the newest version of the SDK? The GetHandlersByIntent method is supposed to return all applicable handlers.
@willportnoy Yes i am using the latest version 3.2.0 SDK. GetHandlersByIntent method returning only the second models Intents
I guess the issue of @eydelrivero's solution is the None intent comes with empty identifier, so the nonNoneWinner might be determined as
c#
var nonNoneWinner = winners.Where(i => string.IsNullOrEmpty(i.BestIntent.Intent) == false).MaxBy(i => i.BestIntent.Score ?? 0d);
@evnik it could be - the GetHandlersByIntent method doesn't even know which model the intents come from (when it looks for matching delegates from the class through reflection), so i don't think it's actually filtering them for just the second model.
However I think selection of a non-None from all the winners doesn't provide the best result for this case. For example, for these LUIS results from two models:
| Model1 | Model2 |
| --- | --- |
| None: 0.35 | B: 0.1 |
| A: 0.3 | None: 0.05 |
this approach will give us B, while A is better candidate.
I suggest to search a winner through results of all models:
c#
protected override LuisServiceResult BestResultFrom(IEnumerable<LuisResult> results)
{
var allResults =
from result in results
from intent in result.Intents
select new LuisServiceResult(result, intent);
var nonNoneWinner = allResults.Where(i => string.IsNullOrEmpty(i.BestIntent.Intent) == false).MaxBy(i => i.BestIntent.Score ?? 0d);
return nonNoneWinner ?? allResults.MaxBy(i => i.BestIntent.Score ?? 0d);
}
@evnik, @eydelrivero Thanks a lot for great trick. This solution is working great. But have one doubt as well. Say my first model returning "None" Intent with score 0.4 and my second model which actually trained for the questioned utterences is having a intent "Travel" with score 0.2 will lead the handler to None Task. But if the case i have given only second model, it will land in Travel Task even if the score is low.
@willportnoy GetHandlersByIntent method identifies all the delegates in a single class "Class A". Is there any possibilities i can define my Task in separate class "Class B" and move my handler to Class B which actually have the defined Intent?
protected virtual IDictionary<string, IntentActivityHandler> GetHandlersByIntent()
{
return LuisDialog.EnumerateHandlers(this).ToDictionary(kv => kv.Key, kv => kv.Value);
}
overriding is not allowing since LuisDialog is Internal
Hello i tried override the GetHandlerByIntent and identify the IntentHandlers in different class. Below my code. Please review this
protected override IDictionary<string, IntentActivityHandler> GetHandlersByIntent()
{
var classCollection = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsSubclassOf(typeof(BaseForm)));
List<KeyValuePair<string, IntentActivityHandler>> handler = new List<KeyValuePair<string, IntentActivityHandler>>();
foreach (var item in classCollection)
{
handler.AddRange(MyLuisDialog.EnumerateHandlers(Activator.CreateInstance(item)).ToList());
}
return handler.ToDictionary(kv => kv.Key, kv => kv.Value);
}
Here MyLuisDialog class is my own custom class which uses the same EnumerateHandlers handlers method.
That seems like a reasonable way to enumerable intent handlers across several classes.
However, using intent handlers spread across different classes is not a scenario that we've tested much.
I'm going to close this issue, but free to open a new issue for further discussions.
Hi ,
I faced one problem in getting document file throw WebAPI in below code.
[LuisIntent("APITest")]
public async Task APITest(IDialogContext context, LuisResult result)
{
HttpClient client = new HttpClient();
string searchValue = string.Empty;
HttpResponseMessage test = null;
client.BaseAddress = new Uri("http://localhost:3979/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
HttpResponseMessage response = await client.GetAsync("api/Registration?key=doc");
if (response.IsSuccessStatusCode)
{
test = await response.Content.ReadAsHttpResponseMessageAsync();
}
await context.PostAsync(test);
context.Wait(MessageReceived);
}
in Response i got file but getting error to post response await context.PostAsync(test); can you please help me to post response ?
thanks
upendra
@upendra1588 if you have a usage question, I'd post to stack overflow - we're trying to keep GitHub for bugs.
Most helpful comment
That seems like a reasonable way to enumerable intent handlers across several classes.
However, using intent handlers spread across different classes is not a scenario that we've tested much.