-
Notifications
You must be signed in to change notification settings - Fork 0
/
multi_iter_svd.py
141 lines (111 loc) · 3.9 KB
/
multi_iter_svd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Assignment #2
Project: To implement both SVD and CUR Matrix decomposition algorithms and
compare their efficency (in terms of space, time etc.)
Instructor: Dr. Aruna Malapati
Contributors: G V Sandeep 2014A7PS106H
Kushagra Agrawal 2014AAPS334H
Snehal Wadhwani 2014A7PS430H
Course: CS F469 Information Retrieval
"""
import numpy as np
import math
import time
from numpy import linalg as LA
from common import handle_input, calc_error
from svd import eigen_pairs
"""
Calculating the matrices U,V and Sigma based on the eigen values returned by the numpy.linalg.eig function
"""
ratings = handle_input("test.txt")
start_time = time.time()
for_U = eigen_pairs(np.dot(ratings,ratings.T))
for_V = eigen_pairs(np.dot(ratings.T,ratings))
eigen_values = []
for j in for_U:
if abs(j) !=0 :
eigen_values.append(round(j,2))
eigen_values = sorted(eigen_values)
neg_energy = 0.0
energy = 0.0
for j in eigen_values:
energy = energy + j
for j in xrange(len(eigen_values)):
neg_energy = neg_energy + eigen_values[j]
if neg_energy/energy < 0.099:
eigen_values[j] = 0.0
for j in eigen_values[:]:
if j == 0:
eigen_values.remove(j)
eigen_values = sorted(eigen_values)[::-1]
U = np.zeros((len(eigen_values),len(for_U[eigen_values[0]])))
for i in xrange(len(eigen_values)):
for j in xrange(len(for_U[eigen_values[i]])):
U[i][j] = for_U[eigen_values[i]][j]
U = U.T
V = np.zeros((len(eigen_values),len(for_V[eigen_values[0]])))
for i in xrange(len(eigen_values)):
for j in xrange(len(for_V[eigen_values[i]])):
V[i][j] = for_V[eigen_values[i]][j]
sigma = np.zeros((len(eigen_values),len(eigen_values)))
for i in range(len(sigma)):
sigma[i][i] = eigen_values[i]**0.5
###############################################################################################################
"""
Here we are trying to find the minimum possible frobenius error by iterating through all the possible values of eigen vectors
"""
final_U = np.zeros((len(eigen_values),len(for_U[eigen_values[0]])))
final_V = np.zeros((len(eigen_values),len(for_V[eigen_values[0]])))
final_matrix = np.dot(U,np.dot(sigma,V))
temp_error = calc_error(ratings, final_matrix)
final_error = 0.0
for i in xrange(len(U[0])):
print "Running U for column ",i
U[:,i] = U[:,i]*-1
temp_matrix = np.dot(U,np.dot(sigma,V))
iter_error = calc_error(ratings, temp_matrix)
if iter_error < temp_error:
temp_error = iter_error
final_error = iter_error
final_U = U
final_matrix = temp_matrix
print "Currently,the best possible matrix \n",final_matrix
print "Currently,the best possible error ", final_error
U[:,i] = U[:,i]*-1
for i in xrange(len(V)):
print "Running V for row ",i
V[i] = V[i]*-1
temp_matrix = np.dot(U,np.dot(sigma,V))
iter_error = calc_error(ratings, temp_matrix)
if iter_error < temp_error:
temp_error = iter_error
final_error = iter_error
final_V = V
final_matrix = temp_matrix
print "Currently,the best possible matrix \n" ,final_matrix
print "Currently,the best possible error ", final_error
V[i] = V[i]*-1
for i in xrange(len(U[0])):
U[:,i] = U[:,i] * -1
for j in xrange(len(V)):
print "Running U for column ",i," V for row ",j
V[j] = V[j]*-1
iter_error = calc_error(ratings, np.dot(U,np.dot(sigma,V)))
if iter_error < temp_error :
final_U = U
final_V = V
final_error = iter_error
temp_error = final_error
final_matrix = np.dot(final_U,np.dot(sigma,final_V))
print "Currently,the best possible matrix \n",final_matrix
print "Currently,the best possible error ",final_error
V[j] = V[j]*-1
U[:,i] = U[:,i]*-1
print "Frobenius Error Of the SVD Decomposition is : ",final_error
print "The matrix obtained by multiplying U , sigma and V' :"
for i in xrange(len(final_matrix)):
for j in xrange(len(final_matrix[i])):
final_matrix[i][j] = round(final_matrix[i][j],2)
print final_matrix
print " ************* Execution Time : ************* "
print "--- %s seconds ---" %(time.time() - start_time)