Regular_MF.py
import time
import copy
import numpy as np
from shared_parameter import *
from load_data import train_data, test_data, item_id_list, user_id_list, predict_step
user_vector = np.zeros([len(user_id_list), hidden_dim]) + 0.01
item_vector = np.zeros([len(item_id_list), hidden_dim]) + 0.01
def iterate():
for i in range(len(user_id_list)):
for r in range(len(train_data[user_id_list[i]])):
'''
对于每个user,遍历他的所有交互item,每次计算都更新user的行和item的列
print('我想看看上面这一句是什么:')
print(user_id_list[i])
1出现23次 4出现13次 5出现12次 6出现18次 7出现20次 8出现14次 10出现9次
加在一起正好109个交互记录
# print(train_data[user_id_list[i]])
train_data[user_id_list[i]]表示用户user_id_list[i]的所有记录,list形式
'''
item_id, rate, _ = train_data[user_id_list[i]][r]
'''
train_data[user_id_list[i]][r]表示
用户交互记录train_data[user_id_list[i]][r]第r条记录
例:[15, 5.0, 964983815]
item_id存储该item在item_id_list列表中的索引
rate存储用户user_id_list[i]对该item的评分
'''
error = rate - np.dot(user_vector[i], np.transpose(item_vector[item_id]))
user_vector[i] = user_vector[i] - \
lr * (-2 * error * item_vector[item_id] + 2 * reg_u * user_vector[i])
'''
print('------------------')
负数:print(lr * (-2 * error * item_vector[item_id] + 2 * reg_u * user_vector[i]))
print(user_vector[i])
'''
item_vector[item_id] = item_vector[item_id] - \
lr * (-2 * error * user_vector[i] + 2 * reg_v * item_vector[item_id])
def loss():
loss = []
for i in range(len(user_id_list)):
for r in range(len(train_data[user_id_list[i]])):
item_id, rate, _ = train_data[user_id_list[i]][r]
error = (rate - np.dot(user_vector[i], np.transpose(item_vector[item_id]))) ** 2
'''
Time 0.0019617080688476562 s
loss 0.7326558669374119
Converged
rmse 1.3969165
'''
'''
Time 0.0009965896606445312 s
loss 0.7326558669374119
Converged
rmse 1.3969165
上面两句好像结果一样
'''
loss.append(error)
return np.mean(loss)
if __name__ == '__main__':
for iteration in range(max_iteration):
print('#################################')
print('Iteration', iteration)
'''
deepcopy一旦复制出来了,就独立了
copy.copy()
copy.deepcopy()
'''
tmp_user_vector = copy.deepcopy(user_vector)
tmp_item_vector = copy.deepcopy(item_vector)
t = time.time()
iterate()
'''
tmp_user_vector = copy.deepcopy(user_vector)
tmp_item_vector = copy.deepcopy(item_vector)
记录上一个值
经过iterate(),user_vector和item_vector都更新了
'''
print('Time', time.time() - t, 's')
print('loss', loss())
'''
每一次迭代iterate()得到的user_vector和item_vector都不一样
因为每次作为初始矩阵都不一样了error也就不一样了
'''
'''
print(np.abs(user_vector - tmp_user_vector)) 输出矩阵 7×100矩阵每一行值一样
print(np.mean(np.abs(user_vector - tmp_user_vector))) 矩阵所有元素相减除以总数
1e-4=0.0001
'''
if np.mean(np.abs(user_vector - tmp_user_vector)) < 1e-4 and\
np.mean(np.abs(item_vector - tmp_item_vector)) < 1e-4:
print('Converged')
break
np.save('user-%s' % len(user_id_list), user_vector)
np.save('item-%s' % len(item_id_list), item_vector)
prediction = []
real_label = []
'''这样相乘的话,与user_i无关的item也参与了'''
for i in range(len(user_id_list)):
'''
# i从0开始到6,有7个user
每个user有3个交互记录
一共可得21个评分预测
'''
p = np.dot(user_vector[i:i+1], np.transpose(item_vector))[0]
r = test_data[user_id_list[i]]
real_label.append([e[1] for e in r])
prediction.append([p[e[0]] for e in r])
'''p[e[0]]表示p矩阵的第几个记录,这个记录是与用户真实交互的,无关的item直接忽略不要'''
prediction = np.array(prediction, dtype=np.float32)
real_label = np.array(real_label, dtype=np.float32)
print('rmse', np.sqrt(np.mean(np.square(real_label - prediction))))
print('mae', np.mean(np.abs(real_label - prediction)))