【知识发现】【知识发现】隐语义模型LFM算法python实现(一)
来源:互联网 发布:双十一淘宝购物技巧 编辑:程序博客网 时间:2024/05/24 01:41
1、隐语义模型:
物品:表示为长度为k的向量q(每个分量都表示 物品具有某个特征的程度)
用户兴趣:表示为长度为k的向量p(每个分量都表示 用户对某个特征的喜好程度)
用户u对物品i的兴趣可以表示为:
其损失函数定义为:
使用随机梯度下降,获得参数p,q。
负样本生成:对于只有正反馈信息(用户收藏了,关注了xxx)的数据集,需要生成负样本,原则如下
1)生成的负样本要和正样本数量相当
2)物品越热门(用户没有收藏该物品),越有可能是负样本
2、数据集:https://grouplens.org/datasets/movielens/
格式:
3、参考代码:
# -*- coding: utf-8 -*-'''Created on 2017年9月15日@author: Jason.F'''from math import expimport pandas as pdimport numpy as npimport pickleimport timefrom numpy import rankdef getUserNegativeItem(frame, userID): ''' 获取用户负反馈物品:热门但是用户没有进行过评分 与正反馈数量相等 :param frame: ratings数据 :param userID:用户ID :return: 负反馈物品 ''' userItemlist = list(set(frame[frame['userid'] == userID]['itemid'])) #用户评分过的物品 otherItemList = [item for item in set(frame['itemid'].values) if item not in userItemlist] #用户没有评分的物品 itemCount = [len(frame[frame['itemid'] == item]['userid']) for item in otherItemList] #物品热门程度 series = pd.Series(itemCount, index=otherItemList) series = series.sort_values(ascending=False)[:len(userItemlist)] #获取正反馈物品数量的负反馈物品 negativeItemList = list(series.index) return negativeItemListdef getUserPositiveItem(frame, userID): ''' 获取用户正反馈物品:用户评分过的物品 :param frame: ratings数据 :param userID: 用户ID :return: 正反馈物品 ''' series = frame[frame['userid'] == userID]['itemid'] positiveItemList = list(series.values) return positiveItemListdef initUserItem(frame, userID=1): ''' 初始化用户正负反馈物品,正反馈标签为1,负反馈为0 :param frame: ratings数据 :param userID: 用户ID :return: 正负反馈物品字典 ''' positiveItem = getUserPositiveItem(frame, userID) negativeItem = getUserNegativeItem(frame, userID) itemDict = {} for item in positiveItem: itemDict[item] = 1 for item in negativeItem: itemDict[item] = 0 return itemDictdef initUserItemPool(frame,userID): ''' 初始化目标用户样本 :param userID:目标用户 :return: ''' userItem = [] for id in userID: itemDict = initUserItem(frame, userID=id) userItem.append({id:itemDict}) return userItemdef initPara(userID, itemID, classCount): ''' 初始化参数q,p矩阵, 随机 :param userCount:用户ID :param itemCount:物品ID :param classCount: 隐类数量 :return: 参数p,q ''' arrayp = np.random.rand(len(userID), classCount) #构造p矩阵,[0,1]内随机值 arrayq = np.random.rand(classCount, len(itemID)) #构造q矩阵,[0,1]内随机值 p = pd.DataFrame(arrayp, columns=range(0,classCount), index=userID) q = pd.DataFrame(arrayq, columns=itemID, index=range(0,classCount)) return p,qdef initModel(frame, classCount): ''' 初始化模型:参数p,q,样本数据 :param frame: 源数据 :param classCount: 隐类数量 :return: ''' userID = list(set(frame['userid'].values)) itemID = list(set(frame['itemid'].values)) p, q = initPara(userID, itemID, classCount)#初始化p、q矩阵 userItem = initUserItemPool(frame,userID)#建立用户-物品对应关系 return p, q, userItemdef latenFactorModel(frame, classCount, iterCount, alpha, lamda): ''' 隐语义模型计算参数p,q :param frame: 源数据 :param classCount: 隐类数量 :param iterCount: 迭代次数 :param alpha: 步长 :param lamda: 正则化参数 :return: 参数p,q ''' p, q, userItem = initModel(frame, classCount) for step in range(0, iterCount): for user in userItem: for userID, samples in user.items(): for itemID, rui in samples.items(): eui = rui - lfmPredict(p, q, userID, itemID) for f in range(0, classCount): print('step %d user %d class %d' % (step, userID, f)) p[f][userID] += alpha * (eui * q[itemID][f] - lamda * p[f][userID]) q[itemID][f] += alpha * (eui * p[f][userID] - lamda * q[itemID][f]) alpha *= 0.9 return p, qdef sigmod(x): ''' 单位阶跃函数,将兴趣度限定在[0,1]范围内 :param x: 兴趣度 :return: 兴趣度 ''' y = 1.0/(1+exp(-x)) return ydef lfmPredict(p, q, userID, itemID): ''' 利用参数p,q预测目标用户对目标物品的兴趣度 :param p: 用户兴趣和隐类的关系 :param q: 隐类和物品的关系 :param userID: 目标用户 :param itemID: 目标物品 :return: 预测兴趣度 ''' p = np.mat(p.ix[userID].values) q = np.mat(q[itemID].values).T r = (p * q).sum() r = sigmod(r) return rdef recommend(frame, userID, p, q, TopN=10): ''' 推荐TopN个物品给目标用户 :param frame: 源数据 :param userID: 目标用户 :param p: 用户兴趣和隐类的关系 :param q: 隐类和物品的关系 :param TopN: 推荐数量 :return: 推荐物品 ''' userItemlist = list(set(frame[frame['userid'] == userID]['itemid'])) otherItemList = [item for item in set(frame['itemid'].values) if item not in userItemlist] predictList = [lfmPredict(p, q, userID, itemID) for itemID in otherItemList] series = pd.Series(predictList, index=otherItemList) series = series.sort_values(ascending=False)[:TopN] return seriesdef Recall(df_test,p,q):#召回率 hit=0 all=0 df_userid=df_test['userid'] df_userid=df_userid.drop_duplicates() for userid in df_userid: pre_item=recommend(df_test, userid, p, q) df_user_item=df_test.loc[df_test['userid'] == userid] true_item=df_user_item['itemid'] for itemid,prob in pre_item.items(): if itemid in true_item: hit+=1 all+=len(true_item) return hit/(all*1.0)def Precision(df_test,p,q): hit=0 all=0 df_userid=df_test['userid'] df_userid=df_userid.drop_duplicates() for userid in df_userid: pre_item=recommend(df_test, userid, p, q) df_user_item=df_test.loc[df_test['userid'] == userid] true_item=df_user_item['itemid'] for itemid,prob in pre_item.items(): if itemid in true_item: hit+=1 all+=len(pre_item) return hit/(all*1.0) if __name__ == '__main__': start = time.clock() #导入数据 df_sample = pd.read_csv("D:\\tmp\\ratings.csv",names=['userid','itemid','ratings','time'],header=0) #模型训练 p, q = latenFactorModel(df_sample,5, 3, 0.02, 0.01 ) #模型评估 df_test=df_sample.sample(frac=0.2)#抽20%来测试 print (Recall(df_test,p,q))#召回率 print (Precision(df_test,p,q))#准确率
print (Coverage(df_test,p,q))#覆盖率 end = time.clock() print('finish all in %s' % str(end - start))
实际推荐应用中,应结合特征工程开展。
补充覆盖率评价指标的函数:
def Coverage(df_test,p,q):#覆盖率 df_itemid=df_test['itemid'] df_itemid=df_itemid.drop_duplicates() rec_items=set()#推荐的物品总数 df_userid=df_test['userid'] df_userid=df_userid.drop_duplicates() for userid in df_userid: pre_item=recommend(df_test, userid, p, q) for itemid,prob in pre_item.items(): rec_items.add(itemid) return len(rec_items)/(len(df_itemid)*1.0)
阅读全文
0 0
- 【知识发现】【知识发现】隐语义模型LFM算法python实现(一)
- 【知识发现】隐语义模型LFM算法python实现(二)
- 【知识发现】隐语义模型LFM算法python实现(三)
- 隐语义模型LFM
- LFM隐语义模型
- 隐语义模型(LFM)
- 推荐系统之隐语义模型(LFM)
- 重叠社区发现-LFM算法
- 知识发现
- 大数据推荐算法之隐语义模型(lfm)进行Top-N推荐
- 【知识发现】基于用户的协同过滤推荐算法python实现
- 【知识发现】基于物品的协同过滤推荐算法python实现
- 【知识发现】python开源哈夫曼编码库huffman
- 使用LFM(Latent factor model)隐语义模型进行Top-N推荐
- 使用LFM(Latent factor model)隐语义模型进行Top-N推荐
- 使用LFM(Latent factor model)隐语义模型进行Top-N推荐
- 使用LFM(Latent factor model)隐语义模型进行Top-N推荐
- 使用LFM(Latent factor model)隐语义模型进行Top-N推荐
- spring循环引用
- IOS-UITabBarController
- 4419: [Shoi2013]发微博
- BLOCKBENCH:一种评估私有链的框架(上)
- JSON 的三种解析方式
- 【知识发现】【知识发现】隐语义模型LFM算法python实现(一)
- php检测字串是不是回文
- 暗黑的字符串
- 图解排序算法(四)之归并排序
- Vue, App与我(十二)
- PHP 仿陌陌直播
- 多态 抽象类 接口
- 如何利用github绑定自己的域名
- HTTP协议详解(转载)