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

首頁 > 編程 > Python > 正文

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

2020-02-15 22:52:47
字體:
來源:轉載
供稿:網友

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

矩陣分解推薦的思想就是基于此,將每個user和item的內在feature構成的矩陣分別表示為M1與M2,則內在feature的乘積得到M;因此我們可以利用已有數據(user對item的打分)通過隨機梯度下降的方法計算出現有user和item最可能的feature對應到的M1與M2(相當于得到每個user和每個item的內在屬性),這樣就可以得到通過feature之間的內積得到user沒有打過分的item的分數。

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

代碼如下:

# -*- 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) #參數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]#得到的數據里面還有其他同列名的column  df.columns = left_columns # 重新定義columns  return df  def readfile(filepath): #讀取文件,同時得到訓練集和測試集    pwd = os.getcwd()#返回當前工程的工作目錄  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] #將最后一列數據去掉  newIndexData = predData.drop_duplicates()  trainData = newIndexData.sample(axis=0,frac = 0.1) #90%的數據作為訓練集  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 #隨機梯度下降中加入,防止更新過度  user = pd.DataFrame(train.userId.drop_duplicates(),columns=['userId']).reset_index(drop=True) #把在原來dataFrame中的索引重新設置,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) #構造user和movie的特征向量集合  movieFeatures = np.random.rand(movieNum,features)  #假設每個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') #重新設置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中對應uId的feature       u_m = train[train['userId'] == uId] #找到在train中userId點評過的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:/學習/研究生/推薦系統/ml-latest-small/ratings.csv"  train,test = readfile(filepath)  userFeaturesFrame,movieFeaturesFrame = getmodel(train)  result = evaluate(userFeaturesFrame,movieFeaturesFrame,test)            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 历史| 高邮市| 芦溪县| 巴里| 蓝山县| 津南区| 浦县| 吉林市| 福鼎市| 裕民县| 江阴市| 泰兴市| 嘉黎县| 鹿泉市| 永宁县| 东安县| 台中县| 南澳县| 西丰县| 自贡市| 沭阳县| 寿阳县| 淮阳县| 渝中区| 措美县| 乐昌市| 南华县| 台州市| 奉贤区| 清流县| 怀安县| 宜川县| 大田县| 阳城县| 托克逊县| 中山市| 连城县| 平塘县| 连云港市| 张北县| 许昌市|