国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

基于隨機(jī)梯度下降的矩陣分解推薦算法(python)

2020-01-04 14:36:26
字體:
供稿:網(wǎng)友

SVD是矩陣分解常用的方法,其原理為:矩陣M可以寫成矩陣A、B與C相乘得到,而B可以與A或者C合并,就變成了兩個元素M1與M2的矩陣相乘可以得到M。

矩陣分解推薦的思想就是基于此,將每個user和item的內(nèi)在feature構(gòu)成的矩陣分別表示為M1與M2,則內(nèi)在feature的乘積得到M;因此我們可以利用已有數(shù)據(jù)(user對item的打分)通過隨機(jī)python/322771.html">梯度下降的方法計(jì)算出現(xiàn)有user和item最可能的feature對應(yīng)到的M1與M2(相當(dāng)于得到每個user和每個item的內(nèi)在屬性),這樣就可以得到通過feature之間的內(nèi)積得到user沒有打過分的item的分?jǐn)?shù)。

本文所采用的數(shù)據(jù)是movielens中的數(shù)據(jù),且自行切割成了train和test,但是由于數(shù)據(jù)量較大,沒有用到全部數(shù)據(jù)。

代碼如下:

# -*- coding: utf-8 -*-"""Created on Mon Oct 9 19:33:00 2017@author: wjw"""import pandas as pdimport numpy as npimport os def difference(left,right,on): #求兩個dataframe的差集  df = pd.merge(left,right,how='left',on=on) #參數(shù)on指的是用于連接的列索引名稱  left_columns = left.columns  col_y = df.columns[-1] # 得到最后一列  df = df[df[col_y].isnull()]#得到boolean的list  df = df.iloc[:,0:left_columns.size]#得到的數(shù)據(jù)里面還有其他同列名的column  df.columns = left_columns # 重新定義columns  return df  def readfile(filepath): #讀取文件,同時得到訓(xùn)練集和測試集    pwd = os.getcwd()#返回當(dāng)前工程的工作目錄  os.chdir(os.path.dirname(filepath))  #os.path.dirname()獲得filepath文件的目錄;chdir()切換到filepath目錄下  initialData = pd.read_csv(os.path.basename(filepath))  #basename()獲取指定目錄的相對路徑  os.chdir(pwd)#回到先前工作目錄下  predData = initialData.iloc[:,0:3] #將最后一列數(shù)據(jù)去掉  newIndexData = predData.drop_duplicates()  trainData = newIndexData.sample(axis=0,frac = 0.1) #90%的數(shù)據(jù)作為訓(xùn)練集  testData = difference(newIndexData,trainData,['userId','movieId']).sample(axis=0,frac=0.1)  return trainData,testData def getmodel(train):  slowRate = 0.99  preRmse = 10000000.0  max_iter = 100  features = 3  lamda = 0.2  gama = 0.01 #隨機(jī)梯度下降中加入,防止更新過度  user = pd.DataFrame(train.userId.drop_duplicates(),columns=['userId']).reset_index(drop=True) #把在原來dataFrame中的索引重新設(shè)置,drop=True并拋棄   movie = pd.DataFrame(train.movieId.drop_duplicates(),columns=['movieId']).reset_index(drop=True)  userNum = user.count().loc['userId'] #671  movieNum = movie.count().loc['movieId']   userFeatures = np.random.rand(userNum,features) #構(gòu)造user和movie的特征向量集合  movieFeatures = np.random.rand(movieNum,features)  #假設(shè)每個user和每個movie有3個feature  userFeaturesFrame =user.join(pd.DataFrame(userFeatures,columns = ['f1','f2','f3']))  movieFeaturesFrame =movie.join(pd.DataFrame(movieFeatures,columns= ['f1','f2','f3']))  userFeaturesFrame = userFeaturesFrame.set_index('userId')  movieFeaturesFrame = movieFeaturesFrame.set_index('movieId') #重新設(shè)置index   for i in range(max_iter):     rmse = 0    n = 0    for index,row in user.iterrows():      uId = row.userId      userFeature = userFeaturesFrame.loc[uId] #得到userFeatureFrame中對應(yīng)uId的feature       u_m = train[train['userId'] == uId] #找到在train中userId點(diǎn)評過的movieId的data      for index,row in u_m.iterrows():         u_mId = int(row.movieId)        realRating = row.rating        movieFeature = movieFeaturesFrame.loc[u_mId]          eui = realRating-np.dot(userFeature,movieFeature)        rmse += pow(eui,2)        n += 1        userFeaturesFrame.loc[uId] += gama * (eui*movieFeature-lamda*userFeature)         movieFeaturesFrame.loc[u_mId] += gama*(eui*userFeature-lamda*movieFeature)    nowRmse = np.sqrt(rmse*1.0/n)    print('step:%f,rmse:%f'%((i+1),nowRmse))    if nowRmse<preRmse:      preRmse = nowRmse    elif nowRmse<0.5:      break    elif nowRmse-preRmse<=0.001:      break    gama*=slowRate  return userFeaturesFrame,movieFeaturesFrame def evaluate(userFeaturesFrame,movieFeaturesFrame,test):  test['predictRating']='NAN' # 新增一列   for index,row in test.iterrows():         print(index)    userId = row.userId    movieId = row.movieId    if userId not in userFeaturesFrame.index or movieId not in movieFeaturesFrame.index:      continue    userFeature = userFeaturesFrame.loc[userId]    movieFeature = movieFeaturesFrame.loc[movieId]    test.loc[index,'predictRating'] = np.dot(userFeature,movieFeature) #不定位到不能修改值      return test   if __name__ == "__main__":  filepath = r"E:/學(xué)習(xí)/研究生/推薦系統(tǒng)/ml-latest-small/ratings.csv"  train,test = readfile(filepath)  userFeaturesFrame,movieFeaturesFrame = getmodel(train)  result = evaluate(userFeaturesFrame,movieFeaturesFrame,test)

在test中得到的結(jié)果為:

梯度下降,矩陣分解,python

NAN則是訓(xùn)練集中沒有的數(shù)據(jù)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到python教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 伊春市| 子长县| 乐清市| 遵化市| 柘城县| 兴安盟| 府谷县| 日喀则市| 迁安市| 隆化县| 临泉县| 宁陕县| 方山县| 襄垣县| 永康市| 鄂托克旗| 札达县| 中山市| 从江县| 纳雍县| 深州市| 湘潭县| 黑河市| 石柱| 蒙自县| 宜兴市| 尤溪县| 婺源县| 绥棱县| 甘孜| 绥宁县| 宝鸡市| 上杭县| 武义县| 云林县| 寿宁县| 东明县| 闽侯县| 南木林县| 同德县| 鄂伦春自治旗|