import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
# 字体问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def MF(data, k, alpha, beta, maxsteps):
"""矩阵分解的实现:
输入:
data:评分矩阵
k:矩阵分量的中间维度
alpha:学习步长
beta: 正则化参数
maxsteps:最大迭代次数
输出:
p:用户关系矩阵
q:产品关系矩阵的转置矩阵
loss:损失函数值
result: 损失函数值容器
"""
m, n = data.shape
p = np.random.random((m, k))
q = np.random.random((k, n))
result = []
for t in range(maxsteps):
# print(t)
for i in range(m):
for j in range(n):
if data[i,j]:
error = data[i][j] - np.dot(p[i,:], q[:,j])
for r in range(k):
p[i][r] += alpha * (2 * error * q[r][j] - beta * p[i][r])
q[r][j] += alpha * (2 * error * p[i][r] - beta * q[r][j])
loss = 0
for i in range(m):
for j in range(n):
if data[i,j]:
error = data[i][j] - np.dot(p[i,:], q[:,j])
loss += pow(error, 2)
for r in range(k):
loss += (beta/2) * (pow(p[i][r], 2) + pow(q[r][j], 2))
result.append(loss)
if (t+1) % 10 == 0:
print('第{}次迭代的损失值为:{:.2f}。'.format(t+1, loss))
if loss < 0.001:
break
return p, q, loss, result
def get_list_max_index(list_, n):
"""输出列表中最大的前n个数的索引
输入:
list:列表
n:需要输出的数目
输出:
最大的前n个数的索引列表
"""
N_large = pd.DataFrame({'score': list_}).sort_values(by='score', ascending=[False])
return list(N_large.index)[:n]
def recommend_information(data, new_MF, bxbooks, sort_user_rating, i, nums):
"""输出推荐书籍
输入:
data:原始评分矩阵
new_MF: 预测频分矩阵
bxbook: 书籍信息表
sort_user_rating:分数排名索引
i: 用户在矩阵中的下标
nums: 推荐书籍的本数
输出:
无
"""
num = 0
for k in sort_user_rating:
# print(data.values[i,k])
if data.values[i,k]:
continue
if data.columns[k] in bxbooks.index:
# print(data.columns[k])
num += 1
if num > nums:
break
book = bxbooks.loc[data.columns[k],'BookTitle'].replace("\*", "'")
book = book.replace("#", "'")
information = 'top{}'.format(num) + '书籍名为:{}'.format(book)
information = information + '({}),'.format(data.columns[k])
information = information + ',作者是:{},'.format(bxbooks.loc[data.columns[k],'BookAuthor'])
information = information + '预测分为:{:.2f}。'.format(new_MF.iloc[i,k])
print(information)
def select(data, new_MF, bxbooks, user, m, n, nums):
"""选择推荐书籍
输入:
data:原始评分矩阵
new_MF: 预测频分矩阵
bxbook: 书籍信息表
user:需要推荐用户名列表
i: 用户在矩阵中的下标
nums: 推荐书籍的本数
输出:
无
"""
user_index = data.index
for j in user:
print('给用户{}推荐的书籍名为:'.format(j))
i = list(user_index).index(j)
user_rating = new_MF.iloc[i,:].values
sort_user_rating = get_list_max_index(list(user_rating), n)
recommend_information(data, new_MF, bxbooks, sort_user_rating, i, nums)
def topN(path, new_path, bxbooks_path, user, nums):
"""推荐书籍
输入:
path:原始评分矩阵路径
new_path: 预测频分矩阵路径
bxbooks_path: 书籍信息表路径
user:需要推荐用户名列表
nums: 推荐书籍的本数
输出:
无
"""
data = pd.read_excel(path, index_col=0).replace(np.nan, 0)
new_MF = pd.read_excel(new_path, sheet_name='new', header=None)
bxbooks = pd.read_excel(bxbooks_path, index_col=0)
m, n = data.shape
select(data, new_MF, bxbooks, user, m, n, nums)
图书系统的算法
最新推荐文章于 2024-08-14 20:03:33 发布