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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25db10d98a5439cbbc18327adba57ed9422211b2088644d950d9172cb8ed210f
4
- data.tar.gz: 4ccf19d8a3633de04e0764fa74c374d185e3182dece8750cb3d9a7931a07167a
3
+ metadata.gz: 40656e57b36f5684b58789c2fc8756f6c311c5e5cd54e3151a61687df70ba2c8
4
+ data.tar.gz: 494f66bdcb5bc7083e048d2da54ec7e64b7bd1a5d1edd26b6a6ae287f1102b2b
5
5
  SHA512:
6
- metadata.gz: a6184e011cda087ec1e98cb5a81da9f3e01a982e05fdb7d75946bc2a3e083573f61a1992139533f2d73f6b4a42c4b1de73f36fcf30c68189e1b45347e7a3eee6
7
- data.tar.gz: 136be99c729217c0e7af0e24c7fc5401dad0f311dc60045b58b8490b48ee160d4a871d72fc156f61cb2e5ed823ca23c97e3b507e07ce3b4fea82d3effb9b4a0e
6
+ metadata.gz: 5eaa23df59165d67b674e7a96cd53e65353548fa3ef34cfb9f56e818468ab383fbab98cddab7f8cc1233fae1caec4f7afa9280c2784e795b205f3275e48faa5d
7
+ data.tar.gz: 0aada1752399c7a77b921e9ec9e8bc1cfb6a400cb571f124431393bee12a6e435b1d2321f4903ac91f30c5f3b8e783129a8b8fdfa85c91c92fae2ff77c8b1648
@@ -1,3 +1,8 @@
1
+ 0.1.6
2
+ ---
3
+ * enhancements to test report
4
+ * added support for :json, :csv, :yaml and :hash formats
5
+
1
6
  0.1.5 (22/Feb/2019)
2
7
  ---
3
8
  * Added IBM Watson Assistant
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
- C: Create, R: Get, U: Update, D: Delete
29
-
30
- NLU Service | Intent | Intet Collection | Intent identification
31
- ----------- | ------ | ---------------- | ---------------------
32
- [Aws Lex](https://aws.amazon.com/lex/) ([doc](docs/lex.md)) | C,R,U | C,R,U | Yes
33
- [Google Dialogflow](https://dialogflow.com/) ([doc](docs/dialogflow.md)) | C,R,U | To-Do | Yes
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
- return { intent_name: response.query_result.intent.display_name }
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
@@ -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 = nil
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 = resp.intent_name #=> String
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
- # {"BookHotel":["please book a hotel"],"intent1":["book me a hotel, please","book a hotel"]}
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
- # json:
34
- # [{"text":"book me a hotel, please","expected":"intent1","got":"BookHotel"},{"text":"book a hotel","expected":"intent1","got":"BookHotel"},{"text":"please book a hotel","expected":"BookHotel","got":"BookHotel"}]
35
- # csv:
36
- # "book me a hotel, please",intent1,BookHotel
37
- # book a hotel,intent1,BookHotel
38
- # please book a hotel,BookHotel,BookHotel
39
- # hash:
40
- # [{:text=>"book me a hotel, please", :expected=>"intent1", :got=>"BookHotel"}, {:text=>"book a hotel", :expected=>"intent1", :got=>"BookHotel"}, {:text=>"please book a hotel", :expected=>"BookHotel", :got=>"BookHotel"}]
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
- m = Metrics.new(expected, got)
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
- return {accuracy: m.accuracy, confusion_matrix: m.confusion_matrix, classification_report: m.classification_report}
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
@@ -1,3 +1,3 @@
1
1
  module NluAdapter
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -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 = nil
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
- intent_name = response.result["intents"][0]["intent"]
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
@@ -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.5
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-02-21 00:00:00.000000000 Z
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: