• qinggeouye
    2019-04-21
    # 优化了一下,运行时间减少一半以上
    # https://github.com/qinggeouye/GeekTime/blob/master/MathematicProgrammer/49_recommendSystem/lesson49_2.py

    import numpy as np
    import pandas as pd
    from sklearn.preprocessing import scale
    import time

    """
    对 lesson49_1.py 优化:矩阵操作
    """
    # 运行开始时间
    time_start = time.time()

    # 加载用户对电影对评分数据
    df = pd.read_csv("ml-latest-small/ratings.csv")

    # 获取用户对数量和电影对数量
    user_num = df["userId"].max()
    movie_num = df["movieId"].max()

    # 构造用户对电影的二元关系矩阵
    user_rating = np.zeros((user_num, movie_num))
    # 由于用户和电影的 ID 都是从 1 开始,为了和 Python 的索引一致,减去 1
    df["userId"] = df["userId"] - 1
    df["movieId"] = df["movieId"] - 1
    for index in range(user_num):
        user_rating[index][df[df["userId"] == index]["movieId"]] = df[df["userId"] == index]["rating"]

    # 把二维数组转化为矩阵
    x = np.mat(user_rating)
    # 对每一行对数据,进行标准化
    x_s = scale(x, with_mean=True, with_std=True, axis=1)

    # 获取 XX'
    y = x_s.dot(x_s.transpose())
    # 夹角余弦的分母
    v = np.zeros((np.shape(y)[0], np.shape(y)[1]))
    v[:] = np.diag(y)
    # 获用户相似度矩阵 US , 对应位置上元素相除
    us = y/v

    # 通过用户之间的相似度,计算 USP 矩阵
    usp = np.mat(us).dot(x_s)

    # 求用于归一化的分母 按行求和
    usr = np.sum(us, axis=1)

    # 进行元素对应的除法 归一化
    p = np.divide(usp, np.mat(usr).transpose())

    # 运行结束时间
    time_end = time.time()

    print(p)
    print(np.shape(p))

    print("程序运行耗时:", time_end - time_start)
    展开

    作者回复: 感谢代码的优化🙏

    
     4
  • CarreyWang
    2019-04-08
    您好,对于上面的代码有三个问题
    第一:
    # 设置用户对电影的评分
        i += 1
        if i % 10000 == 0:
            print(i)
    这里仅仅是为了打印出i吗??

    第二:
    计算矩阵时直接运行会有分母为0的情况导致报错。

    第三:
    最后一行代码是不是写错了??少个括号把。。。
    p = divide(usp, mat(usr).transpose()
    展开

    作者回复: 第1个只是为了显示加载进度,因为在我的机器上有点慢。
    第2个是很好的点,可以让分母加一个很小的值避免分母为0
    第3个确实漏了一个括号,回头补上

    感谢看得这么仔细,帮我找出了2个笔误 🤝

    
     3
  • Paul Shan
    2019-10-18
    原始推荐数据可以找出用户之间的相似度,再求出所有用户对任意电影的评价,进而补上那些原始推荐数据中没有的配对。
    
    
  • 冄~
    2019-04-28
    老师好,感觉按照公式来看,USR作为分母,第一行应该是US的第一行元素求和(1+0.482+0.671+0=2.153),而不是USP的第一行求和(0.500+0.790+0.496=1.786)。否则会像文中一样,p矩阵每行求和为1也是因为USR这样计算导致的。代码部分usr[userId] = sum(us[userId])应该是对的。不知我理解得对不对?

    作者回复: 我回头仔细看一下,可能是个笔误

     1
    
我们在线,来聊聊吧