cofi_cost 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/cofi_cost.rb +15 -33
  2. metadata +16 -6
data/lib/cofi_cost.rb CHANGED
@@ -6,10 +6,10 @@ include GSL::MultiMin
6
6
 
7
7
  class CofiCost
8
8
 
9
- attr_accessor :ratings, :num_features, :cost, :lambda, :iterations, :features, :theta
9
+ attr_accessor :ratings, :num_features, :cost, :regularization, :iterations, :features, :theta
10
10
  attr_reader :boolean_rated, :num_tracks, :num_users, :ratings_mean, :ratings_norm, :predictions
11
11
 
12
- def initialize(ratings, num_features = 2, lambda = 1, iterations = 10, features = nil, theta = nil)
12
+ def initialize(ratings, num_features = 2, regularization = 1, iterations = 10, features = nil, theta = nil)
13
13
  @ratings = ratings.to_f # make sure it's a float for correct normalization
14
14
  @num_features = num_features
15
15
  @cost = 0
@@ -24,7 +24,7 @@ class CofiCost
24
24
  @ratings_mean = NArray.float(1, @num_tracks).fill(0.0)
25
25
  @ratings_norm = NArray.float(@num_users, @num_tracks).fill(0.0)
26
26
  @ratings_mean, @ratings_norm = normalize_ratings
27
- @lambda = lambda
27
+ @regularization = regularization
28
28
  @predictions = nil
29
29
  @iterations = iterations
30
30
  end
@@ -32,7 +32,7 @@ class CofiCost
32
32
  def normalize_ratings
33
33
  for i in 0..@num_tracks-1 # sadly, @num_tracks.each_index does not work with NArray yet
34
34
  track_rating = @ratings[true,i] # get all user ratings for track i (including unrated)
35
- boolean_track_rating = boolean_rated[true,i] # get all user ratings that exist for track i
35
+ boolean_track_rating = @boolean_rated[true,i] # get all user ratings that exist for track i
36
36
  track_rating_boolean = track_rating[boolean_track_rating]
37
37
  if track_rating_boolean.size == 0
38
38
  @ratings_mean[i] = 0
@@ -54,21 +54,15 @@ class CofiCost
54
54
  return theta, features
55
55
  end
56
56
 
57
- def partial_cost_calc(theta,features)
57
+ def partial_cost_calc(theta=@theta,features=@features)
58
58
  (NArray.ref(NMatrix.ref(features) * NMatrix.ref(theta.transpose(1,0))) - @ratings_norm) * @boolean_rated
59
59
  end
60
60
 
61
61
  def roll_up_theta_and_features
62
- # roll up theta and features together
63
- # (oddly, NArray objects created don't seem to recognize the hcat method
64
- # added to the open class NArray
65
- # x = GSL:: Vector.alloc(@theta.reshape(true).hcat(@features.reshape(true)))
66
- # will fail)
67
- # I don't understand why this is/how to fix it.
68
62
  theta_reshaped = @theta.reshape(true)
69
63
  features_reshaped = @features.reshape(true)
70
64
  rolled = NArray.hcat(theta_reshaped,features_reshaped)
71
- GSL:: Vector.alloc(rolled) # starting point
65
+ GSL::Vector.alloc(rolled) # starting point
72
66
  end
73
67
 
74
68
  def unroll_params_init_shape(x)
@@ -79,22 +73,22 @@ class CofiCost
79
73
 
80
74
  def min_cost
81
75
  cost_f = Proc.new { |v|
82
- theta, features = unroll_params(v)
76
+ theta_l, features_l = unroll_params(v)
83
77
  # In octave:
84
- # 1/2 * sum(sum(((X * Theta.transpose - Y).*R).^2)) + lambda/2 * sum(sum((Theta).^2)) + lambda/2 * sum(sum((X).^2))
85
- (partial_cost_calc(theta,features)**2).sum + @lambda/2 * (features**2).sum
78
+ # 1/2 * sum(sum(((X * Theta.transpose - Y).*R).^2)) + regularization/2 * sum(sum((Theta).^2)) + regularization/2 * sum(sum((X).^2))
79
+ 0.5 * (partial_cost_calc(theta_l,features_l)**2).sum + @regularization/2 * (features_l**2).sum
86
80
  }
87
81
  cost_df = Proc.new { |v, df|
88
- theta, features = unroll_params(v)
82
+ theta_l, features_l = unroll_params(v)
89
83
  # In octave:
90
- # xgrad = ((X * Theta.transpose - Y).* R) * Theta + lambda * X # X_grad
91
- # thetagrad = ((X * Theta.transpose - Y).* R).transpose * X + lambda * Theta
84
+ # xgrad = ((X * Theta.transpose - Y).* R) * Theta + regularization * X # X_grad
85
+ # thetagrad = ((X * Theta.transpose - Y).* R).transpose * X + regularization * Theta
92
86
 
93
87
  # I realize this is a hack. I'm not totally sure why or how but just setting
94
- # df = NArray.hcat(dfzero,dfone) results in no steps being made in gradient descent.
88
+ # df = NArray.hcat(dfzero,dfone).to_gv results in no steps being made in gradient descent.
95
89
  # ideas/suggestions welcome :)
96
- dfzero = (NArray.ref(NMatrix.ref(partial_cost_calc(theta,features)) * NMatrix.ref(theta)) + @lambda * features).flatten
97
- dfone = (NArray.ref(NMatrix.ref((partial_cost_calc(theta,features)).transpose(1,0)) * NMatrix.ref(features)) + @lambda * theta).flatten
90
+ dfzero = (NArray.ref(NMatrix.ref(partial_cost_calc(theta_l,features_l)) * NMatrix.ref(theta_l)) + @regularization * features_l).flatten
91
+ dfone = (NArray.ref(NMatrix.ref((partial_cost_calc(theta_l,features_l)).transpose(1,0)) * NMatrix.ref(features_l)) + @regularization * theta_l).flatten
98
92
  dfcomp = NArray.hcat(dfzero,dfone)
99
93
  for i in 0..dfcomp.size-1 # again .each_index does not yet work with NArray
100
94
  df[i] = dfcomp[i]
@@ -157,15 +151,3 @@ class NArray
157
151
  def hcat(*narrays) ; cat(0, *narrays) end
158
152
  end
159
153
  end
160
-
161
- ##ratings = NArray.float(4,5).indgen(0,2)
162
- #ratings = NArray[[1.0,4.0],[4.0,0.0],[0.0,0.0]]
163
- #g = CofiCost.new(ratings, 5, 1, 10, nil, nil)
164
- #puts g.theta.nil?
165
- #g.min_cost
166
- #puts "new theta"
167
- #puts g.theta.to_a.to_s
168
- #puts "new features"
169
- #puts g.features.to_a.to_s
170
- #puts "predictions"
171
- #puts g.predictions.to_a.to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cofi_cost
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gsl
16
- requirement: &77565430 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *77565430
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: narray
27
- requirement: &77565210 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,7 +37,12 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *77565210
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  description: Playground for collaborative filtering in Ruby using NArray and rb-gsl.
37
47
  email: tomwolfe@gmail.com
38
48
  executables: []
@@ -64,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
74
  requirements:
65
75
  - libgsl0-dev
66
76
  rubyforge_project:
67
- rubygems_version: 1.8.11
77
+ rubygems_version: 1.8.23
68
78
  signing_key:
69
79
  specification_version: 3
70
80
  summary: Collaborative filtering