日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

【知识发现】隐语义模型LFM算法python实现(一)

發(fā)布時(shí)間:2025/4/16 python 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【知识发现】隐语义模型LFM算法python实现(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、隱語(yǔ)義模型:

物品:表示為長(zhǎng)度為k的向量q(每個(gè)分量都表示 ?物品具有某個(gè)特征的程度)
用戶興趣:表示為長(zhǎng)度為k的向量p(每個(gè)分量都表示 ?用戶對(duì)某個(gè)特征的喜好程度)


用戶u對(duì)物品i的興趣可以表示為:

其損失函數(shù)定義為:
  

使用隨機(jī)梯度下降,獲得參數(shù)p,q。
負(fù)樣本生成:對(duì)于只有正反饋信息(用戶收藏了,關(guān)注了xxx)的數(shù)據(jù)集,需要生成負(fù)樣本,原則如下
1)生成的負(fù)樣本要和正樣本數(shù)量相當(dāng)
2)物品越熱門(用戶沒(méi)有收藏該物品),越有可能是負(fù)樣本

?

2、數(shù)據(jù)集:https://grouplens.org/datasets/movielens/

格式:

?

3、參考代碼:

?

# -*- coding: utf-8 -*- ''' Created on 2017年9月15日@author: Jason.F '''from math import exp import pandas as pd import numpy as np import pickle import time from numpy import rankdef getUserNegativeItem(frame, userID):'''獲取用戶負(fù)反饋物品:熱門但是用戶沒(méi)有進(jìn)行過(guò)評(píng)分 與正反饋數(shù)量相等:param frame: ratings數(shù)據(jù):param userID:用戶ID:return: 負(fù)反饋物品'''userItemlist = list(set(frame[frame['userid'] == userID]['itemid'])) #用戶評(píng)分過(guò)的物品otherItemList = [item for item in set(frame['itemid'].values) if item not in userItemlist] #用戶沒(méi)有評(píng)分的物品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)] #獲取正反饋物品數(shù)量的負(fù)反饋物品negativeItemList = list(series.index)return negativeItemListdef getUserPositiveItem(frame, userID):'''獲取用戶正反饋物品:用戶評(píng)分過(guò)的物品:param frame: ratings數(shù)據(jù):param userID: 用戶ID:return: 正反饋物品'''series = frame[frame['userid'] == userID]['itemid']positiveItemList = list(series.values)return positiveItemListdef initUserItem(frame, userID=1):'''初始化用戶正負(fù)反饋物品,正反饋標(biāo)簽為1,負(fù)反饋為0:param frame: ratings數(shù)據(jù):param userID: 用戶ID:return: 正負(fù)反饋物品字典'''positiveItem = getUserPositiveItem(frame, userID)negativeItem = getUserNegativeItem(frame, userID)itemDict = {}for item in positiveItem: itemDict[item] = 1for item in negativeItem: itemDict[item] = 0return itemDictdef initUserItemPool(frame,userID):'''初始化目標(biāo)用戶樣本:param userID:目標(biāo)用戶:return:'''userItem = []for id in userID:itemDict = initUserItem(frame, userID=id)userItem.append({id:itemDict})return userItemdef initPara(userID, itemID, classCount):'''初始化參數(shù)q,p矩陣, 隨機(jī):param userCount:用戶ID:param itemCount:物品ID:param classCount: 隱類數(shù)量:return: 參數(shù)p,q'''arrayp = np.random.rand(len(userID), classCount) #構(gòu)造p矩陣,[0,1]內(nèi)隨機(jī)值arrayq = np.random.rand(classCount, len(itemID)) #構(gòu)造q矩陣,[0,1]內(nèi)隨機(jī)值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):'''初始化模型:參數(shù)p,q,樣本數(shù)據(jù):param frame: 源數(shù)據(jù):param classCount: 隱類數(shù)量: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)#建立用戶-物品對(duì)應(yīng)關(guān)系return p, q, userItemdef latenFactorModel(frame, classCount, iterCount, alpha, lamda):'''隱語(yǔ)義模型計(jì)算參數(shù)p,q:param frame: 源數(shù)據(jù):param classCount: 隱類數(shù)量:param iterCount: 迭代次數(shù):param alpha: 步長(zhǎng):param lamda: 正則化參數(shù):return: 參數(shù)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.9return p, qdef sigmod(x):'''單位階躍函數(shù),將興趣度限定在[0,1]范圍內(nèi):param x: 興趣度:return: 興趣度'''y = 1.0/(1+exp(-x))return ydef lfmPredict(p, q, userID, itemID):'''利用參數(shù)p,q預(yù)測(cè)目標(biāo)用戶對(duì)目標(biāo)物品的興趣度:param p: 用戶興趣和隱類的關(guān)系:param q: 隱類和物品的關(guān)系:param userID: 目標(biāo)用戶:param itemID: 目標(biāo)物品:return: 預(yù)測(cè)興趣度'''p = np.mat(p.ix[userID].values)q = np.mat(q[itemID].values).Tr = (p * q).sum()r = sigmod(r)return rdef recommend(frame, userID, p, q, TopN=10):'''推薦TopN個(gè)物品給目標(biāo)用戶:param frame: 源數(shù)據(jù):param userID: 目標(biāo)用戶:param p: 用戶興趣和隱類的關(guān)系:param q: 隱類和物品的關(guān)系:param TopN: 推薦數(shù)量: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=0all=0df_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+=1all+=len(true_item)return hit/(all*1.0)def Precision(df_test,p,q):hit=0all=0df_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+=1all+=len(pre_item)return hit/(all*1.0)if __name__ == '__main__': start = time.clock() #導(dǎo)入數(shù)據(jù)df_sample = pd.read_csv("D:\\tmp\\ratings.csv",names=['userid','itemid','ratings','time'],header=0) #模型訓(xùn)練p, q = latenFactorModel(df_sample,5, 3, 0.02, 0.01 )#模型評(píng)估df_test=df_sample.sample(frac=0.2)#抽20%來(lái)測(cè)試print (Recall(df_test,p,q))#召回率print (Precision(df_test,p,q))#準(zhǔn)確率 print (Coverage(df_test,p,q))#覆蓋率end = time.clock() print('finish all in %s' % str(end - start))


實(shí)際推薦應(yīng)用中,應(yīng)結(jié)合特征工程開(kāi)展。

?

?

補(bǔ)充覆蓋率評(píng)價(jià)指標(biāo)的函數(shù):

?

def Coverage(df_test,p,q):#覆蓋率df_itemid=df_test['itemid']df_itemid=df_itemid.drop_duplicates()rec_items=set()#推薦的物品總數(shù)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)

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的【知识发现】隐语义模型LFM算法python实现(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。