tangram 0.1.3 → 0.3.0

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +23 -19
  4. data/docs/Tangram.html +127 -0
  5. data/docs/Tangram/BagOfWordsFeatureContribution.html +507 -0
  6. data/docs/Tangram/Bigram.html +363 -0
  7. data/docs/Tangram/BinaryClassificationPredictOutput.html +493 -0
  8. data/docs/Tangram/FeatureContributions.html +435 -0
  9. data/docs/Tangram/IdentityFeatureContribution.html +435 -0
  10. data/docs/Tangram/LibTangram.html +160 -0
  11. data/docs/Tangram/LibTangram/TangramStringView.html +193 -0
  12. data/docs/Tangram/LoadModelOptions.html +291 -0
  13. data/docs/Tangram/Model.html +1250 -0
  14. data/docs/Tangram/MulticlassClassificationPredictOutput.html +565 -0
  15. data/docs/Tangram/NormalizedFeatureContribution.html +435 -0
  16. data/docs/Tangram/OneHotEncodedFeatureContribution.html +507 -0
  17. data/docs/Tangram/PredictOptions.html +421 -0
  18. data/docs/Tangram/RegressionPredictOutput.html +421 -0
  19. data/docs/Tangram/Unigram.html +291 -0
  20. data/docs/Tangram/WordEmbeddingFeatureContribution.html +435 -0
  21. data/docs/_index.html +310 -0
  22. data/docs/class_list.html +51 -0
  23. data/docs/css/common.css +1 -0
  24. data/docs/css/full_list.css +58 -0
  25. data/docs/css/style.css +497 -0
  26. data/docs/file.README.html +128 -0
  27. data/docs/file_list.html +56 -0
  28. data/docs/frames.html +17 -0
  29. data/docs/index.html +128 -0
  30. data/docs/js/app.js +314 -0
  31. data/docs/js/full_list.js +216 -0
  32. data/docs/js/jquery.js +4 -0
  33. data/docs/method_list.html +555 -0
  34. data/docs/top-level-namespace.html +110 -0
  35. data/examples/advanced.rb +49 -0
  36. data/examples/basic.rb +29 -0
  37. data/examples/heart_disease.tangram +0 -0
  38. data/lib/tangram.rb +1 -1
  39. data/lib/tangram/libtangram/aarch64-apple-darwin/libtangram.dylib +0 -0
  40. data/lib/tangram/libtangram/x86_64-apple-darwin/libtangram.dylib +0 -0
  41. data/lib/tangram/libtangram/x86_64-pc-windows-msvc/tangram.dll +0 -0
  42. data/lib/tangram/libtangram/x86_64-unknown-linux-gnu/libtangram.so +0 -0
  43. data/lib/tangram/libtangram/x86_64-unknown-linux-musl/libtangram.so +0 -0
  44. data/lib/tangram/tangram.rb +841 -0
  45. data/scripts/build +2 -4
  46. data/scripts/dev +4 -0
  47. data/scripts/docs +1 -0
  48. data/scripts/fmt +0 -0
  49. data/scripts/release +1 -0
  50. data/tangram.gemspec +10 -10
  51. metadata +52 -17
  52. data/examples/monitor/heart-disease.tangram +0 -0
  53. data/examples/monitor/main.rb +0 -52
  54. data/examples/predict/heart-disease.tangram +0 -0
  55. data/examples/predict/main.rb +0 -30
  56. data/lib/tangram/libtangram-0.1.3-linux-x86_64.so +0 -0
  57. data/lib/tangram/libtangram-0.1.3-macos-x86_64.dylib +0 -0
  58. data/lib/tangram/libtangram.rb +0 -24
  59. data/lib/tangram/model.rb +0 -133
  60. data/lib/tangram/tangram-0.1.3-windows-x86_64.dll +0 -0
