ruby-svd 0.1.0 → 0.2.0

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/svd_matrix.rb +37 -8
  2. metadata +3 -3
data/lib/svd_matrix.rb CHANGED
@@ -3,39 +3,68 @@ require 'svd'
3
3
 
4
4
  class SVDMatrix < Matrix
5
5
  public_class_method :new
6
+
7
+ # Create a new SVD Matrix with m rows, n columns
6
8
  def initialize(m, n)
7
9
  @rows = Array.new(m)
8
10
  m.times {|i| @rows[i] = Array.new(n)}
9
11
  end
10
12
 
13
+ # Set the value of the cell i, j
11
14
  def []=(i, j, val)
12
15
  @rows[i][j] = val
13
16
  end
14
17
 
15
- def []=(i, row)
18
+ # Set the value of a row to an array
19
+ def set_row(i, row)
16
20
  @rows[i] = row
17
21
  end
18
22
 
23
+ # Nicely formatted inspect string for the matrix
19
24
  def inspect
20
25
  @rows.collect {|row| "#{row.inspect}\n"}
21
26
  end
22
-
23
- def lsa
27
+
28
+ # Perform SVD and decompose the matrix into three matrices:
29
+ # U, W, and V. You can choose to reduce the dimensionality of
30
+ # the data by setting a number of diagonal cells to 0. For
31
+ # example, reduce_dimentions_to = 2 will set a 4x4 W
32
+ # matrix into:
33
+ # [NUM, 0, 0, 0]
34
+ # [0, NUM, 0, 0]
35
+ # [ 0, 0, 0, 0 ]
36
+ # [ 0, 0, 0, 0 ]
37
+ def decompose(reduce_dimensions_to = nil)
24
38
  input_array = []
25
39
  @rows.each {|row| input_array += row}
26
40
  u_array, w_array, v_array = SVD.decompose(input_array, row_size, column_size)
27
41
 
42
+ # recompose U matrix
28
43
  u = SVDMatrix.new(row_size, column_size)
29
- row_size.times {|i| u[i] = u_array.slice!(0,column_size)}
44
+ row_size.times {|i| u.set_row(i, u_array.slice!(0,column_size))}
30
45
 
46
+ # recompose V matric
31
47
  v = SVDMatrix.new(column_size, column_size)
32
- column_size.times {|i| v[i] = v_array.slice!(0,column_size)}
48
+ column_size.times {|i| v.set_row(i, v_array.slice!(0,column_size))}
33
49
  v = v.transpose
34
50
 
35
- w_array = w_array[0...2] + Array.new(w_array.size - 2).collect {|i| 0}
51
+ # diagonalise W array as a matrix
52
+ if reduce_dimensions_to
53
+ (reduce_dimensions_to...w_array.size).each {|index| w_array[index] = 0.0}
54
+ end
36
55
  w = Matrix.diagonal(*w_array)
37
56
 
38
- r = (u * w * v)
57
+ [u, w, v]
58
+ end
59
+
60
+ # Reduce the number of dimensions of the data to dimensions.
61
+ # Returns a back a recombined matrix (conceptually the original
62
+ # matrix dimensionally reduced). For example Latent Semantic
63
+ # Analysis uses 2 dimensions, and commonly tf-idf cell data.
64
+ # The recombined matrix, and the 3 decomposed matrices are
65
+ # returned.
66
+ def reduce_dimensions(dimensions)
67
+ u, w, v = self.decompose(dimensions)
68
+ [(u * w * v), u, w, v]
39
69
  end
40
70
  end
41
-
metadata CHANGED
@@ -4,12 +4,12 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
- - Will
12
+ - Will Cannings
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []