google-prediction 0.1.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.
- data/lib/google-prediction.rb +179 -0
- metadata +78 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
# Provides an interface to the Google Prediction API.
|
2
|
+
#
|
3
|
+
# Author:: Sam King (samking@cs.stanford.edu)
|
4
|
+
# Copyright:: InSTEDD[http://instedd.org]
|
5
|
+
# License:: GPLv3
|
6
|
+
|
7
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
8
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'curb'
|
12
|
+
require 'json'
|
13
|
+
|
14
|
+
module GooglePrediction
|
15
|
+
VERSION = '0.1.0'
|
16
|
+
|
17
|
+
# = Usage
|
18
|
+
#
|
19
|
+
# auth_token = GooglePrediction.client_login('foo@gmail.com', 'password')
|
20
|
+
# => long string of letters and numbers
|
21
|
+
#
|
22
|
+
# predictor = GooglePrediction.new(auth_token, 'bucket', 'object')
|
23
|
+
#
|
24
|
+
# predictor.#invoke_training
|
25
|
+
# => {"data"=>{"data"=>"bucket/object"}}
|
26
|
+
#
|
27
|
+
# predictor.#get_training_status
|
28
|
+
# => "Training has not completed"
|
29
|
+
#
|
30
|
+
# wait_some_time
|
31
|
+
#
|
32
|
+
# predictor.#get_training_status
|
33
|
+
# => "no estimate available" or something between "0.0" and "1.0"
|
34
|
+
#
|
35
|
+
# predictor.#get_prediction "awesome company"
|
36
|
+
# => "Google"
|
37
|
+
# predictor.#get_prediction "awesome nonprofit"
|
38
|
+
# => "InSTEDD"
|
39
|
+
# predictor.#get_prediction 13
|
40
|
+
# => "lucky"
|
41
|
+
# predictor.#get_prediction [3, 5, 7, 11]
|
42
|
+
# => "prime"
|
43
|
+
class GooglePrediction
|
44
|
+
PREDICTION_URL_PREFIX = 'https://www.googleapis.com/prediction/v1/training'
|
45
|
+
|
46
|
+
attr_reader :auth_code
|
47
|
+
attr_reader :bucket
|
48
|
+
attr_reader :object
|
49
|
+
|
50
|
+
# Gets the auth code from Google's ClientLogin using the provided email
|
51
|
+
# and password.
|
52
|
+
#
|
53
|
+
# This will fail if Google requires a Captcha. If so, follow the
|
54
|
+
# instructions at
|
55
|
+
# http://code.google.com/apis/predict/docs/getting-started.html
|
56
|
+
# and pass in the new URL and new arguments using the optional parameters.
|
57
|
+
def self.client_login(email, password, url='https://www.google.com/accounts/ClientLogin', args={})
|
58
|
+
curl = Curl::Easy.new(url)
|
59
|
+
post_args = {
|
60
|
+
"accountType" => "HOSTED_OR_GOOGLE",
|
61
|
+
"Email" => email,
|
62
|
+
"Passwd" => curl.escape(password),
|
63
|
+
"source" => "companyName-applicationName-versionID",
|
64
|
+
"service" => "xapi"
|
65
|
+
}
|
66
|
+
args.each {|key, val| post_args[key] = val }
|
67
|
+
post_fields = post_args.map {|k,v| Curl::PostField.content(k, v) }
|
68
|
+
curl.http_post(post_fields)
|
69
|
+
curl.body_str.match('Auth.*')[0][5..-1]
|
70
|
+
end
|
71
|
+
|
72
|
+
# auth_code: the login code generated from self.client_login
|
73
|
+
#
|
74
|
+
# bucket: the name of the bucket in Google Storage
|
75
|
+
#
|
76
|
+
# object: the filename of the object to do prediction on
|
77
|
+
def initialize(auth_code, bucket, object)
|
78
|
+
@auth_code=auth_code
|
79
|
+
@bucket=bucket
|
80
|
+
@object=object
|
81
|
+
end
|
82
|
+
|
83
|
+
# Wrapper. Creates a new object and runs invoke_training on it.
|
84
|
+
def self.invoke_training(auth_code, bucket, object)
|
85
|
+
predictor = GooglePrediction.new(auth_code, bucket, object)
|
86
|
+
predictor.invoke_training
|
87
|
+
end
|
88
|
+
|
89
|
+
# Wrapper. Creates a new object and runs get_training_status on it.
|
90
|
+
def self.get_training_status(auth_code, bucket, object)
|
91
|
+
predictor = GooglePrediction.new(auth_code, bucket, object)
|
92
|
+
predictor.get_training_status
|
93
|
+
end
|
94
|
+
|
95
|
+
# Wrapper. Creates a new object and runs get_prediction on it.
|
96
|
+
def self.get_prediction(auth_code, bucket, object, submission)
|
97
|
+
predictor = GooglePrediction.new(auth_code, bucket, object)
|
98
|
+
predictor.get_prediction(submission)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Starts training on the specified object.
|
102
|
+
#
|
103
|
+
# Returns
|
104
|
+
# {"data"=>{"data"=>"bucket/object"}}
|
105
|
+
# on success, and
|
106
|
+
# {"errors"=>{"errors"=>[{all of your errors}], "code"=>code, "message"=>message}}
|
107
|
+
# on error.
|
108
|
+
def invoke_training
|
109
|
+
url = PREDICTION_URL_PREFIX + "?data=" + @bucket + "%2F" + @object
|
110
|
+
curl = Curl::Easy.new(url)
|
111
|
+
curl.post_body = JSON.generate({:data => {}})
|
112
|
+
curl.headers = {"Content-Type" => "application/json",
|
113
|
+
"Authorization" => "GoogleLogin auth=#{@auth_code}"}
|
114
|
+
curl.http("POST")
|
115
|
+
JSON.parse(curl.body_str)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Gets the training status of the specified object.
|
119
|
+
#
|
120
|
+
# If the training is incomplete, returns "Training has not completed".
|
121
|
+
# If the training did not have enough data to do cross-fold validation,
|
122
|
+
# returns "no estimate available".
|
123
|
+
# If the training went as desired, returns the accuracy of the training
|
124
|
+
# from 0 to 1.
|
125
|
+
#
|
126
|
+
# Returns
|
127
|
+
# {"errors"=>{"errors"=>[{all of your errors}], "code"=>code, "message"=>message}}
|
128
|
+
# on error.
|
129
|
+
def get_training_status
|
130
|
+
url = PREDICTION_URL_PREFIX + "/" + @bucket + "%2F" + @object
|
131
|
+
curl = Curl::Easy.new(url)
|
132
|
+
curl.headers = {"Authorization" => "GoogleLogin auth=#{@auth_code}"}
|
133
|
+
curl.http_get
|
134
|
+
|
135
|
+
# response will be
|
136
|
+
# {"data"=>{"data"=>"bucket/object", "modelinfo"=>accuracy_prediction}}
|
137
|
+
# on success
|
138
|
+
response = JSON.parse(curl.body_str)
|
139
|
+
return response["data"]["modelinfo"] unless response["data"].nil?
|
140
|
+
return response
|
141
|
+
end
|
142
|
+
|
143
|
+
# Submission must be either a string, a single number,
|
144
|
+
# or an array of numbers
|
145
|
+
#
|
146
|
+
# Gets the prediction for the label of the submission based on the training.
|
147
|
+
#
|
148
|
+
# Returns the prediction on success and
|
149
|
+
# {"errors"=>{"errors"=>[{all of your errors}], "code"=>code, "message"=>message}}
|
150
|
+
# on error.
|
151
|
+
def get_prediction(submission)
|
152
|
+
url = PREDICTION_URL_PREFIX + "/" + @bucket + "%2F" + @object + "/predict"
|
153
|
+
curl = Curl::Easy.new(url)
|
154
|
+
post_body = {:data => {:input => {}}}
|
155
|
+
if submission.is_a? String
|
156
|
+
post_body[:data][:input] = {:text => [submission]}
|
157
|
+
elsif submission.is_a? Fixnum
|
158
|
+
post_body[:data][:input] = {:numeric => [submission]}
|
159
|
+
elsif submission.is_a? Array
|
160
|
+
post_body[:data][:input] = {:numeric => submission}
|
161
|
+
else
|
162
|
+
raise Exception.new("submission must be String, Fixnum, or Array")
|
163
|
+
end
|
164
|
+
curl.post_body = JSON.generate(post_body)
|
165
|
+
curl.headers = {"Content-Type" => "application/json",
|
166
|
+
"Authorization" => "GoogleLogin auth=#{@auth_code}"}
|
167
|
+
curl.http("POST")
|
168
|
+
|
169
|
+
# response will be
|
170
|
+
# {"data"=>{"output"=>{"output_label"=>label}}}
|
171
|
+
# on success
|
172
|
+
response = JSON.parse(curl.body_str)
|
173
|
+
return response["data"]["output"]["output_label"] unless response["data"].nil?
|
174
|
+
return response
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: google-prediction
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam King
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-08-18 00:00:00 +07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: curb
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.7.7.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.3
|
34
|
+
version:
|
35
|
+
description: |-
|
36
|
+
Generates an auth token from a google account
|
37
|
+
Trains using the auth token and data uploaded to Google Storage for Developers
|
38
|
+
Checks the training status
|
39
|
+
Predicts outputs when given new input
|
40
|
+
email: samking@cs.stanford.edu
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
files:
|
48
|
+
- lib/google-prediction.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://code.google.com/p/ruby-google-prediction/
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Google Prediction API interface for Ruby.
|
77
|
+
test_files: []
|
78
|
+
|