zoukankan      html  css  js  c++  java
  • 利用SVD-推荐未尝过的菜肴

    推荐未尝过的菜肴-基于物品相似度的推荐

    推荐系统的工作过程:给定一个用户,系统会为此用户返回N个最好的推荐菜

      1. 寻找用户没有评级的菜肴,即在用户-物品矩阵中的0值

      2. 在用户没有评级的所有物品中,对每个物品预计一个可能的评级分数(利用相似度计算)。这就是说,我们预测用户对每个物品的打分

      3. 对这些物品的评分从高到低进行排序,返回前N个物品

    from numpy import *
    from numpy import linalg as la

    一、相似度计算(欧式距离、皮尔逊相关系数、余弦相似度)

    # 相似度计算
    # 计算欧式距离
    def ecludSim(inA, inB):
        return 1.0 / (1.0 + la.norm(inA - inB))
    
    # pearsim()函数会检查是否存在3个或更多的点
    # corrcoef直接计算皮尔逊相关系数,范围[-1, 1],归一化后[0, 1]
    def pearsSim(inA, inB):
        # 如果不存在,该函数返回1.0,此时两个向量完全相关
        if len(inA) < 3:
            return 1.0
        return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]
    
    # 计算余弦相似度,如果夹角为90度,相似度为0;如果两个向量的方向相同,相似度为1.0
    def cosSim(inA, inB): 
        num = float(inA.T * inB)
        denom = la.norm(inA) * la.norm(inB)
        return 0.5 + 0.5 * (num / denom)

    二、基于物品相似度的推荐

    计算未评分物品的分值:用已评分物品的分值以及与未评分物品的相似度进行评分

    # 基于物品相似度的推荐引擎
    def standEst(dataMat, user, simMeas, item):
        """standEst(计算用户未评分物品中,以对该物品和其他物品评分的用户的物品相似度,然后进行综合评分)
        Args:
            dataMat 训练数据集
            user    用户编号
            simMeas 相似度计算方法
            item    未评分的物品编号
        Return:
            ratSimTotal / simTotal  评分(0~5之间的值)
        """
        # 得到数据集中物品数目
        n = shape(dataMat)[1]
        
        # 初始化两个评分值
        simTotal = 0.0
        ratSimTotal = 0.0
        # 遍历行中的每个物品(对用户评过分的物品进行遍历,并将它与其他物品进行比较)
        for j in range(n):
            userRating = dataMat[user, j]
            # 如果某个物品的评分值为0,则跳过这个物品
            if userRating == 0: 
                continue
            
            # 寻找两个用户都评级的物品
            # 变量overlap给出的是两个物品当中已经被评分的那个元素的索引ID
            # logical_and 计算x1和x2元素的真值
            overLap = nonzero(logical_and(dataMat[:, item].A > 0, dataMat[:, j].A > 0))[0]
            
            if len(overLap) == 0: 
                similarity = 0
            # 如果存在重合的物品,则基于这些重合物重新计算相似度
            else:
                similarity = simMeas(dataMat[overLap, item], dataMat[overLap, j])
                
            # 相似度会不断累加,每次计算时还考虑相似度和当前用户评分的乘积
            # similarity  用户相似度  userRating  用户评分
            simTotal += similarity
            ratSimTotal += similarity * userRating
        if simTotal == 0:
            return 0
        # 通过除以所有的评分总合,对上述相似度评分的乘积进行归一化,使得最后评分在0~5之间,这些评分用来对预测进行排序
        else:
            return ratSimTotal / simTotal    

    三、排序获取最后的推荐结果

    # recommend()函数,就是推荐引擎,它默认调用 standEst()函数,产生了最高的N个推荐结果
    # 如果不指定N的大小,则默认值为3,该函数另外的参数该包括相似度计算方法和估计方法
    def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
        """recommend()
        Args:
            dataMat 训练数据集
            user    用户编号
            simMeas 相似度计算方法
            estMethod 使用的推荐算法
        Returns:
            返回最终N个推荐结果
        """
        # 寻找未评级的物品
        # 对给定用户建立一个未评分的物品列表
        unratedItems = nonzero(dataMat[user, :].A == 0)[1]
        # 如果不存在未评分物品,那么就退出函数
        if len(unratedItems) == 0:
            return 'you rated everything'
        # 物品的编号和评分值
        itemScores = []
        for item in unratedItems:
            # 获取 item 该物品的评分
            estimatedScore = estMethod(dataMat, user, simMeas, item)
            itemScores.append((item, estimatedScore))
        # 按照评分得分,进行逆排序,获取前N个未评级物品进行推荐
        return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[: N]

    四、矩阵测试

    myMat = mat([[4, 4, 0, 2, 2],
               [4, 0, 0, 3, 3],
               [4, 0, 0, 1, 1],
               [1, 1, 1, 2, 0],
               [2, 2, 2, 0, 0],
               [1, 1, 1, 0, 0],
               [5, 5, 5, 0, 0]])
    recommend(myMat, 2)
    [(2, 2.5), (1, 2.0243290220056256)]
    这表明用户2(从0开始计数,对应是矩阵第三行),对物品2的预测评分为2.5,对物品1预测评分为2.02

    使用其他方法进行推荐:

    recommend(myMat, 2, simMeas=ecludSim)
    [(2, 3.0), (1, 2.8266504712098603)]
    recommend(myMat, 2, simMeas=pearsSim)
    [(2, 2.5), (1, 2.0)]
  • 相关阅读:
    实验一 网络侦查与网络扫描
    网络对抗作业一
    [BSidesCF 2020]Hurdles
    [BSidesCF 2019]Mixer
    安恒期末 admin
    C#编程:正则表达式验证身份证校验码-10
    分享1-3年经验的Java面试
    SpringMVC配置web.xml文件详解(列举常用的配置)
    Hibernate全套增删改查+分页
    Node.js连接mysql数据库方法
  • 原文地址:https://www.cnblogs.com/gezhuangzhuang/p/10204999.html
Copyright © 2011-2022 走看看