monkeylearn 0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b8b41d5910d61c77645da60123ad508a1e444eb0
4
+ data.tar.gz: 6d385382a783204a3e8cfa9d8044a755815e206f
5
+ SHA512:
6
+ metadata.gz: 5138110e12266e1fc4841a75ddf8928b5c3aa222d09236773cf76172443857451de6ede605201f99f488ccba5b7d03485fd96d52b8e7dac5802e12040f71548c
7
+ data.tar.gz: 551435a4e5a476e335d67db0631db44dfea2f663df04a6f19ca7b199b4355c3d3d5859b85b9757c732f8668024f2e5b95cd4b80bb8bc521b841c529b1c4b7ce5
@@ -0,0 +1,142 @@
1
+ # monkeylearn-ruby
2
+
3
+ Official Ruby client for the MonkeyLearn API. Build and consume machine learning models for language processing from your Ruby apps.
4
+
5
+ Installation
6
+ ------------
7
+
8
+ Install with rubygems:
9
+
10
+ gem install monkeylearn
11
+
12
+ Or add this line to your Gemfile
13
+
14
+ gem "monkeylearn"
15
+
16
+ Quick start
17
+ -----------
18
+
19
+ First require and configure the lib:
20
+
21
+ ```ruby
22
+ require 'monkeylearn'
23
+
24
+ # Basic configuration
25
+ Monkeylearn.configure do |c|
26
+ c.token = 'INSERT_YOUR_API_TOKEN_HERE'
27
+ end
28
+ ```
29
+
30
+ Classification:
31
+
32
+ ```ruby
33
+ r = Monkeylearn.classifiers.classify('cl_hDDngsX8', ['Hola te va amigo?', 'How are you doing mate?'], sandbox: false)
34
+ r.result
35
+ # => [[{"probability"=>0.461, "label"=>"Spanish"}], [{"probability"=>0.996, "label"=>"English"}]]
36
+ ```
37
+
38
+ Extraction:
39
+
40
+ ```ruby
41
+ r = Monkeylearn.extractors.extract('ex_y7BPYzNG', ['A panel of Goldman Sachs employees spent a recent Tuesday night at the Columbia University faculty club'])
42
+ r.result
43
+ # => [[{"relevance"=>"0.962", "count"=>1, "positions_in_text"=>[80], "keyword"=>"University faculty club"}, {"relevance"=>"0.962", "count"=>1, "positions_in_text"=>[43], "keyword"=>"recent Tuesday night"}, {"relevance"=>"0.962", "count"=>1, "positions_in_text"=>[11], "keyword"=>"Goldman Sachs employees"}, {"relevance"=>"0.385", "count"=>1, "positions_in_text"=>[2], "keyword"=>"panel"}]]
44
+ ```
45
+
46
+ Pipelines:
47
+
48
+ ```ruby
49
+ data = {
50
+ input: [
51
+ { text: "Friendly service, superior room! Loved the high ceiling. Housekeeping service should have been a little better. Excellent breakfast and fitness room." }
52
+ ]
53
+ }
54
+ r = Monkeylearn.pipelines.run('pi_WNo4z7fJ', data, sandbox: false)
55
+ r.result
56
+ # => {"result"=>{"sentiment_labels"=>[{"sentiment"=>[{"probability"=>1.0, "label"=>"Good"}], "sentence"=>"Friendly service, superior room!"}, {"sentiment"=>[{"probability"=>1.0, "label"=>"Good"}], "sentence"=>"Loved the high ceiling."}, {"sentiment"=>[{"probability"=>0.5, "label"=>"Bad"}], "sentence"=>"Housekeeping service should have been a little better."}, {"sentiment"=>[{"probability"=>0.912, "label"=>"Good"}], "sentence"=>"Excellent breakfast and fitness room."}]}}
57
+ ```
58
+
59
+ Classifiers endpoints example
60
+ -----------------------------
61
+
62
+ Create a new classifier:
63
+
64
+ ```ruby
65
+ r = Monkeylearn.classifiers.create('Test API sentiment classifier',
66
+ description: 'This is a sentiment classifier created with the monkeylearn ruby API client',
67
+ language: 'en')
68
+ classifier_id = r.result['result']['classifier']['hashed_id']
69
+ ```
70
+
71
+ Get the details from the new classifier and the root category id:
72
+
73
+ ```ruby
74
+ r = Monkeylearn.classifiers.detail(classifier_id)
75
+ root_category_id = r.result['result']['sandbox_categories'][0]['id']
76
+ ```
77
+
78
+ Create two child categories:
79
+
80
+ ```ruby
81
+ r = Monkeylearn.classifiers.categories.create(classifier_id, 'Positive', root_category_id)
82
+ positive_category_id = r.result['result']['category']['id']
83
+
84
+ r = Monkeylearn.classifiers.categories.create(classifier_id, 'Negative', root_category_id)
85
+ negative_category_id = r.result['result']['category']['id']
86
+ ```
87
+
88
+ Upload some samples to each category:
89
+
90
+ ```ruby
91
+ samples = {
92
+ positive_category_id => ['Nice beatiful', 'awesome excelent'],
93
+ negative_category_id => ['Awful bad', 'sad pale'],
94
+ }
95
+ r = Monkeylearn.classifiers.upload_samples(classifier_id, samples)
96
+ ```
97
+
98
+ Train the classifier:
99
+
100
+ ```ruby
101
+ Monkeylearn.classifiers.train(classifier_id)
102
+ ```
103
+
104
+ Classify using the sandbox:
105
+
106
+ ```ruby
107
+ r = Monkeylearn.classifiers.classify(classifier_id, ['Awesome excelence'], sandbox: true)
108
+ r.result
109
+ # => [[{"probability"=>0.998, "label"=>"Positive"}]]
110
+ ```
111
+
112
+ Deploy a live version:
113
+
114
+ ```ruby
115
+ Monkeylearn.classifiers.deploy(classifier_id)
116
+ ```
117
+
118
+ Classify using the live classifier:
119
+
120
+ ```ruby
121
+ r = Monkeylearn.classifiers.classify(classifier_id, ['Awesome excelence'], sandbox: false)
122
+ r.result
123
+ # => [[{"probability"=>0.998, "label"=>"Positive"}]]
124
+ ```
125
+
126
+ Edit a category, rename and move the negative category:
127
+
128
+ ```ruby
129
+ r = Monkeylearn.classifiers.categories.edit(classifier_id, negative_category_id, 'Positive child', positive_category_id)
130
+ ```
131
+
132
+ Delete a category:
133
+
134
+ ```ruby
135
+ r = Monkeylearn.classifiers.categories.delete(classifier_id, negative_category_id)
136
+ ```
137
+
138
+ Delete the classifier:
139
+
140
+ ```ruby
141
+ r = Monkeylearn.classifiers.delete(classifier_id)
142
+ ```
@@ -0,0 +1,14 @@
1
+ require 'monkeylearn/configurable'
2
+ require 'monkeylearn/exceptions'
3
+ require 'monkeylearn/classifiers'
4
+ require 'monkeylearn/extractors'
5
+ require 'monkeylearn/pipelines'
6
+
7
+
8
+ module Monkeylearn
9
+ class << self
10
+ include Monkeylearn::Configurable
11
+ end
12
+ end
13
+
14
+ Monkeylearn.reset!
@@ -0,0 +1,135 @@
1
+ require 'monkeylearn/requests'
2
+
3
+ module Monkeylearn
4
+ class << self
5
+ def classifiers
6
+ return Classifiers
7
+ end
8
+ end
9
+
10
+ module Classifiers
11
+ class << self
12
+ include Monkeylearn::Requests
13
+
14
+ def categories
15
+ return Categories
16
+ end
17
+
18
+ def build_endpoint(*args)
19
+ File.join('classifiers', *args) + '/'
20
+ end
21
+
22
+ def validate_batch_size(batch_size)
23
+ max_size = Monkeylearn::Defaults.max_batch_size
24
+ if batch_size > max_size
25
+ raise MonkeylearnError, "The param batch_size is too big, max value is #{max_size}."
26
+ end
27
+ min_size = Monkeylearn::Defaults.min_batch_size
28
+ if batch_size < min_size
29
+ raise MonkeylearnError, "The param batch_size is too small, min value is #{min_size}."
30
+ end
31
+ true
32
+ end
33
+
34
+ def classify(module_id, texts, options = {})
35
+ options[:batch_size] ||= Monkeylearn::Defaults.default_batch_size
36
+ batch_size = options[:batch_size]
37
+ validate_batch_size batch_size
38
+
39
+ endpoint = build_endpoint(module_id, 'classify')
40
+ query_params = { sandbox: true } if options[:sandbox]
41
+
42
+ responses = (0...texts.length).step(batch_size).collect do |start_idx|
43
+ data = { text_list: texts.slice(start_idx, batch_size) }
44
+ response = request :post, endpoint, data, query_params
45
+ end
46
+
47
+ Monkeylearn::MultiResponse.new(responses)
48
+ end
49
+
50
+ def create(name, options = {})
51
+ data = {
52
+ name: name,
53
+ description: options[:description],
54
+ language: options[:language],
55
+ ngram_range: options[:ngram_range],
56
+ use_stemmer: options[:use_stemmer],
57
+ stop_words: options[:stop_words],
58
+ max_features: options[:max_features],
59
+ strip_stopwords: options[:strip_stopwords],
60
+ is_multilabel: options[:is_multilabel],
61
+ is_twitter_data: options[:is_twitter_data],
62
+ normalize_weights: options[:normalize_weights],
63
+ classifier: options[:classifier],
64
+ industry: options[:industry],
65
+ classifier_type: options[:classifier_type],
66
+ text_type: options[:text_type],
67
+ permissions: options[:permissions]
68
+ }.delete_if { |k,v| v.nil? }
69
+ request :post, build_endpoint, data
70
+ end
71
+
72
+ def detail(module_id)
73
+ request :get, build_endpoint(module_id)
74
+ end
75
+
76
+ def upload_samples(module_id, samples_with_categories)
77
+ endpoint = build_endpoint(module_id, 'samples')
78
+ data = {
79
+ samples: samples_with_categories.collect do |category_id, texts|
80
+ texts.collect { |text| {text: text, category_id: category_id} }
81
+ end.flatten(1)
82
+ }
83
+ request :post, endpoint, data
84
+ end
85
+
86
+ def train(module_id)
87
+ request :post, build_endpoint(module_id, 'train')
88
+ end
89
+
90
+ def deploy(module_id)
91
+ request :post, build_endpoint(module_id, 'deploy')
92
+ end
93
+
94
+ def delete(module_id)
95
+ request :delete, build_endpoint(module_id)
96
+ end
97
+ end
98
+ end
99
+
100
+ module Categories
101
+ class << self
102
+ include Monkeylearn::Requests
103
+
104
+ def build_endpoint(module_id, *args)
105
+ File.join('classifiers', module_id, 'categories', *args.collect { |x| x.to_s }) + '/'
106
+ end
107
+
108
+ def create(module_id, name, parent_id)
109
+ data = {
110
+ name: name,
111
+ parent_id: parent_id
112
+ }
113
+ request :post, build_endpoint(module_id), data
114
+ end
115
+
116
+ def edit(module_id, category_id, name = nil, parent_id = nil)
117
+ endpoint = build_endpoint(module_id, category_id)
118
+ data = {
119
+ name: name,
120
+ parent_id: parent_id
121
+ }.delete_if { |k,v| v.nil? }
122
+ request :patch, endpoint, data
123
+ end
124
+
125
+ def delete(module_id, category_id, samples_strategy = nil, samples_category_id = nil)
126
+ endpoint = build_endpoint(module_id, category_id)
127
+ data = {
128
+ 'samples-strategy'.to_s => samples_strategy,
129
+ 'samples-category-id'.to_s => samples_category_id
130
+ }.delete_if { |k,v| v.nil? }
131
+ request :delete, endpoint, data
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,37 @@
1
+ require 'monkeylearn/defaults'
2
+
3
+ module Monkeylearn
4
+ module Configurable
5
+ attr_accessor :token, :api_endpoint
6
+ attr_writer :api_endpoint
7
+
8
+ class << self
9
+ def keys
10
+ @keys ||= [
11
+ :api_endpoint,
12
+ :token,
13
+ :wait_on_throttle
14
+ ]
15
+ end
16
+ end
17
+
18
+ def configure
19
+ yield self
20
+ end
21
+
22
+ def reset!
23
+ Monkeylearn::Configurable.keys.each do |key|
24
+ instance_variable_set(:"@#{key}", Monkeylearn::Defaults.options[key])
25
+ end
26
+ self
27
+ end
28
+
29
+ def wait_on_throttle
30
+ @wait_on_throttle
31
+ end
32
+
33
+ def api_endpoint
34
+ File.join(@api_endpoint, "")
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ module Monkeylearn
2
+ module Defaults
3
+ # Constants
4
+ DEFAULT_BATCH_SIZE = 200
5
+ MAX_BATCH_SIZE = 500
6
+ MIN_BATCH_SIZE = 100
7
+ # Configurable options
8
+ API_ENDPOINT = 'https://api.monkeylearn.com/v2/'
9
+ WAIT_ON_THROTTLE = true
10
+
11
+ class << self
12
+ def options
13
+ Hash[Monkeylearn::Configurable.keys.map{|key| [key, send(key)]}]
14
+ end
15
+
16
+ def api_endpoint
17
+ ENV['MONKEYLEARN_API_ENDPOINT'] || API_ENDPOINT
18
+ end
19
+
20
+ def token
21
+ ENV['MONKEYLEARN_TOKEN'] || nil
22
+ end
23
+
24
+ def wait_on_throttle
25
+ ENV['MONKEYLEARN_WAIT_ON_THROTTLE'] || WAIT_ON_THROTTLE
26
+ end
27
+
28
+ def max_batch_size
29
+ MAX_BATCH_SIZE
30
+ end
31
+
32
+ def min_batch_size
33
+ MIN_BATCH_SIZE
34
+ end
35
+
36
+ def default_batch_size
37
+ DEFAULT_BATCH_SIZE
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,2 @@
1
+ class MonkeylearnError < StandardError
2
+ end
@@ -0,0 +1,46 @@
1
+ require 'monkeylearn/requests'
2
+
3
+ module Monkeylearn
4
+ class << self
5
+ def extractors
6
+ return Extractors
7
+ end
8
+ end
9
+
10
+ module Extractors
11
+ class << self
12
+ include Monkeylearn::Requests
13
+
14
+ def build_endpoint(*args)
15
+ File.join('extractors', *args) + '/'
16
+ end
17
+
18
+ def validate_batch_size(batch_size)
19
+ max_size = Monkeylearn::Defaults.max_batch_size
20
+ if batch_size > max_size
21
+ raise MonkeylearnError, "The param batch_size is too big, max value is #{max_size}."
22
+ end
23
+ min_size = Monkeylearn::Defaults.min_batch_size
24
+ if batch_size < min_size
25
+ raise MonkeylearnError, "The param batch_size is too small, min value is #{min_size}."
26
+ end
27
+ true
28
+ end
29
+
30
+ def extract(module_id, texts, options = {})
31
+ options[:batch_size] ||= Monkeylearn::Defaults.default_batch_size
32
+ batch_size = options[:batch_size]
33
+ validate_batch_size batch_size
34
+
35
+ endpoint = build_endpoint(module_id, 'extract')
36
+
37
+ responses = (0...texts.length).step(batch_size).collect do |start_idx|
38
+ data = { text_list: texts.slice(start_idx, batch_size) }
39
+ response = request :post, endpoint, data
40
+ end
41
+
42
+ Monkeylearn::MultiResponse.new(responses)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ require 'monkeylearn/requests'
2
+
3
+ module Monkeylearn
4
+ class << self
5
+ def pipelines
6
+ return Pipelines
7
+ end
8
+ end
9
+
10
+ module Pipelines
11
+ class << self
12
+ include Monkeylearn::Requests
13
+
14
+ def build_endpoint(*args)
15
+ File.join('pipelines', *args) + '/'
16
+ end
17
+
18
+ def run(module_id, data, options = {})
19
+ query_params = { sandbox: true } if options[:sandbox]
20
+ endpoint = build_endpoint(module_id, 'run')
21
+ unless data.is_a?(Hash)
22
+ raise MonkeylearnError, 'The data param must be a hash'
23
+ end
24
+ puts endpoint
25
+ request :post, endpoint, data
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ require 'faraday'
2
+ require 'json'
3
+ require 'monkeylearn/response'
4
+
5
+ module Monkeylearn
6
+ module Requests
7
+ def request(method, path, data = nil, query_params = nil)
8
+ response = get_connection.send(method) do |req|
9
+ url = path.to_s
10
+ if query_params
11
+ url += '?' + URI.encode_www_form(query_params)
12
+ end
13
+ req.url url
14
+ req.headers['Authorization'] = 'Token ' + Monkeylearn.token
15
+ req.headers['Content-Type'] = 'application/json'
16
+ if data
17
+ req.body = data.to_json
18
+ end
19
+ end
20
+ if Monkeylearn.wait_on_throttle && seconds = throttled?(response)
21
+ # Request was throttled, wait 'seconds' seconds and retry
22
+ sleep seconds
23
+ response = request(method, path, data)
24
+ end
25
+ Monkeylearn::Response.new(response)
26
+ end
27
+
28
+ def throttled?(response)
29
+ return false if response.status != 429
30
+ error_detail = JSON.parse(response.body)['detail']
31
+ match = /available in ([\d]+) seconds/.match(error_detail)
32
+ if match then match[1].to_i else false end
33
+ end
34
+
35
+ def get_connection
36
+ @conn ||= Faraday.new(url: Monkeylearn.api_endpoint) do |faraday|
37
+ faraday.adapter Faraday.default_adapter # Net::HTTP
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module Monkeylearn
2
+ class Response
3
+ attr_reader :raw_response, :result, :query_limit_remaining
4
+
5
+ def initialize(raw_response)
6
+ self.raw_response = raw_response
7
+ end
8
+
9
+ def raw_response=(raw_response)
10
+ @raw_response = raw_response
11
+ @result = JSON.parse(raw_response.body)
12
+ @query_limit_remaining = raw_response.headers['X-Query-Limit-Remaining'].to_i
13
+ end
14
+ end
15
+
16
+ class MultiResponse
17
+ attr_reader :responses, :result, :query_limit_remaining
18
+
19
+ def initialize(responses)
20
+ self.responses = responses
21
+ end
22
+
23
+ def responses=(responses)
24
+ @responses = responses
25
+ @query_limit_remaining = responses[-1].raw_response.headers['X-Query-Limit-Remaining'].to_i
26
+ @result = responses.collect do |r|
27
+ r.result['result']
28
+ end.reduce(:+)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'monkeylearn'
7
+ spec.summary = 'Ruby client for the MonkeyLearn API'
8
+ spec.description = 'A simple client for the MonkeyLearn API'
9
+ spec.authors = ['Monkeylearn']
10
+ spec.email = ['hello@monkeylearn.com']
11
+ spec.homepage = 'https://github.com/monkeylearn/monkeylearn-ruby'
12
+
13
+ spec.version = '0.1'
14
+ spec.add_dependency 'faraday', '>= 0.9.2'
15
+
16
+ spec.licenses = ['MIT']
17
+
18
+ spec.files = %w(README.md monkeylearn.gemspec)
19
+ spec.files += Dir.glob('lib/**/*.rb')
20
+ spec.require_paths = ['lib']
21
+ spec.required_ruby_version = '>= 1.9.2'
22
+ spec.required_rubygems_version = '>= 1.3.5'
23
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monkeylearn
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Monkeylearn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.2
27
+ description: A simple client for the MonkeyLearn API
28
+ email:
29
+ - hello@monkeylearn.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - monkeylearn.gemspec
36
+ - lib/monkeylearn/classifiers.rb
37
+ - lib/monkeylearn/configurable.rb
38
+ - lib/monkeylearn/defaults.rb
39
+ - lib/monkeylearn/exceptions.rb
40
+ - lib/monkeylearn/extractors.rb
41
+ - lib/monkeylearn/pipelines.rb
42
+ - lib/monkeylearn/requests.rb
43
+ - lib/monkeylearn/response.rb
44
+ - lib/monkeylearn.rb
45
+ homepage: https://github.com/monkeylearn/monkeylearn-ruby
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: 1.9.2
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.5
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.0.14
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Ruby client for the MonkeyLearn API
69
+ test_files: []