图书系统的算法

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)
            

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值