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))

      

  • 相关阅读:
    数据库范式
    将DBF,XLS,XML,MDB文件导入C#DataGrid的方法
    在类文件中引用Server对象
    在使用了母版页的页面里加载css和js文件
    IIS 7.5 URL重写参数
    hdu Can you solve this equation?
    hdu Dome of Circus
    hdu Bone Collector
    hdu Turn the corner
    hdu 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
  • 原文地址:https://www.cnblogs.com/glove/p/7258387.html
Copyright © 2011-2022 走看看