Skip to content

Commit 5a3e5cf

Browse files
committed
Convert timestamp to opt-in feature
Not convinced that we need to do this, but we can spare a few bytes in the NLU results files by only including the timestamp when requested via CLI argument.
1 parent 503d2c5 commit 5a3e5cf

File tree

11 files changed

+49
-21
lines changed

11 files changed

+49
-21
lines changed

docs/Test.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ See [Caching speech-to-text transcriptions](#caching-speech-to-text-transcriptio
140140

141141
This is currently only used for LUIS, see the section on LUIS prebuilt entities in [Configuring prebuilt entities](LuisModelConfiguration.md#configuring-prebuilt-entities).
142142

143+
### `--timestamp`
144+
(Optional) Signals whether to add a timestamp to each NLU test result.
145+
146+
See the documentation on the [`timestamp` property](UtteranceExtensions.md#returning-timestamps-for-each-query) for more details.
147+
143148
### `-i, --include`
144149
(Optional) Path to custom NLU provider DLL. See documentation about [Specifying the include path](https://github.com/microsoft/NLU.DevOps/blob/master/docs/CliExtensions.md#specifying-the-include-path) for more details.
145150

docs/UtteranceExtensions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ When an NLU provider in NLU.DevOps returns a prediction result, the value will b
2222
```
2323
In this case, the intent confidence score was `0.99` and the text transcription confidence score was `0.95`. This is useful context when debugging false predictions, as a low confidence score may indicate that the model could be improved with more training examples. The recognized `genre` entity also includes a confidence score of `0.80`, although it should be noted that only the LUIS provider currently returns confidence score for entity types trained from examples.
2424

25-
## Labeled utterance timestamps
25+
## Returning timestamps for each query
2626

2727
When analyzing results for a set of NLU predictions, it is often important context to understand when the test was run. For example, for Dialogflow `date` and `time` entities, the service only returns a date time string, and no indication of what token(s) triggered that entity to be recognized. For example, the result from a query like `"Call a taxi in 15 minutes"` may look like the following:
2828
```json
@@ -38,7 +38,7 @@ When analyzing results for a set of NLU predictions, it is often important conte
3838
"timestamp": "2020-01-01T00:00:00-04:00"
3939
}
4040
```
41-
Without the context provided by the `timestamp` property, we wouldn't be able to make any assertion about the correctness of the `entityValue` property for time. Currently, LUIS, Lex, and Dialogflow return a timestamp for each prediction result.
41+
Without the context provided by the `timestamp` property, we wouldn't be able to make any assertion about the correctness of the `entityValue` property for time. Currently, you must specify the [`--timestamp`](Test.md#--timestamp) option to ensure a timestamp is assigned to each NLU prediction result.
4242

4343
## Adjusting entity compare results
4444

src/NLU.DevOps.CommandLine/Test/TestCommand.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ namespace NLU.DevOps.CommandLine.Test
66
using System;
77
using System.Collections.Generic;
88
using System.IO;
9+
using System.Threading;
910
using System.Threading.Tasks;
11+
using Core;
1012
using Models;
1113
using Newtonsoft.Json.Linq;
1214
using static Serializer;
@@ -31,7 +33,8 @@ public override int Main()
3133

3234
protected override INLUTestClient CreateNLUTestClient()
3335
{
34-
return NLUClientFactory.CreateTestInstance(this.Options, this.Configuration, this.Options.SettingsPath);
36+
var client = NLUClientFactory.CreateTestInstance(this.Options, this.Configuration, this.Options.SettingsPath);
37+
return this.Options.Timestamp ? new TimestampNLUTestClient(client) : client;
3538
}
3639

3740
private static void EnsureDirectory(string filePath)
@@ -129,5 +132,34 @@ private void SaveTranscriptions()
129132
yield return (query, speechFile);
130133
}
131134
}
135+
136+
private class TimestampNLUTestClient : INLUTestClient
137+
{
138+
public TimestampNLUTestClient(INLUTestClient client)
139+
{
140+
this.Client = client;
141+
}
142+
143+
private INLUTestClient Client { get; }
144+
145+
public async Task<LabeledUtterance> TestAsync(JToken query, CancellationToken cancellationToken)
146+
{
147+
var timestamp = DateTimeOffset.Now;
148+
var result = await this.Client.TestAsync(query, cancellationToken).ConfigureAwait(false);
149+
return result.WithTimestamp(timestamp);
150+
}
151+
152+
public async Task<LabeledUtterance> TestSpeechAsync(string speechFile, JToken query, CancellationToken cancellationToken)
153+
{
154+
var timestamp = DateTimeOffset.Now;
155+
var result = await this.Client.TestSpeechAsync(speechFile, query, cancellationToken).ConfigureAwait(false);
156+
return result.WithTimestamp(timestamp);
157+
}
158+
159+
public void Dispose()
160+
{
161+
this.Client.Dispose();
162+
}
163+
}
132164
}
133165
}

src/NLU.DevOps.CommandLine/Test/TestOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ internal class TestOptions : BaseOptions
2525

2626
[Option('p', "parallelism", HelpText = "Numeric value to determine the numer of parallel tests. Default value is 3.", Required = false)]
2727
public int Parallelism { get; set; } = 3;
28+
29+
[Option("timestamp", HelpText = "Assign a timestamp to each utterance result.", Required = false)]
30+
public bool Timestamp { get; set; }
2831
}
2932
}

src/NLU.DevOps.Dialogflow/DialogflowNLUTestClient.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ protected override async Task<LabeledUtterance> TestAsync(string utterance, Canc
7878
result.QueryResult.Intent.DisplayName,
7979
result.QueryResult.Parameters?.Fields.SelectMany(GetEntities).ToList())
8080
.WithScore(result.QueryResult.IntentDetectionConfidence)
81-
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence)
82-
.WithTimestamp(DateTimeOffset.Now);
81+
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence);
8382
},
8483
cancellationToken)
8584
.ConfigureAwait(false);
@@ -115,8 +114,7 @@ protected override async Task<LabeledUtterance> TestSpeechAsync(string speechFil
115114
result.QueryResult.Intent.DisplayName,
116115
result.QueryResult.Parameters?.Fields.SelectMany(GetEntities).ToList())
117116
.WithScore(result.QueryResult.IntentDetectionConfidence)
118-
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence)
119-
.WithTimestamp(DateTimeOffset.Now);
117+
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence);
120118
},
121119
cancellationToken)
122120
.ConfigureAwait(false);

src/NLU.DevOps.Lex.Tests/LexNLUTestClientTests.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ public static async Task TestsWithSpeech(string slots, string entityType, string
8686
// assert reads content from file (file contents are "hello world")
8787
content.Should().Be("hello world");
8888

89-
// assert result type
90-
result.Should().BeOfType<JsonLabeledUtterance>();
91-
9289
// assert intent and text
9390
result.Intent.Should().Be(intent);
9491
result.Text.Should().Be(transcript);
@@ -121,7 +118,6 @@ public static async Task CreatesLabeledUtterances()
121118
using (var lex = new LexNLUTestClient(string.Empty, string.Empty, mockClient.Object))
122119
{
123120
var response = await lex.TestAsync(text).ConfigureAwait(false);
124-
response.Should().BeOfType<JsonLabeledUtterance>();
125121
response.Text.Should().Be(text);
126122
response.Intent.Should().Be(intent);
127123
response.Entities.Should().BeEmpty();

src/NLU.DevOps.Lex/LexNLUTestClient.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ protected override async Task<LabeledUtterance> TestAsync(string utterance, Canc
8787
.Select(slot => new Entity(slot.Key, slot.Value, null, 0))
8888
.ToArray();
8989

90-
return new LabeledUtterance(utterance, postTextResponse.IntentName, entities)
91-
.WithTimestamp(DateTimeOffset.Now);
90+
return new LabeledUtterance(utterance, postTextResponse.IntentName, entities);
9291
}
9392

9493
/// <inheritdoc />
@@ -118,8 +117,7 @@ protected override async Task<LabeledUtterance> TestSpeechAsync(string speechFil
118117
.ToArray()
119118
: null;
120119

121-
return new JsonLabeledUtterance(postContentResponse.InputTranscript, postContentResponse.IntentName, slots)
122-
.WithTimestamp(DateTimeOffset.Now);
120+
return new LabeledUtterance(postContentResponse.InputTranscript, postContentResponse.IntentName, slots);
123121
}
124122
}
125123

src/NLU.DevOps.Luis.Tests/LuisNLUTestClientTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public static async Task TestModel()
6666
using (var luis = builder.Build())
6767
{
6868
var result = await luis.TestAsync(test).ConfigureAwait(false);
69-
result.Should().BeOfType<JsonLabeledUtterance>();
7069
result.Text.Should().Be(test);
7170
result.Intent.Should().Be("intent");
7271
result.Entities.Count.Should().Be(1);

src/NLU.DevOps.Luis/LuisNLUTestClient.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ roleValue is string role &&
134134
speechLuisResult.LuisResult.Entities?.Select(getEntity).ToList())
135135
.WithProperty("intents", speechLuisResult.LuisResult.Intents)
136136
.WithScore(speechLuisResult.LuisResult.TopScoringIntent?.Score)
137-
.WithTextScore(speechLuisResult.TextScore)
138-
.WithTimestamp(DateTimeOffset.Now);
137+
.WithTextScore(speechLuisResult.TextScore);
139138
}
140139
}
141140
}

src/NLU.DevOps.LuisV3.Tests/LuisNLUTestClientTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public static async Task TestModel()
7070
using (var luis = builder.Build())
7171
{
7272
var result = await luis.TestAsync(test).ConfigureAwait(false);
73-
result.Should().BeOfType<JsonLabeledUtterance>();
7473
result.Text.Should().Be(test);
7574
result.Intent.Should().Be("intent");
7675
result.Entities.Count.Should().Be(1);

0 commit comments

Comments
 (0)