nlu_adapter 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +15 -8
- data/lib/nlu_adapter/dialogflow.rb +6 -1
- data/lib/nlu_adapter/lex.rb +4 -2
- data/lib/nlu_adapter/parse_helper.rb +167 -13
- data/lib/nlu_adapter/version.rb +1 -1
- data/lib/nlu_adapter/watson_assistant.rb +4 -2
- data/nlu_adapter.gemspec +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40656e57b36f5684b58789c2fc8756f6c311c5e5cd54e3151a61687df70ba2c8
|
4
|
+
data.tar.gz: 494f66bdcb5bc7083e048d2da54ec7e64b7bd1a5d1edd26b6a6ae287f1102b2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5eaa23df59165d67b674e7a96cd53e65353548fa3ef34cfb9f56e818468ab383fbab98cddab7f8cc1233fae1caec4f7afa9280c2784e795b205f3275e48faa5d
|
7
|
+
data.tar.gz: 0aada1752399c7a77b921e9ec9e8bc1cfb6a400cb571f124431393bee12a6e435b1d2321f4903ac91f30c5f3b8e783129a8b8fdfa85c91c92fae2ff77c8b1648
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -21,17 +21,17 @@ Or install it yourself as:
|
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
24
|
-
Check [documentation](docs) for usage.
|
24
|
+
* Check [documentation](docs) for usage.
|
25
|
+
* Check [nlu toolset](https://github.com/technopreneurG/nlu_tools_ruby) on how this lib is utilised to create cli tools.
|
25
26
|
|
26
27
|
## NLU Adapter support matrix
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
[
|
33
|
-
[
|
34
|
-
[IBM Watson Assistant](https://cloud.ibm.com/catalog/services/watson-assistant) ([doc](docs/watson_assistant.md)) | C,R,U | To-Do | Yes
|
29
|
+
| NLU Service | Intent | Intent | Intent | Intent Collection | Intent Collection | Intent Collection | Intent identification
|
30
|
+
|--- | --- | --- | --- | --- | --- | --- | ---
|
31
|
+
| | **Create** | **Get** | **Update** | **Create** | **Get** | **Update** |
|
32
|
+
[Aws Lex](https://aws.amazon.com/lex/) ([doc](docs/lex.md)) | Yes | Yes | Yes | Yes | Yes | Yes | Yes
|
33
|
+
[Google Dialogflow](https://dialogflow.com/) ([doc](docs/dialogflow.md)) | Yes | Yes | Yes | To-Do | To-Do | To-Do | Yes
|
34
|
+
[IBM Watson Assistant](https://cloud.ibm.com/catalog/services/watson-assistant) ([doc](docs/watson_assistant.md)) | Yes | Yes | Yes | To-Do | To-Do | To-Do | Yes
|
35
35
|
|
36
36
|
## Classification metrics
|
37
37
|
### Supported intent classification metrics
|
@@ -40,6 +40,13 @@ NLU Service | Intent | Intet Collection | Intent identification
|
|
40
40
|
* Precision (per Class)
|
41
41
|
* Recall (per Class)
|
42
42
|
|
43
|
+
### Supported intent classification report formats
|
44
|
+
* JSON
|
45
|
+
* CSV
|
46
|
+
* YAML
|
47
|
+
* Ruby-Hash
|
48
|
+
|
49
|
+
|
43
50
|
## Development
|
44
51
|
|
45
52
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -22,10 +22,15 @@ module NluAdapter
|
|
22
22
|
sessions_client = Google::Cloud::Dialogflow::Sessions.new(version: :v2)
|
23
23
|
formatted_session = Google::Cloud::Dialogflow::V2::SessionsClient.session_path(@project_id, @session_id)
|
24
24
|
language_code = 'en'
|
25
|
+
intent_name = :NO_INTENT_FOUND
|
26
|
+
|
25
27
|
query_input = Google::Cloud::Dialogflow::V2::QueryInput.new({text: {language_code: language_code, text: text}})
|
26
28
|
response = sessions_client.detect_intent(formatted_session, query_input)
|
27
29
|
|
28
|
-
|
30
|
+
unless response.nil? || response.query_result.nil? || response.query_result.intent.nil? || response.query_result.intent.display_name.empty?
|
31
|
+
intent_name = response.query_result.intent.display_name
|
32
|
+
end
|
33
|
+
return { intent_name: intent_name }
|
29
34
|
end
|
30
35
|
|
31
36
|
# Get an instance of Intent, if it exists else nil
|
data/lib/nlu_adapter/lex.rb
CHANGED
@@ -23,7 +23,7 @@ module NluAdapter
|
|
23
23
|
# @return [Json] return the identified intent name
|
24
24
|
#
|
25
25
|
def parse(text)
|
26
|
-
intent_name =
|
26
|
+
intent_name = :NO_INTENT_FOUND
|
27
27
|
begin
|
28
28
|
resp = @lex_client.post_text({
|
29
29
|
bot_name: @bot_name, # required
|
@@ -38,7 +38,9 @@ module NluAdapter
|
|
38
38
|
input_text: text, # required
|
39
39
|
})
|
40
40
|
|
41
|
-
intent_name
|
41
|
+
unless resp.intent_name.nil? || resp.intent_name.empty?
|
42
|
+
intent_name = resp.intent_name #=> String
|
43
|
+
end
|
42
44
|
rescue Aws::Lex::Errors::ServiceError => e
|
43
45
|
puts "Error: #{e.inspect}"
|
44
46
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'csv'
|
2
2
|
require 'json'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
#helper functions to parse text and match intent
|
5
6
|
module NluAdapter
|
@@ -28,19 +29,63 @@ module NluAdapter
|
|
28
29
|
#
|
29
30
|
# Example input/output
|
30
31
|
# test_data
|
31
|
-
#
|
32
|
+
# {
|
33
|
+
# "Intent1"=>["APR for personal credit cards", "interest rates for personal credit cards"],
|
34
|
+
# "Intent2"=>["Am I still part of the rewards program?", "Am I still in the loyalty program?"]
|
35
|
+
# }
|
32
36
|
# test_results
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
37
|
+
# json:
|
38
|
+
# [
|
39
|
+
# {
|
40
|
+
# "text" : "APR for personal credit cards",
|
41
|
+
# "expected" : "Intent1",
|
42
|
+
# "got" : "Intent1"
|
43
|
+
# },
|
44
|
+
# {
|
45
|
+
# "text" : "interest rates for personal credit cards",
|
46
|
+
# "expected" : "Intent1",
|
47
|
+
# "got" : "Intent1"
|
48
|
+
# },
|
49
|
+
# {
|
50
|
+
# "text" : "Am I still part of the rewards program?",
|
51
|
+
# "expected" : "Intent2",
|
52
|
+
# "got" : "Intent3"
|
53
|
+
# },
|
54
|
+
# {
|
55
|
+
# "text" : "Am I still in the loyalty program?",
|
56
|
+
# "expected" : "Intent2",
|
57
|
+
# "got" : "Intent3"
|
58
|
+
# }
|
59
|
+
# ]
|
60
|
+
# csv:
|
61
|
+
# APR for personal credit cards,Intent1,Intent1
|
62
|
+
# interest rates for personal credit cards,Intent1,Intent1
|
63
|
+
# Am I still part of the rewards program?,Intent2,Intent3
|
64
|
+
# Am I still in the loyalty program?,Intent2,Intent3
|
65
|
+
# hash:
|
66
|
+
# [
|
67
|
+
# {:text=>"APR for personal credit cards", :expected=>"Intent1", :got=>"Intent1"},
|
68
|
+
# {:text=>"interest rates for personal credit cards", :expected=>"Intent1", :got=>"Intent1"},
|
69
|
+
# {:text=>"Am I still part of the rewards program?", :expected=>"Intent2", :got=>"Intent3"},
|
70
|
+
# {:text=>"Am I still in the loyalty program?", :expected=>"Intent2", :got=>"Intent3"}
|
71
|
+
# ]
|
72
|
+
# yaml:
|
73
|
+
# ---
|
74
|
+
# - :text: APR for personal credit cards
|
75
|
+
# :expected: Intent1
|
76
|
+
# :got: Intent1
|
77
|
+
# - :text: interest rates for personal credit cards
|
78
|
+
# :expected: Intent1
|
79
|
+
# :got: Intent1
|
80
|
+
# - :text: Am I still part of the rewards program?
|
81
|
+
# :expected: Intent2
|
82
|
+
# :got: Intent3
|
83
|
+
# - :text: Am I still in the loyalty program?
|
84
|
+
# :expected: Intent2
|
85
|
+
# :got: Intent3
|
41
86
|
#
|
42
87
|
# @param test_data [Json]: Test data in specified format
|
43
|
-
# @param output_format [Symbol] supported formats :csv, :json or :hash
|
88
|
+
# @param output_format [Symbol] supported formats :csv, :json, :yaml or :hash
|
44
89
|
# @return [test_results]: output the test results in expected format
|
45
90
|
#
|
46
91
|
def parse_test(test_data, output_format = :hash)
|
@@ -59,6 +104,8 @@ module NluAdapter
|
|
59
104
|
return to_csv(test_results)
|
60
105
|
when :hash
|
61
106
|
return test_results
|
107
|
+
when :yaml
|
108
|
+
return test_results.to_yaml
|
62
109
|
else
|
63
110
|
puts 'Warning: valid format not specified'
|
64
111
|
return test_results
|
@@ -69,11 +116,80 @@ module NluAdapter
|
|
69
116
|
|
70
117
|
# run the parse tests with test_data and generate test report
|
71
118
|
#
|
119
|
+
# Example input/output
|
120
|
+
# test_data
|
121
|
+
# {
|
122
|
+
# "Intent1"=>["APR for personal credit cards", "interest rates for personal credit cards"],
|
123
|
+
# "Intent2"=>["Am I still part of the rewards program?", "Am I still in the loyalty program?"]
|
124
|
+
# }
|
125
|
+
# test_report
|
126
|
+
# json:
|
127
|
+
# {
|
128
|
+
# "accuracy":50.0,
|
129
|
+
# "confusion_matrix":"Matrix[[2, 0, 0], [0, 0, 2], [0, 0, 0]]",
|
130
|
+
# "classification_report": {
|
131
|
+
# "Intent1":{"precision":1.0,"recall":1.0,"class_total":2},
|
132
|
+
# "Intent2":{"precision":0.0,"recall":0.0,"class_total":2},
|
133
|
+
# "Intent3":{"precision":0.0,"recall":0.0,"class_total":0}
|
134
|
+
# }
|
135
|
+
# }
|
136
|
+
# csv:
|
137
|
+
# Accuracy,50.0
|
138
|
+
# CONFUSION MATRIX:
|
139
|
+
# "",Intent1,Intent2,Intent3
|
140
|
+
# Intent1,2,0,0
|
141
|
+
# Intent2,0,0,2
|
142
|
+
# Intent3,0,0,0
|
143
|
+
# CLASSIFICATION REPORT:
|
144
|
+
# Class,Precision,Recall,Class total
|
145
|
+
# Intent1,1.0,1.0,2
|
146
|
+
# Intent2,0.0,0.0,2
|
147
|
+
# Intent3,0.0,0.0,0
|
148
|
+
# hash:
|
149
|
+
# {
|
150
|
+
# :accuracy=>50.0,
|
151
|
+
# :confusion_matrix=>Matrix[[2, 0, 0], [0, 0, 2], [0, 0, 0]],
|
152
|
+
# :classification_report=>{
|
153
|
+
# :"Intent1"=>{:precision=>1.0, :recall=>1.0, :class_total=>2},
|
154
|
+
# :"Intent2"=>{:precision=>0.0, :recall=>0.0, :class_total=>2},
|
155
|
+
# :"Intent3"=>{:precision=>0.0, :recall=>0.0, :class_total=>0}
|
156
|
+
# }
|
157
|
+
# }
|
158
|
+
# yaml:
|
159
|
+
# ---
|
160
|
+
# :accuracy: 50.0
|
161
|
+
# :confusion_matrix: !ruby/object:Matrix
|
162
|
+
# rows:
|
163
|
+
# - - 2
|
164
|
+
# - 0
|
165
|
+
# - 0
|
166
|
+
# - - 0
|
167
|
+
# - 0
|
168
|
+
# - 2
|
169
|
+
# - - 0
|
170
|
+
# - 0
|
171
|
+
# - 0
|
172
|
+
# column_count: 3
|
173
|
+
# :classification_report:
|
174
|
+
# :Intent1:
|
175
|
+
# :precision: 1.0
|
176
|
+
# :recall: 1.0
|
177
|
+
# :class_total: 2
|
178
|
+
# :Intent2:
|
179
|
+
# :precision: 0.0
|
180
|
+
# :recall: 0.0
|
181
|
+
# :class_total: 2
|
182
|
+
# :Intent3:
|
183
|
+
# :precision: 0.0
|
184
|
+
# :recall: 0.0
|
185
|
+
# :class_total: 0
|
186
|
+
#
|
72
187
|
# @param test_data [Json]: Test data in specified format
|
188
|
+
# @param output_format [Symbol] supported formats :csv, :json, :yaml or :hash
|
73
189
|
# @return [test_report]: generate a test report
|
74
190
|
# @todo F1-Score
|
75
191
|
#
|
76
|
-
def parse_test_report(test_data)
|
192
|
+
def parse_test_report(test_data, output_format = :hash)
|
77
193
|
test_results = parse_test(test_data)
|
78
194
|
expected = []
|
79
195
|
got = []
|
@@ -82,9 +198,25 @@ module NluAdapter
|
|
82
198
|
got << result[:got]
|
83
199
|
end
|
84
200
|
|
85
|
-
|
201
|
+
test_report = {accuracy: 0, confusion_matrix: [], classification_report: {}}
|
202
|
+
if !got.reject { |e| e.to_s.empty? }.empty?
|
203
|
+
m = Metrics.new(expected, got)
|
204
|
+
test_report = {accuracy: m.accuracy, confusion_matrix: m.confusion_matrix, classification_report: m.classification_report}
|
205
|
+
end
|
86
206
|
|
87
|
-
|
207
|
+
case output_format
|
208
|
+
when :json
|
209
|
+
return test_report.to_json
|
210
|
+
when :csv
|
211
|
+
return report_to_csv(test_report)
|
212
|
+
when :hash
|
213
|
+
return test_report
|
214
|
+
when :yaml
|
215
|
+
return test_report.to_yaml
|
216
|
+
else
|
217
|
+
puts 'Warning: valid format not specified'
|
218
|
+
return test_report
|
219
|
+
end
|
88
220
|
end
|
89
221
|
|
90
222
|
private
|
@@ -96,5 +228,27 @@ module NluAdapter
|
|
96
228
|
end
|
97
229
|
csv_string
|
98
230
|
end
|
231
|
+
|
232
|
+
def report_to_csv(test_report)
|
233
|
+
|
234
|
+
csv_string = CSV.generate do |csv|
|
235
|
+
csv << ["Accuracy", test_report[:accuracy]]
|
236
|
+
csv << ["CONFUSION MATRIX:"]
|
237
|
+
class_row = [""]
|
238
|
+
test_report[:classification_report].each do |c, r|
|
239
|
+
class_row << c
|
240
|
+
end
|
241
|
+
csv << class_row
|
242
|
+
test_report[:confusion_matrix].to_a.each_with_index do |row, i|
|
243
|
+
csv << [class_row[i+1]] + row
|
244
|
+
end
|
245
|
+
csv << ["CLASSIFICATION REPORT:"]
|
246
|
+
csv << ["Class", "Precision", "Recall", "Class total"]
|
247
|
+
test_report[:classification_report].each do |c, r|
|
248
|
+
csv << [c, r[:precision], r[:recall], r[:class_total]]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
csv_string
|
252
|
+
end
|
99
253
|
end
|
100
254
|
end
|
data/lib/nlu_adapter/version.rb
CHANGED
@@ -32,7 +32,7 @@ module NluAdapter
|
|
32
32
|
# @return [Json] return the identified intent name
|
33
33
|
#
|
34
34
|
def parse(text)
|
35
|
-
intent_name =
|
35
|
+
intent_name = :NO_INTENT_FOUND
|
36
36
|
begin
|
37
37
|
response = @assistant.message(
|
38
38
|
workspace_id: @workspace_id,
|
@@ -41,7 +41,9 @@ module NluAdapter
|
|
41
41
|
}
|
42
42
|
)
|
43
43
|
|
44
|
-
|
44
|
+
unless response.nil? || response.result.nil? || response.result["intents"].nil? || response.result["intents"][0].nil?
|
45
|
+
intent_name = response.result["intents"][0]["intent"]
|
46
|
+
end
|
45
47
|
rescue WatsonApiException => ex
|
46
48
|
puts "Error: #{ex.inspect}"
|
47
49
|
end
|
data/nlu_adapter.gemspec
CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
23
23
|
spec.metadata["source_code_uri"] = "https://github.com/technopreneurG/nlu_adapter_ruby"
|
24
24
|
spec.metadata["changelog_uri"] = "https://github.com/technopreneurG/nlu_adapter_ruby/blob/master/CHANGELOG.md"
|
25
|
+
spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/nlu_adapter"
|
25
26
|
else
|
26
27
|
raise "RubyGems 2.0 or newer is required to protect against " \
|
27
28
|
"public gem pushes."
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nlu_adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Girish Nair
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -164,6 +164,7 @@ metadata:
|
|
164
164
|
homepage_uri: https://rubygems.org/gems/nlu_adapter
|
165
165
|
source_code_uri: https://github.com/technopreneurG/nlu_adapter_ruby
|
166
166
|
changelog_uri: https://github.com/technopreneurG/nlu_adapter_ruby/blob/master/CHANGELOG.md
|
167
|
+
documentation_uri: https://www.rubydoc.info/gems/nlu_adapter
|
167
168
|
post_install_message:
|
168
169
|
rdoc_options: []
|
169
170
|
require_paths:
|