@@ -0,0 +1,110 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.26
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
+
17
+ <script type="text/javascript">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="Tangram.html" title="Tangram (module)">Tangram</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Fri Apr 23 15:50:02 2021 by
104
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.26 (ruby-3.0.1).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
@@ -0,0 +1,49 @@
1
+ require 'tangram'
2
+
3
+ # If you are running the Tangram app on your own server you can pass the URL to it with the TANGRAM_URL environment variable.
4
+ tangram_url = ENV['TANGRAM_URL'] || 'https://app.tangram.xyz'
5
+
6
+ # Get the path to the `.tangram` file.
7
+ model_path = File.join(File.dirname(__FILE__), 'heart_disease.tangram')
8
+ # Load the model from the path and set the url where the tangram app is running.
9
+ options = Tangram::LoadModelOptions.new(tangram_url: tangram_url)
10
+ model = Tangram::Model.from_path(model_path, options: options)
11
+
12
+ # Create an example input matching the schema of the CSV file the model was trained on. Here the data is just hard-coded, but in your application you will probably get this from a database or user input.
13
+ input = {
14
+ age: 63.0,
15
+ gender: 'male',
16
+ chest_pain: 'typical angina',
17
+ resting_blood_pressure: 145.0,
18
+ cholesterol: 233.0,
19
+ fasting_blood_sugar_greater_than_120: 'true',
20
+ resting_ecg_result: 'probable or definite left ventricular hypertrophy',
21
+ exercise_max_heart_rate: 150.0,
22
+ exercise_induced_angina: 'no',
23
+ exercise_st_depression: 2.3,
24
+ exercise_st_slope: 'downsloping',
25
+ fluoroscopy_vessels_colored: '0',
26
+ thallium_stress_test: 'fixed defect'
27
+ }
28
+
29
+ # Make the prediction using a custom threshold chosen on the "Tuning" page of the Tangram app.
30
+ options = Tangram::PredictOptions.new(threshold: 0.5, compute_feature_contributions: true)
31
+ output = model.predict(input, options: options)
32
+
33
+ # Make the prediction using a custom threshold chosen on the "Tuning" page of the Tangram app.
34
+ puts('Input:', input)
35
+ puts('Output:', output)
36
+
37
+ # Log the prediction.
38
+ model.log_prediction(
39
+ identifier: '71762b29-2296-4bf9-a1d4-59144d74c9d9',
40
+ input: input,
41
+ output: output,
42
+ options: options
43
+ )
44
+
45
+ # Later on, if we get an official diagnosis for the patient, log the true value. Make sure to match the `identifier`.
46
+ model.log_true_value(
47
+ identifier: '71762b29-2296-4bf9-a1d4-59144d74c9d9',
48
+ true_value: 'Positive'
49
+ )
data/examples/basic.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'tangram'
2
+
3
+ # Get the path to the .tangram file.
4
+ model_path = File.join(File.dirname(__FILE__), 'heart_disease.tangram')
5
+ # Load the model from the path.
6
+ model = Tangram::Model.from_path(model_path)
7
+
8
+ # Create an example input matching the schema of the CSV file the model was trained on. Here the data is just hard-coded, but in your application you will probably get this from a database or user input.
9
+ input = {
10
+ age: 63.0,
11
+ gender: 'male',
12
+ chest_pain: 'typical angina',
13
+ resting_blood_pressure: 145.0,
14
+ cholesterol: 233.0,
15
+ fasting_blood_sugar_greater_than_120: 'true',
16
+ resting_ecg_result: 'probable or definite left ventricular hypertrophy',
17
+ exercise_max_heart_rate: 150.0,
18
+ exercise_induced_angina: 'no',
19
+ exercise_st_depression: 2.3,
20
+ exercise_st_slope: 'downsloping',
21
+ fluoroscopy_vessels_colored: '0',
22
+ thallium_stress_test: 'fixed defect'
23
+ }
24
+
25
+ # Make the prediction!
26
+ output = model.predict(input)
27
+
28
+ # Print the output.
29
+ puts('Output:', output.inspect)
Binary file
data/lib/tangram.rb CHANGED
@@ -1 +1 @@
1
- require 'tangram/model'
1
+ require 'tangram/tangram'
@@ -0,0 +1,841 @@
1
+ require 'date'
2
+ require 'ffi'
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'rbconfig'
6
+
7
+ # This is the main module in the `tangram` gem.
8
+ module Tangram
9
+
10
+ # These are the options passed when loading a model.
11
+ class LoadModelOptions
12
+ # If you are running the app locally or on your own server, use this field to provide the url to it. If not specified, the default value is https://app.tangram.xyz.
13
+ attr_reader :tangram_url
14
+ def initialize(tangram_url:)
15
+ @tangram_url = tangram_url
16
+ end
17
+ end
18
+
19
+ # These are the options passed to `predict`.
20
+ class PredictOptions
21
+ # If your model is a binary classifier, use this field to make predictions using a threshold chosen on the tuning page of the app. The default value is `0.5`.
22
+ attr_reader :threshold
23
+ # Computing feature contributions is disabled by default. If you set this field to `true`, you will be able to access the feature contributions with the `feature_contributions` field of the predict output.
24
+ attr_reader :compute_feature_contributions
25
+ def initialize(compute_feature_contributions:, threshold: nil)
26
+ @threshold = threshold
27
+ @compute_feature_contributions = compute_feature_contributions
28
+ end
29
+ def to_json(*args)
30
+ {'threshold' => @threshold, 'compute_feature_contributions' => @compute_feature_contributions}.to_json(*args)
31
+ end
32
+ end
33
+
34
+ # `predict` outputs `RegressionPredictOutput` when the model's task is regression.
35
+ class RegressionPredictOutput
36
+ # This is the predicted value.
37
+ attr_reader :value
38
+ # If computing feature contributions was enabled in the predict options, this value will explain the model's output, showing how much each feature contributed to the output.
39
+ attr_reader :feature_contributions
40
+ def initialize(value:, feature_contributions:)
41
+ @value = value
42
+ @feature_contributions = feature_contributions
43
+ end
44
+ def to_json(*args)
45
+ {'value' => @value}.to_json(*args)
46
+ end
47
+ end
48
+
49
+ # `predict` outputs `BinaryClassificationPredictOutput` when the model's task is binary classification.
50
+ class BinaryClassificationPredictOutput
51
+ # This is the name of the predicted class.
52
+ attr_reader :class_name
53
+ # This is the probability the model assigned to the predicted class.
54
+ attr_reader :probability
55
+ # If computing feature contributions was enabled in the predict options, this value will explain the model's output, showing how much each feature contributed to the output.
56
+ attr_reader :feature_contributions
57
+ def initialize(class_name:, probability:, feature_contributions:)
58
+ @class_name = class_name
59
+ @probability = probability
60
+ @feature_contributions = feature_contributions
61
+ end
62
+ def to_json(*args)
63
+ {'class_name' => @class_name, "probability" => @probability}.to_json(*args)
64
+ end
65
+ end
66
+
67
+ # `predict` outputs `MulticlassClassificationPredictOutput` when the model's task is multiclass classification.
68
+ class MulticlassClassificationPredictOutput
69
+ # This is the name of the predicted class.
70
+ attr_reader :class_name
71
+ # This is the probability the model assigned to the predicted class.
72
+ attr_reader :probability
73
+ # This value maps from class names to the probability the model assigned to each class.
74
+ attr_reader :probabilities
75
+ # If computing feature contributions was enabled in the predict options, this value will explain the model's output, showing how much each feature contributed to the output. This value maps from class names to `FeatureContributions` values for each class. The class with the `FeatureContributions` value with the highest `output_value` is the predicted class.
76
+ attr_reader :feature_contributions
77
+ def initialize(class_name:, probability:, probabilities:, feature_contributions:)
78
+ @class_name = class_name
79
+ @probability = probability
80
+ @probabilities = probabilities
81
+ @feature_contributions = feature_contributions
82
+ end
83
+ def to_json(*args)
84
+ {'class_name' => @class_name, "probability" => @probability, "probabilities" => @probabilities}.to_json(*args)
85
+ end
86
+ end
87
+
88
+ # This is a description of the feature contributions for the prediction if the task is regression or binary classification, or for a single class if the task is multiclass classification.
89
+ class FeatureContributions
90
+ # This is the value the model would output if all features had baseline values.
91
+ attr_reader :baseline
92
+ # This is the value the model output. Any difference from the `baseline_value` is because of the deviation of the features from their baseline values.
93
+ attr_reader :output
94
+ # This list will contain one entry for each of the model's features. Note that features are computed from columns, so there will likely be more features than columns.
95
+ attr_reader :entries
96
+ def initialize(baseline:, output:, entries:)
97
+ @baseline = baseline
98
+ @output = output
99
+ @entries = entries
100
+ end
101
+ end
102
+
103
+ # This describes the contribution of a feature from an identity feature group.
104
+ class IdentityFeatureContribution
105
+ # This is the name of the source column for the feature group.
106
+ attr_reader :column_name
107
+ # This is the value of the feature.
108
+ attr_reader :feature_value
109
+ # This is the amount that the feature contributed to the output.
110
+ attr_reader :feature_contribution_value
111
+ def initialize(column_name:, feature_contribution_value:, feature_value:)
112
+ @column_name = column_name
113
+ @feature_value = feature_value
114
+ @feature_contribution_value = feature_contribution_value
115
+ end
116
+ end
117
+
118
+ # This describes the contribution of a feature from a normalized feature group.
119
+ class NormalizedFeatureContribution
120
+ # This is the name of the source column for the feature group.
121
+ attr_reader :column_name
122
+ # This is the value of the feature.
123
+ attr_reader :feature_value
124
+ # This is the amount that the feature contributed to the output.
125
+ attr_reader :feature_contribution_value
126
+ def initialize(column_name:, feature_value:, feature_contribution_value:)
127
+ @column_name = column_name
128
+ @feature_value = feature_value
129
+ @feature_contribution_value = feature_contribution_value
130
+ end
131
+ end
132
+
133
+ # This describes the contribution of a feature from a one hot encoded feature group.
134
+ class OneHotEncodedFeatureContribution
135
+ # This is the name of the source column for the feature group.
136
+ attr_reader :column_name
137
+ # This is the enum variant the feature indicates the presence of.
138
+ attr_reader :variant
139
+ # This is the value of the feature.
140
+ attr_reader :feature_value
141
+ # This is the amount that the feature contributed to the output.b
142
+ attr_reader :feature_contribution_value
143
+ def initialize(column_name:, variant:, feature_contribution_value:, feature_value:)
144
+ @column_name = column_name
145
+ @variant = variant
146
+ @feature_contribution_value = feature_contribution_value
147
+ @feature_value = feature_value
148
+ end
149
+ end
150
+
151
+ # This describes the contribution of a feature from a bag of words feature group.
152
+ class BagOfWordsFeatureContribution
153
+ # This is the name of the source column for the feature group.
154
+ attr_reader :column_name
155
+ # This is the ngram for the feature.
156
+ attr_reader :ngram
157
+ # This is the value of the feature.
158
+ attr_reader :feature_value
159
+ # This is the amount that the feature contributed to the output.
160
+ attr_reader :feature_contribution_value
161
+ def initialize(column_name:, ngram:, feature_contribution_value:, feature_value:)
162
+ @column_name = column_name
163
+ @ngram = ngram
164
+ @feature_contribution_value = feature_contribution_value
165
+ @feature_value = feature_value
166
+ end
167
+ end
168
+
169
+ # This describes a unigram ngram.
170
+ class Unigram
171
+ # This is the token.
172
+ attr_reader :token
173
+ def initialize(token)
174
+ @token = token
175
+ end
176
+ end
177
+
178
+ # This describes a bigram ngram.
179
+ class Bigram
180
+ # This is the first token in the bigram.
181
+ attr_reader :token_a
182
+ # This is the second token in the bigram.
183
+ attr_reader :token_b
184
+ def initialize(token_a:, token_b:)
185
+ @token_a = token_a
186
+ @token_b = token_b
187
+ end
188
+ end
189
+
190
+ # This describes the contribution of a feature from a word embedding feature group.
191
+ class WordEmbeddingFeatureContribution
192
+ # This is the name of the source column for the feature group.
193
+ attr_reader :column_name
194
+ # This is the index of the feature in the word embedding.
195
+ attr_reader :value_index
196
+ # This is the amount that the feature contributed to the output.
197
+ attr_reader :feature_contribution_value
198
+ def initialize(column_name:, value_index:, feature_contribution_value:)
199
+ @column_name = column_name
200
+ @value_index = value_index
201
+ @feature_contribution_value = feature_contribution_value
202
+ end
203
+ end
204
+
205
+ # Use this class to load a model, make predictions, and log events to the app.
206
+ class Model
207
+ # Load a model from the `.tangram` file at `path`.
208
+ # @param path [String] The path to the `.tangram` file.
209
+ # @param options [LoadModelOptions] The options to use when loading the model.
210
+ # @return [Model]
211
+ def self.from_path(path, options: nil)
212
+ c_model = FFI::MemoryPointer.new(:pointer)
213
+ c_err = LibTangram.tangram_model_from_path(path, c_model)
214
+ unless c_err.null?
215
+ c_err = FFI::AutoPointer.new(c_err, LibTangram.method(:tangram_error_delete))
216
+ c_error_s = LibTangram::TangramStringView.new
217
+ LibTangram.tangram_error_get_message(c_err, c_error_s)
218
+ raise c_error_s.into_string
219
+ end
220
+ new(c_model, options: options)
221
+ end
222
+
223
+ # Load a model from bytes instead of a file. You should use this only if you already have a `.tangram` loaded into memory. Otherwise, use `Model.from_path`, which is faster because it memory maps the file.
224
+ # @param bytes [String] The bytes for the .tangram model.
225
+ # @param options [LoadModelOptions] The options to use when loading the model.
226
+ # @return [Model]
227
+ def self.from_bytes(bytes, options: nil)
228
+ c_model = FFI::MemoryPointer.new(:pointer)
229
+ c_err = LibTangram.tangram_model_from_bytes(bytes, bytes.size, c_model)
230
+ unless err.null?
231
+ c_err = FFI::AutoPointer.new(c_err, LibTangram.method(:tangram_error_delete))
232
+ c_error_s = LibTangram::TangramStringView.new
233
+ LibTangram.tangram_error_get_message(c_err, c_error_s)
234
+ raise errors.into_string
235
+ end
236
+ new(c_model, options: options)
237
+ end
238
+
239
+ def initialize(c_model, options: nil)
240
+ @tangram_url = options&.tangram_url.nil? ? 'https://app.tangram.xyz' : options&.tangram_url
241
+ @log_queue = []
242
+ @model = FFI::AutoPointer.new(c_model.read_pointer, LibTangram.method(:tangram_model_delete))
243
+ end
244
+
245
+ # Retrieve the model's id.
246
+ def id
247
+ c_id = LibTangram::TangramStringView.new
248
+ LibTangram.tangram_model_get_id(@model, c_id)
249
+ c_id.into_string
250
+ end
251
+
252
+ # Make a prediction!
253
+ # @param input [Array<Hash{String, Symbol => String, Number}>, Hash{String, Symbol => String, Number}] A predict input is either a single predict input which is a map from symbols or strings to strings or floats or an array of such maps. The keys should match the columns in the CSV file you trained your model with.
254
+ # @param options [PredictOptions] These are the predict options.
255
+ # @return [Array<RegressionPredictOutput, BinaryClassificationPredictOutput, MulticlassClassificationPredictOutput>, RegressionPredictOutput, BinaryClassificationPredictOutput, MulticlassClassificationPredictOutput]. Return a single output if `input` was a single input, or an array if `input` was an array of `input`s.
256
+ def predict(input, options: nil)
257
+ is_array = input.is_a?(Array)
258
+ input = is_array ? input : [input]
259
+ c_input_vec = new_predict_input_vec(input)
260
+ c_options = new_predict_options(options)
261
+ c_output_vec = FFI::MemoryPointer.new(:pointer)
262
+ c_error = LibTangram.tangram_model_predict(@model, c_input_vec, c_options, c_output_vec)
263
+ raise 'tangram error' unless c_error.null?
264
+ c_output_vec = FFI::AutoPointer.new(c_output_vec.read_pointer, LibTangram.method(:tangram_predict_output_vec_delete))
265
+ output = predict_output_vec_from_tangram_predict_output_vec(c_output_vec)
266
+ is_array ? output : output[0]
267
+ end
268
+
269
+ # Send a prediction event to the app. If you want to batch events, you can use `enqueue_log_prediction` instead.
270
+ # @param identifier [String, Number] This is a unique identifier for the prediction, which will associate it with a true value event and allow you to look it up in the app.
271
+ # @param input [Hash{String, Symbol => String, Number}] A single `PredictInput`.
272
+ # @param output [PredictOutput] A single `PredictOutput`.
273
+ # @param options [PredictOptions] This is the same `predictOptions` value that you passed to `predict`.
274
+ def log_prediction(identifier:, input:, output:, options: nil)
275
+ event = prediction_event(
276
+ identifier: identifier,
277
+ input: input,
278
+ output: output,
279
+ options: options
280
+ )
281
+ log_event(event)
282
+ end
283
+
284
+ # Add a prediction event to the queue. Remember to call `flush_log_queue` at a later point to send the event to the app.
285
+ # @param identifier [String, Number] This is a unique identifier for the prediction, which will associate it with a true value event and allow you to look it up in the app.
286
+ # @param input [Hash{String, Symbol => String, Number}] A single `PredictInput`.
287
+ # @param output [PredictOutput] A single `PredictOutput`.
288
+ # @param options [PredictOptions] This is the same `predictOptions` value that you passed to `predict`.
289
+ def enqueue_log_prediction(identifier:, input:, output:, options: nil)
290
+ event = prediction_event(
291
+ identifier: identifier,
292
+ input: input,
293
+ output: output,
294
+ options: options
295
+ )
296
+ log_queue.push(event)
297
+ end
298
+
299
+ # Send a true value event to the app. If you want to batch events, you can use `enqueue_log_true_value` instead.
300
+ # @param identifier [String, Number] This is a unique identifier for the prediction, which will associate it with a true value event and allow you to look it up in the app.
301
+ # @param true_value [String, Number] This is the true value for the prediction.
302
+ def log_true_value(identifier:, true_value:)
303
+ event = true_value_event(
304
+ identifier: identifier,
305
+ true_value: true_value
306
+ )
307
+ log_event(event)
308
+ end
309
+
310
+ # Add a true value event to the queue. Remember to call `flush_log_queue` at a later point to send the event to the app.
311
+ # @param identifier [String, Number] This is a unique identifier for the prediction, which will associate it with a true value event and allow you to look it up in the app.
312
+ # @param true_value [String, Number] This is the true value for the prediction.
313
+ def enqueue_log_true_value(identifier:, true_value:)
314
+ event = true_value_event(
315
+ identifier: identifier,
316
+ true_value: true_value
317
+ )
318
+ log_queue.push(event)
319
+ end
320
+
321
+ # Send all events in the queue to the app.
322
+ def flush_log_queue
323
+ log_events(@log_queue)
324
+ @log_queue = []
325
+ end
326
+
327
+ private
328
+
329
+ def log_event(event)
330
+ log_events([event])
331
+ end
332
+
333
+ def log_events(events)
334
+ headers = {
335
+ 'Content-Type': 'application/json'
336
+ }
337
+ uri = URI("#{@tangram_url}/track")
338
+ http = Net::HTTP.new(uri.host, uri.port)
339
+ request = Net::HTTP::Post.new(uri.request_uri, headers)
340
+ request.body = events.to_json
341
+ response = http.request(request)
342
+ raise response unless response.is_a? Net::HTTPSuccess
343
+ end
344
+
345
+ def prediction_event(identifier:, input:, output:, options: nil)
346
+ {
347
+ date: DateTime.now.rfc3339,
348
+ identifier: identifier,
349
+ input: input,
350
+ model_id: id,
351
+ options: options,
352
+ output: output,
353
+ type: 'prediction'
354
+ }
355
+ end
356
+
357
+ def true_value_event(identifier:, true_value:)
358
+ {
359
+ date: DateTime.now.rfc3339,
360
+ identifier: identifier,
361
+ model_id: id,
362
+ true_value: true_value,
363
+ type: 'true_value'
364
+ }
365
+ end
366
+
367
+ def new_predict_options(options)
368
+ c_options = FFI::MemoryPointer.new(:pointer)
369
+ LibTangram.tangram_predict_options_new(c_options)
370
+ c_options = FFI::AutoPointer.new(c_options.read_pointer, LibTangram.method(:tangram_predict_options_delete))
371
+ unless options.nil?
372
+ unless options.threshold.nil?
373
+ LibTangram.tangram_predict_options_set_threshold(c_options, options.threshold)
374
+ end
375
+ unless options.compute_feature_contributions.nil?
376
+ LibTangram.tangram_predict_options_set_compute_feature_contributions(c_options, options.compute_feature_contributions)
377
+ end
378
+ end
379
+ c_options
380
+ end
381
+
382
+ def new_predict_input_vec(input_vec)
383
+ c_inputs = FFI::MemoryPointer.new(:pointer)
384
+ LibTangram.tangram_predict_input_vec_new(c_inputs)
385
+ c_inputs = FFI::AutoPointer.new(c_inputs.read_pointer, LibTangram.method(:tangram_predict_input_vec_delete))
386
+ (0...input_vec.length).each do |input_index|
387
+ input = input_vec[input_index]
388
+ predict_input = new_predict_input(input)
389
+ LibTangram.tangram_predict_input_vec_push(c_inputs, predict_input)
390
+ end
391
+ c_inputs
392
+ end
393
+
394
+ def new_predict_input(input)
395
+ c_input = FFI::MemoryPointer.new(:pointer)
396
+ LibTangram.tangram_predict_input_new(c_input)
397
+ c_input = c_input.read_pointer
398
+ input.each do |key, value|
399
+ is_float = value.is_a?(Float)
400
+ is_string = value.is_a?(String)
401
+ if is_float
402
+ LibTangram.tangram_predict_input_set_value_number(c_input, key.to_s, value)
403
+ elsif is_string
404
+ LibTangram.tangram_predict_input_set_value_string(c_input, key.to_s, value)
405
+ else
406
+ raise 'tangram error'
407
+ end
408
+ end
409
+ c_input
410
+ end
411
+
412
+ def predict_output_vec_from_tangram_predict_output_vec(c_output_vec)
413
+ outputs = []
414
+ c_output_len = FFI::MemoryPointer.new(:int)
415
+ LibTangram.tangram_predict_output_vec_len(c_output_vec, c_output_len)
416
+ output_len = c_output_len.read(:int)
417
+ (0...output_len).each do |output_index|
418
+ c_output = FFI::MemoryPointer.new(:pointer)
419
+ LibTangram.tangram_predict_output_vec_get_at_index(c_output_vec, output_index, c_output)
420
+ c_output = c_output.read_pointer
421
+ outputs.push(predict_output_from_tangram_predict_output(c_output))
422
+ end
423
+
424
+ outputs
425
+ end
426
+
427
+ def predict_output_from_tangram_predict_output(c_output)
428
+ c_task_type = FFI::MemoryPointer.new(:int)
429
+ LibTangram.tangram_model_get_task(@model, c_task_type)
430
+ case c_task_type.read(:int)
431
+ when LibTangram::TangramTaskType[:regression]
432
+ regression_output_from_tangram_predict_output(c_output)
433
+ when LibTangram::TangramTaskType[:binary_classification]
434
+ binary_classification_output_from_tangram_predict_output(c_output)
435
+ when LibTangram::TangramTaskType[:multiclass_classification]
436
+ multiclass_classification_output_from_tangram_predict_output(c_output)
437
+ end
438
+ end
439
+
440
+ def regression_output_from_tangram_predict_output(c_output)
441
+ c_regression_output = FFI::MemoryPointer.new(:pointer)
442
+ LibTangram.tangram_predict_output_as_regression(c_output, c_regression_output)
443
+ c_regression_output = c_regression_output.read_pointer
444
+ c_value = FFI::MemoryPointer.new(:float)
445
+ LibTangram.tangram_regression_predict_output_get_value(c_regression_output, c_value)
446
+ value = c_value.read(:float)
447
+ c_feature_contributions = FFI::MemoryPointer.new(:pointer)
448
+ LibTangram.tangram_regression_predict_output_get_feature_contributions(c_regression_output, c_feature_contributions)
449
+ c_feature_contributions = c_feature_contributions.read_pointer
450
+ feature_contributions = c_feature_contributions.null? ? {} : get_feature_contributions(c_feature_contributions)
451
+ RegressionPredictOutput.new(
452
+ value: value,
453
+ feature_contributions: feature_contributions
454
+ )
455
+ end
456
+
457
+ def binary_classification_output_from_tangram_predict_output(c_output)
458
+ c_binary_classification_output = FFI::MemoryPointer.new(:pointer)
459
+ LibTangram.tangram_predict_output_as_binary_classification(c_output, c_binary_classification_output)
460
+ c_binary_classification_output = c_binary_classification_output.read_pointer
461
+ c_probability = FFI::MemoryPointer.new(:float)
462
+ LibTangram.tangram_binary_classification_predict_output_get_probability(c_binary_classification_output, c_probability)
463
+ probability = c_probability.read(:float)
464
+ c_class_name = LibTangram::TangramStringView.new
465
+ LibTangram.tangram_binary_classification_predict_output_get_class_name(c_binary_classification_output, c_class_name)
466
+ class_name = c_class_name.into_string
467
+ c_feature_contributions = FFI::MemoryPointer.new(:pointer)
468
+ LibTangram.tangram_binary_classification_predict_output_get_feature_contributions(c_binary_classification_output, c_feature_contributions)
469
+ c_feature_contributions = c_feature_contributions.read_pointer
470
+ feature_contributions = c_feature_contributions.null? ? {} : get_feature_contributions(c_feature_contributions)
471
+ BinaryClassificationPredictOutput.new(
472
+ class_name: class_name,
473
+ probability: probability,
474
+ feature_contributions: feature_contributions
475
+ )
476
+ end
477
+
478
+ def multiclass_classification_output_from_tangram_predict_output(c_output)
479
+ c_multiclass_classification_output = FFI::MemoryPointer.new(:pointer)
480
+ LibTangram.tangram_predict_output_as_multiclass_classification(c_output, c_multiclass_classification_output)
481
+ c_multiclass_classification_output = c_multiclass_classification_output.read_pointer
482
+ c_probability = FFI::MemoryPointer.new(:float)
483
+ LibTangram.tangram_multiclass_classification_predict_output_get_probability(c_multiclass_classification_output, c_probability)
484
+ probability = c_probability.read(:float)
485
+ c_class_name = LibTangram::TangramStringView.new
486
+ LibTangram.tangram_multiclass_classification_predict_output_get_class_name(c_multiclass_classification_output, c_class_name)
487
+ class_name = c_class_name.into_string
488
+ probabilities = multiclass_classification_output_get_probabilities(c_multiclass_classification_output)
489
+ feature_contributions = multiclass_classification_output_get_feature_contributions(c_multiclass_classification_output)
490
+ MulticlassClassificationPredictOutput.new(
491
+ class_name: class_name,
492
+ probability: probability,
493
+ probabilities: probabilities,
494
+ feature_contributions: feature_contributions
495
+ )
496
+ end
497
+
498
+ def multiclass_classification_output_get_probabilities(c_multiclass_classification_output)
499
+ probabilities = {}
500
+ c_probabilities_iter = FFI::MemoryPointer.new(:pointer)
501
+ LibTangram.tangram_multiclass_classification_predict_output_get_probabilities_iter(c_multiclass_classification_output, c_probabilities_iter)
502
+ c_probabilities_iter = FFI::AutoPointer.new(c_probabilities_iter.read_pointer, LibTangram.method(:tangram_multiclass_classification_predict_output_probabilities_iter_delete))
503
+ c_class_probability = FFI::MemoryPointer.new(:float)
504
+ c_class_name = LibTangram::TangramStringView.new
505
+ while LibTangram.tangram_multiclass_classification_predict_output_probabilities_iter_next(c_probabilities_iter, c_class_name, c_class_probability)
506
+ class_name = c_class_name.into_string
507
+ probabilities[class_name] = c_class_probability.read(:float)
508
+ end
509
+ probabilities
510
+ end
511
+
512
+ def multiclass_classification_output_get_feature_contributions(c_multiclass_classification_output)
513
+ c_feature_contributions_iter = FFI::MemoryPointer.new(:pointer)
514
+ LibTangram.tangram_multiclass_classification_predict_output_get_feature_contributions_iter(c_multiclass_classification_output, c_feature_contributions_iter)
515
+ c_feature_contributions_iter = FFI::AutoPointer.new(c_feature_contributions_iter.read_pointer, LibTangram.method(:tangram_multiclass_classification_predict_output_feature_contributions_iter_delete))
516
+ feature_contributions = {}
517
+ unless c_feature_contributions_iter.null?
518
+ c_class_name = LibTangram::TangramStringView.new
519
+ c_feature_contributions_ptr = FFI::MemoryPointer.new(:pointer)
520
+ while LibTangram.tangram_multiclass_classification_predict_output_feature_contributions_iter_next(c_feature_contributions_iter, c_class_name, c_feature_contributions_ptr)
521
+ class_name = c_class_name.into_string
522
+ c_feature_contributions = c_feature_contributions_ptr.read_pointer
523
+ unless c_feature_contributions.null?
524
+ feature_contributions[class_name] = get_feature_contributions(c_feature_contributions)
525
+ end
526
+ end
527
+ end
528
+ feature_contributions
529
+ end
530
+
531
+ def get_feature_contributions(c_feature_contributions)
532
+ c_baseline = FFI::MemoryPointer.new(:float)
533
+ LibTangram.tangram_feature_contributions_get_baseline_value(c_feature_contributions, c_baseline)
534
+ baseline = c_baseline.read(:float)
535
+ c_output = FFI::MemoryPointer.new(:float)
536
+ LibTangram.tangram_feature_contributions_get_output_value(c_feature_contributions, c_output)
537
+ output = c_output.read(:float)
538
+ feature_contribution_entries = get_feature_contributions_entries(c_feature_contributions)
539
+ FeatureContributions.new(
540
+ baseline: baseline,
541
+ output: output,
542
+ entries: feature_contribution_entries
543
+ )
544
+ end
545
+
546
+ def get_feature_contributions_entries(c_feature_contributions)
547
+ c_len = FFI::MemoryPointer.new(:int)
548
+ LibTangram.tangram_feature_contributions_get_entries_len(c_feature_contributions, c_len)
549
+ len = c_len.read(:int)
550
+ feature_contributions = []
551
+ (0...len).each do |i|
552
+ c_feature_contribution = FFI::MemoryPointer.new(:pointer)
553
+ LibTangram.tangram_feature_contributions_get_entry_at_index(c_feature_contributions, i, c_feature_contribution)
554
+ c_feature_contribution = c_feature_contribution.read_pointer
555
+ feature_contributions.push(get_feature_contribution(c_feature_contribution))
556
+ end
557
+ feature_contributions
558
+ end
559
+
560
+ def get_feature_contribution(c_feature_contribution)
561
+ c_feature_contribution_type = FFI::MemoryPointer.new(:int)
562
+ LibTangram.tangram_feature_contribution_entry_get_type(c_feature_contribution, c_feature_contribution_type)
563
+ case c_feature_contribution_type.read(:int)
564
+ when LibTangram::TangramFeatureContributionEntryType[:identity]
565
+ get_identity_feature_contribution(c_feature_contribution)
566
+ when LibTangram::TangramFeatureContributionEntryType[:normalized]
567
+ get_normalized_feature_contribution(c_feature_contribution)
568
+ when LibTangram::TangramFeatureContributionEntryType[:one_hot_encoded]
569
+ get_one_hot_encoded_feature_contribution(c_feature_contribution)
570
+ when LibTangram::TangramFeatureContributionEntryType[:bag_of_words]
571
+ get_bag_of_words_feature_contribution(c_feature_contribution)
572
+ when LibTangram::TangramFeatureContributionEntryType[:word_embedding]
573
+ get_word_embedding_feature_contribution(c_feature_contribution)
574
+ end
575
+ end
576
+
577
+ def get_identity_feature_contribution(c_feature_contribution)
578
+ c_identity_feature_contribution = FFI::MemoryPointer.new(:pointer)
579
+ LibTangram.tangram_feature_contribution_entry_as_identity(c_feature_contribution, c_identity_feature_contribution)
580
+ c_identity_feature_contribution = c_identity_feature_contribution.read_pointer
581
+ c_column_name = LibTangram::TangramStringView.new
582
+ LibTangram.tangram_identity_feature_contribution_get_column_name(c_identity_feature_contribution, c_column_name)
583
+ column_name = c_column_name.into_string
584
+ c_feature_contribution_value = FFI::MemoryPointer.new(:float)
585
+ LibTangram.tangram_identity_feature_contribution_get_feature_contribution_value(c_identity_feature_contribution, c_feature_contribution_value)
586
+ feature_contribution_value = c_feature_contribution_value.read(:float)
587
+ c_feature_value = FFI::MemoryPointer.new(:float)
588
+ LibTangram.tangram_identity_feature_contribution_get_feature_value(c_identity_feature_contribution, c_feature_value)
589
+ feature_value = c_feature_value.read(:float)
590
+ IdentityFeatureContribution.new(
591
+ column_name: column_name,
592
+ feature_value: feature_value,
593
+ feature_contribution_value: feature_contribution_value
594
+ )
595
+ end
596
+
597
+ def get_normalized_feature_contribution(c_feature_contribution)
598
+ c_normalized_feature_contribution = FFI::MemoryPointer.new(:pointer)
599
+ LibTangram.tangram_feature_contribution_entry_as_normalized(
600
+ c_feature_contribution, c_normalized_feature_contribution
601
+ )
602
+ c_normalized_feature_contribution = c_normalized_feature_contribution.read_pointer
603
+ c_column_name = LibTangram::TangramStringView.new
604
+ LibTangram.tangram_normalized_feature_contribution_get_column_name(c_normalized_feature_contribution, c_column_name)
605
+ column_name = c_column_name.into_string
606
+ c_feature_value = FFI::MemoryPointer.new(:float)
607
+ LibTangram.tangram_normalized_feature_contribution_get_feature_value(c_normalized_feature_contribution, c_feature_value)
608
+ feature_value = c_feature_value.read(:float)
609
+ c_feature_contribution_value = FFI::MemoryPointer.new(:float)
610
+ LibTangram.tangram_normalized_feature_contribution_get_feature_contribution_value(c_normalized_feature_contribution, c_feature_contribution_value)
611
+ feature_contribution_value = c_feature_contribution_value.read(:float)
612
+ NormalizedFeatureContribution.new(
613
+ column_name: column_name,
614
+ feature_value: feature_value,
615
+ feature_contribution_value: feature_contribution_value
616
+ )
617
+ end
618
+
619
+ def get_one_hot_encoded_feature_contribution(c_feature_contribution)
620
+ c_one_hot_encoded_feature_contribution = FFI::MemoryPointer.new(:pointer)
621
+ LibTangram.tangram_feature_contribution_entry_as_one_hot_encoded(c_feature_contribution, c_one_hot_encoded_feature_contribution)
622
+ c_one_hot_encoded_feature_contribution = c_one_hot_encoded_feature_contribution.read_pointer
623
+ c_column_name = LibTangram::TangramStringView.new
624
+ LibTangram.tangram_one_hot_encoded_feature_contribution_get_column_name(c_one_hot_encoded_feature_contribution, c_column_name)
625
+ column_name = c_column_name.into_string
626
+ c_feature_contribution_value = FFI::MemoryPointer.new(:float)
627
+ LibTangram.tangram_one_hot_encoded_feature_contribution_get_feature_contribution_value(c_one_hot_encoded_feature_contribution, c_feature_contribution_value)
628
+ feature_contribution_value = c_feature_contribution_value.read(:float)
629
+ c_feature_value = FFI::MemoryPointer.new(:float)
630
+ LibTangram.tangram_one_hot_encoded_feature_contribution_get_feature_value(c_one_hot_encoded_feature_contribution, c_feature_value)
631
+ feature_value = c_feature_value.read(:float)
632
+ c_variant = LibTangram::TangramStringView.new
633
+ LibTangram.tangram_one_hot_encoded_feature_contribution_get_variant(c_one_hot_encoded_feature_contribution, c_variant)
634
+ variant = c_variant[:ptr].null? ? nil : c_variant.into_string
635
+ OneHotEncodedFeatureContribution.new(
636
+ column_name: column_name,
637
+ variant: variant,
638
+ feature_contribution_value: feature_contribution_value,
639
+ feature_value: feature_value
640
+ )
641
+ end
642
+
643
+ def get_bag_of_words_feature_contribution(c_feature_contribution)
644
+ c_bag_of_words_feature_contribution = FFI::MemoryPointer.new(:pointer)
645
+ LibTangram.tangram_feature_contribution_entry_as_bag_of_words(c_feature_contribution, c_bag_of_words_feature_contribution)
646
+ c_bag_of_words_feature_contribution = c_bag_of_words_feature_contribution.read_pointer
647
+ c_column_name = LibTangram::TangramStringView.new
648
+ LibTangram.tangram_bag_of_words_feature_contribution_get_column_name(c_bag_of_words_feature_contribution, c_column_name)
649
+ column_name = c_column_name.into_string
650
+ c_feature_contribution_value = FFI::MemoryPointer.new(:float)
651
+ LibTangram.tangram_bag_of_words_feature_contribution_get_feature_contribution_value(c_bag_of_words_feature_contribution, c_feature_contribution_value)
652
+ feature_contribution_value = c_feature_contribution_value.read(:float)
653
+ c_feature_value = FFI::MemoryPointer.new(:float)
654
+ LibTangram.tangram_bag_of_words_feature_contribution_get_feature_value(c_bag_of_words_feature_contribution, c_feature_value)
655
+ feature_value = c_feature_value.read(:float)
656
+ c_ngram = FFI::MemoryPointer(:pointer)
657
+ LibTangram.tangram_bag_of_words_feature_contribution_get_ngram(c_bag_of_words_feature_contribution, c_ngram)
658
+ c_ngram = c_ngram.read_pointer
659
+ ngram = get_ngram(c_ngram)
660
+ BagOfWordsFeatureContribution.new(
661
+ column_name: column_name,
662
+ ngram: ngram,
663
+ feature_contribution_value: feature_contribution_value,
664
+ feature_value: feature_value
665
+ )
666
+ end
667
+
668
+ def get_word_embedding_feature_contribution(c_feature_contribution)
669
+ c_word_embedding_feature_contribution = FFI::MemoryPointer.new(:pointer)
670
+ LibTangram.tangram_feature_contribution_entry_as_word_embedding(
671
+ c_feature_contribution, c_word_embedding_feature_contribution
672
+ )
673
+ c_word_embedding_feature_contribution = c_word_embedding_feature_contribution.read_pointer
674
+ c_column_name = LibTangram::TangramStringView.new
675
+ LibTangram.tangram_word_embedding_feature_contribution_get_column_name(c_word_embedding_feature_contribution, c_column_name)
676
+ column_name = c_column_name.into_string
677
+ c_feature_contribution_value = FFI::MemoryPointer.new(:float)
678
+ LibTangram.tangram_word_embedding_feature_contribution_get_feature_contribution_value(c_word_embedding_feature_contribution, c_feature_contribution_value)
679
+ feature_contribution_value = c_feature_contribution_value.read(:float)
680
+ c_value_index = FFI::MemoryPointer.new(:int)
681
+ LibTangram.tangram_word_embedding_feature_contribution_get_value_index(c_word_embedding_feature_contribution, c_value_index)
682
+ value_index = c_value_index.read(:int)
683
+ WordEmbeddingFeatureContribution.new(
684
+ column_name: column_name,
685
+ value_index: value_index,
686
+ feature_contribution_value: feature_contribution_value
687
+ )
688
+ end
689
+
690
+ def get_ngram(ngram)
691
+ c_ngram_type = FFI::MemoryPointer.new(:int)
692
+ LibTangram.tangram_ngram_get_type(ngram, ngram_type)
693
+ case c_ngram_type.read(:int)
694
+ when LibTangram::TangramNGramType[:unigram]
695
+ get_unigram_ngram(ngram)
696
+ when LibTangram::TangramNGramType[:bigram]
697
+ get_bigram_ngram(ngram)
698
+ end
699
+ end
700
+
701
+ def get_unigram_ngram(ngram)
702
+ c_token = LibTangram::TangramStringView.new
703
+ LibTangram.tangram_unigram_get_token(ngram, c_token)
704
+ token = c_token.into_string
705
+ Unigram.new(
706
+ token: token
707
+ )
708
+ end
709
+
710
+ def get_bigram_ngram(ngram)
711
+ c_token_a = LibTangram::TangramStringView.new
712
+ c_token_b = LibTangram::TangramStringView.new
713
+ LibTangram.tangram_bigram_get_token_a(ngram, c_token_a)
714
+ LibTangram.tangram_bigram_get_token_b(ngram, c_token_b)
715
+ token_a = c_token_a.into_string
716
+ token_b = c_token_b.into_string
717
+ Bigram.new(
718
+ token_a: token_a,
719
+ token_b: token_b
720
+ )
721
+ end
722
+ end
723
+
724
+ module LibTangram
725
+ cpu = RbConfig::CONFIG['host_cpu']
726
+ os = RbConfig::CONFIG['host_os']
727
+ if (cpu == 'x86_64') && os =~ (/linux/)
728
+ library_path = 'libtangram/x86_64-unknown-linux-gnu/libtangram.so'
729
+ elsif (cpu == 'x86_64') && os =~ (/darwin/)
730
+ library_path = 'libtangram/x86_64-apple-darwin/libtangram.dylib'
731
+ elsif (cpu == 'x86_64') && os =~ (/mingw/)
732
+ library_path = 'libtangram/x86_64-pc-windows-msvc/tangram.dll'
733
+ else
734
+ raise 'Tangram for Ruby does not yet support your combination of CPU architecture and operating system. Open an issue at https://github.com/tangramxyz/tangram/issues/new or email us at help@tangram.xyz to complain.'
735
+ end
736
+ extend FFI::Library
737
+ ffi_lib File.expand_path(library_path.to_s, __dir__)
738
+
739
+ class TangramStringView < FFI::Struct
740
+ layout :ptr, :pointer,
741
+ :len, :int
742
+ def into_string
743
+ self[:ptr].read_string(self[:len]).force_encoding('utf-8')
744
+ end
745
+ end
746
+
747
+ TangramTaskType = enum(
748
+ :regression,
749
+ :binary_classification,
750
+ :multiclass_classification
751
+ )
752
+
753
+ TangramFeatureContributionEntryType = enum(
754
+ :identity,
755
+ :normalized,
756
+ :one_hot_encoded,
757
+ :bag_of_words,
758
+ :word_embedding
759
+ )
760
+
761
+ TangramNGramType = enum(
762
+ :unigram,
763
+ :bigram
764
+ )
765
+
766
+ typedef :pointer, :tangram_error
767
+
768
+ attach_function :tangram_error_get_message, [:pointer, TangramStringView.by_ref], :void
769
+ attach_function :tangram_error_delete, [:pointer], :void
770
+ attach_function :tangram_version, [TangramStringView.by_ref], :void
771
+ attach_function :tangram_model_from_bytes, [:pointer, :int, :pointer], :tangram_error
772
+ attach_function :tangram_model_from_path, [:string, :pointer], :tangram_error
773
+ attach_function :tangram_model_delete, [:pointer], :void
774
+ attach_function :tangram_model_get_id, [:pointer, TangramStringView.by_ref], :void
775
+ attach_function :tangram_model_get_task, [:pointer, :pointer], :void
776
+ attach_function :tangram_predict_input_new, [:pointer], :void
777
+ attach_function :tangram_predict_input_delete, [:pointer], :void
778
+ attach_function :tangram_predict_input_set_value_number, [:pointer, :string, :double], :int
779
+ attach_function :tangram_predict_input_set_value_string, [:pointer, :string, :string], :int
780
+ attach_function :tangram_predict_input_vec_new, [:pointer], :void
781
+ attach_function :tangram_predict_input_vec_delete, [:pointer], :void
782
+ attach_function :tangram_predict_input_vec_push, [:pointer, :pointer], :void
783
+ attach_function :tangram_predict_options_new, [:pointer], :void
784
+ attach_function :tangram_predict_options_delete, [:pointer], :void
785
+ attach_function :tangram_predict_options_set_threshold, [:pointer, :float], :void
786
+ attach_function :tangram_predict_options_set_compute_feature_contributions, [:pointer, :bool], :void
787
+ attach_function :tangram_model_predict, [:pointer, :pointer, :pointer, :pointer], :tangram_error
788
+ attach_function :tangram_predict_output_delete, [:pointer], :void
789
+ attach_function :tangram_predict_output_vec_delete, [:pointer], :void
790
+ attach_function :tangram_predict_output_vec_len, [:pointer, :pointer], :void
791
+ attach_function :tangram_predict_output_vec_get_at_index, [:pointer, :int, :pointer], :void
792
+ attach_function :tangram_predict_output_as_regression, [:pointer, :pointer], :void
793
+ attach_function :tangram_predict_output_as_binary_classification, [:pointer, :pointer], :void
794
+ attach_function :tangram_predict_output_as_multiclass_classification, [:pointer, :pointer], :void
795
+ attach_function :tangram_regression_predict_output_get_value, [:pointer, :pointer], :void
796
+ attach_function :tangram_regression_predict_output_get_feature_contributions, [:pointer, :pointer], :void
797
+ attach_function :tangram_binary_classification_predict_output_get_class_name, [:pointer, TangramStringView.by_ref], :void
798
+ attach_function :tangram_binary_classification_predict_output_get_probability, [:pointer, :pointer], :void
799
+ attach_function :tangram_binary_classification_predict_output_get_feature_contributions, [:pointer, :pointer], :void
800
+ attach_function :tangram_multiclass_classification_predict_output_get_class_name, [:pointer, TangramStringView.by_ref], :void
801
+ attach_function :tangram_multiclass_classification_predict_output_get_probability, [:pointer, :pointer], :void
802
+ attach_function :tangram_multiclass_classification_predict_output_get_probabilities_len, [:pointer, :pointer], :void
803
+ attach_function :tangram_multiclass_classification_predict_output_probabilities_iter_delete, [:pointer], :void
804
+ attach_function :tangram_multiclass_classification_predict_output_get_probabilities_iter, [:pointer, :pointer], :void
805
+ attach_function :tangram_multiclass_classification_predict_output_probabilities_iter_next, [:pointer, :pointer, :pointer], :bool
806
+ attach_function :tangram_multiclass_classification_predict_output_feature_contributions_iter_delete, [:pointer], :void
807
+ attach_function :tangram_multiclass_classification_predict_output_get_feature_contributions_iter, [:pointer, :pointer], :void
808
+ attach_function :tangram_multiclass_classification_predict_output_feature_contributions_iter_next, [:pointer, :pointer, :pointer], :bool
809
+ attach_function :tangram_feature_contributions_get_baseline_value, [:pointer, :pointer], :void
810
+ attach_function :tangram_feature_contributions_get_output_value, [:pointer, :pointer], :void
811
+ attach_function :tangram_feature_contributions_get_entries_len, [:pointer, :pointer], :void
812
+ attach_function :tangram_feature_contributions_get_entry_at_index, [:pointer, :int, :pointer], :void
813
+ attach_function :tangram_feature_contribution_entry_get_type, [:pointer, :pointer], :void
814
+ attach_function :tangram_feature_contribution_entry_as_identity, [:pointer, :pointer], :void
815
+ attach_function :tangram_feature_contribution_entry_as_normalized, [:pointer, :pointer], :void
816
+ attach_function :tangram_feature_contribution_entry_as_one_hot_encoded, [:pointer, :pointer], :void
817
+ attach_function :tangram_feature_contribution_entry_as_bag_of_words, [:pointer, :pointer], :void
818
+ attach_function :tangram_feature_contribution_entry_as_word_embedding, [:pointer, :pointer], :void
819
+ attach_function :tangram_identity_feature_contribution_get_column_name, [:pointer, TangramStringView.by_ref], :void
820
+ attach_function :tangram_identity_feature_contribution_get_feature_value, [:pointer, :pointer], :void
821
+ attach_function :tangram_identity_feature_contribution_get_feature_contribution_value, [:pointer, :pointer], :void
822
+ attach_function :tangram_normalized_feature_contribution_get_column_name, [:pointer, TangramStringView.by_ref], :void
823
+ attach_function :tangram_normalized_feature_contribution_get_feature_value, [:pointer, :pointer], :void
824
+ attach_function :tangram_normalized_feature_contribution_get_feature_contribution_value, [:pointer, :pointer], :void
825
+ attach_function :tangram_one_hot_encoded_feature_contribution_get_column_name, [:pointer, TangramStringView.by_ref], :void
826
+ attach_function :tangram_one_hot_encoded_feature_contribution_get_variant, [:pointer, TangramStringView.by_ref], :void
827
+ attach_function :tangram_one_hot_encoded_feature_contribution_get_feature_value, [:pointer, :pointer], :void
828
+ attach_function :tangram_one_hot_encoded_feature_contribution_get_feature_contribution_value, [:pointer, :pointer], :void
829
+ attach_function :tangram_bag_of_words_feature_contribution_get_column_name, [:pointer, TangramStringView.by_ref], :void
830
+ attach_function :tangram_bag_of_words_feature_contribution_get_feature_value, [:pointer, :pointer], :void
831
+ attach_function :tangram_bag_of_words_feature_contribution_get_feature_contribution_value, [:pointer, :pointer], :void
832
+ attach_function :tangram_bag_of_words_feature_contribution_get_ngram, [:pointer, :pointer], :void
833
+ attach_function :tangram_ngram_get_type, [:pointer, :pointer], :void
834
+ attach_function :tangram_unigram_get_token, [:pointer, TangramStringView.by_ref], :void
835
+ attach_function :tangram_bigram_get_token_a, [:pointer, TangramStringView.by_ref], :void
836
+ attach_function :tangram_bigram_get_token_b, [:pointer, TangramStringView.by_ref], :void
837
+ attach_function :tangram_word_embedding_feature_contribution_get_column_name, [:pointer, TangramStringView.by_ref], :void
838
+ attach_function :tangram_word_embedding_feature_contribution_get_value_index, [:pointer, :pointer], :void
839
+ attach_function :tangram_word_embedding_feature_contribution_get_feature_contribution_value, [:pointer, :pointer], :void
840
+ end
841
+ end