zoukankan      html  css  js  c++  java
  • 基于Python 的简单推荐系统

    def loadExData():
        return[[1,1,1,0,0],
                [2,2,2,0,0],
                [1,1,1,0,0],
                [5,5,5,0,0],
                [1,1,0,2,2],
                [0,0,0,3,3],
                [0,0,0,1,1]]
    
    def loadExData2():
        return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
               [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
               [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
               [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
               [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
               [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
               [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
               [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
               [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
               [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
               [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
        
    from numpy import * 
    from numpy import linalg as la 
    #欧氏距离
    def euclidSim(inA,inB):
        return 1.0/(1.0+la.norm(inA-inB))
    #皮尔逊相关系数  
    def pearsSim(inA,inB):
        if len(inA)<3:return 1.0
        return 0.5+0.5*corrcoef(inA,inB,rowvar=0)[0][1]
    
    #余弦相似度
    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):
        #商品数目
        n=shape(dataMat)[1]
        #两个用于计算估计评分值的变量
        simTotal=0.0;ratSimTotal=0.0
        #遍历所有商品,并将它与所有的物品进行比较
        for j in range(n):
            #用户对某个物品的评分
            userRating=dataMat[user,j]
            if userRating==0:continue
            # logical_and:矩阵逐个元素运行逻辑与,返回值为每个元素的True,False  
            # dataMat[:,item].A>0: 第item列中大于0的元素  
            # dataMat[:,j].A: 第j列中大于0的元素  
            # overLap: dataMat[:,item],dataMat[:,j]中同时都大于0的那个元素的行下标(一个向量) 
            overLap=nonzero(logical_and(dataMat[:,item].A>0,
                                        dataMat[:,j].A>0))[0]
            print(j)
            print("------overLap------")
            print(overLap)
            if len(overLap)==0:similarity=0
            # 计算overLap矩阵的相似度
            else: similarity=simMeas(dataMat[overLap,item],
                            dataMat[overLap,j])
            print("dataMat[overLap,item:")
            print(dataMat[overLap,item])
            print("dataMat[overLap,j:")
            print(dataMat[overLap,j])
            print ('the %d and %d similarity is:%f' % (item,j,similarity))
            # 累计总相似度(不太理解)
    #        假设A评分未知,A,B相似度0.9,B评分5,;A C相似度0.8,C评分4.
    #        那么按照公式A评分=(0.9*5+0.8*4)/(0.9+0.8)
    #       相当于加权平均(如果除以2),但是因为2个评分的权重是不一样的,所以应除以相似度之和
            simTotal+=similarity
            # ratSimTotal = 相似度*元素值 
            
            ratSimTotal+=similarity*userRating
            print("ratSimTotal+=similarity*userRating:")
            print(ratSimTotal)
        if simTotal==0:return 0
        else:return ratSimTotal/simTotal
    
    #对某个用户产生最高的N个推荐结果
    #user 表示要推荐的用户编号
    def recommend(dataMat,user,N=3,simMeas=cosSim,estMethod=standEst):
        #对给定用户建立一个未评分的物品矩阵
        unratedItems=nonzero(dataMat[user,:].A==0)[1] #第user行中等于0的元素 
    #    print(dataMat[user,:].A==0)----[[ True  True  True ...,  True False  True]]
    #    对于二维数组b2,nonzero(b2)所得到的是一个长度为2的元组。它的第0个元素是数组a中值不为0的元素的第0轴的下标,第1个元素则是第1轴的下标,因此从下面的结果可知b2[0,0]、b[0,2]和b2[1,0]的值不为0:
    #
    #>>> b2 = np.array([[True, False, True], [True, False, False]])  
    #>>> np.nonzero(b2)  
    #(array([0, 0, 1], dtype=int64), array([0, 2, 0], dtype=int64))  
       
        if len(unratedItems)==0:return 'you rated everything'
        #给未评分物品存放预测得分的列表
        itemScores=[]
        for item in unratedItems:
            #对每个未评分物品通过standEst()方法来预测得分
            print("item------------")
            print(item)
            estimatedScore=estMethod(dataMat,user,simMeas,item)
            #将物品编号和估计得分存放在列表中
            itemScores.append((item,estimatedScore))
        #sorted排序函数,key 是按照关键字排序,lambda是隐函数,固定写法,
        #jj表示待排序元祖,jj[1]按照jj的第二列排序,reverse=True,降序;[:N]前N个
        return sorted(itemScores,key=lambda jj:jj[1],reverse=True)[:N]
        
    #利用SVD提高推荐效果
    #基于SVD的评分估计
    def svdEst(dataMat,user,simMeas,item):
        #商品数目    
        n=shape(dataMat)[1]
        simTotal=0.0;ratSimTotal=0.0
        #SVD分解为:U*S*V
        U,Sigma,VT=la.svd(dataMat)
        #分解后只利用90%能量的奇异值,存放在numpy数组里面
        Sig4=mat(eye(4)*Sigma[:4])
        #利用U矩阵将物品转换到低维空间中
        xformeditems=dataMat.T*U[:,:4]*Sig4.I
        for j in range(n):
            userRating=dataMat[user,j]
            if userRating==0 or j==item:continue
            similarity=simMeas(xformeditems[item,:].T,
                                xformeditems[j,:].T)
            print ('the %d and %d similarity is :%f' % (item,j,similarity))
            simTotal+=similarity
            ratSimTotal+=similarity*userRating
        if simTotal==0:return 0
        else: return ratSimTotal/simTotal 
        
    if __name__ == '__main__':
       myMat=mat(loadExData2())
       print(recommend(myMat,2))

      

  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/glove/p/7258387.html
Copyright © 2011-2022 走看看