亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

python3實現基于用戶的協同過濾

2020-02-15 21:36:09
字體:
來源:轉載
供稿:網友

本文實例為大家分享了python3實現基于用戶協同過濾的具體代碼,供大家參考,具體內容如下

廢話不多說,直接看代碼。

#!/usr/bin/python3 # -*- coding: utf-8 -*- #20170916號協同過濾電影推薦基稿 #字典等格式數據處理及直接寫入文件   ##from numpy import * import time from math import sqrt ##from texttable import Texttable   class CF:   def __init__(self, movies, ratings, k=5, n=20):   self.movies = movies#[MovieID,Title,Genres]   (self.train_data,self.test_data) = (ratings[0], ratings[1])#[UserID::MovieID::Rating::Timestamp]   # 鄰居個數   self.k = k   # 推薦個數   self.n = n   # 用戶對電影的評分   # 數據格式{'UserID用戶ID':[(MovieID電影ID,Rating用戶對電影的評星)]}   self.userDict = {}   # 對某電影評分的用戶   # 數據格式:{'MovieID電影ID':[UserID,用戶ID]}   # {'1',[1,2,3..],...}   self.ItemUser = {}   # 鄰居的信息   self.neighbors = []   # 推薦列表   self.recommandList = []#包含dist和電影id   self.recommand = [] #訓練集合測試集的交集,且僅有電影id   #用戶評過電影信息   self.train_user = []   self.test_user = []   #給用戶的推薦列表,僅含movieid   self.train_rec =[]   self.test_rec = []   #test中的電影評分預測數據集合,   self.forecast = {}#前k個近鄰的評分集合   self.score = {}#最終加權平均后的評分集合{“電影id”:預測評分}   #召回率和準確率   self.pre = [0.0,0.0]   self.z = [0.0, 0.0]  '''''  userDict數據格式:  '3': [('3421', 0.8), ('1641', 0.4), ('648', 0.6), ('1394', 0.8), ('3534', 0.6), ('104', 0.8),  ('2735', 0.8), ('1210', 0.8), ('1431', 0.6), ('3868', 0.6), ('1079', 1.0), ('2997', 0.6),  ('1615', 1.0), ('1291', 0.8), ('1259', 1.0), ('653', 0.8), ('2167', 1.0), ('1580', 0.6),  ('3619', 0.4), ('260', 1.0), ('2858', 0.8), ('3114', 0.6), ('1049', 0.8), ('1261', 0.2),  ('552', 0.8), ('480', 0.8), ('1265', 0.4), ('1266', 1.0), ('733', 1.0), ('1196', 0.8),  ('590', 0.8), ('2355', 1.0), ('1197', 1.0), ('1198', 1.0), ('1378', 1.0), ('593', 0.6),  ('1379', 0.8), ('3552', 1.0), ('1304', 1.0), ('1270', 0.6), ('2470', 0.8), ('3168', 0.8),  ('2617', 0.4), ('1961', 0.8), ('3671', 1.0), ('2006', 0.8), ('2871', 0.8), ('2115', 0.8),  ('1968', 0.8), ('1136', 1.0), ('2081', 0.8)]}  ItemUser數據格式:  {'42': ['8'], '2746': ['10'], '2797': ['1'], '2987': ['5'], '1653': ['5', '8', '9'],  '194': ['5'], '3500': ['8', '10'], '3753': ['6', '7'], '1610': ['2', '5', '7'],  '1022': ['1', '10'], '1244': ['2'], '25': ['8', '9']  '''   # 將ratings轉換為userDict和ItemUser  def formatRate(self,train_or_test):   self.userDict = {}   self.ItemUser = {}   for i in train_or_test:#[UserID,MovieID,Rating,Timestamp]    # 評分最高為5 除以5 進行數據歸一化 ##   temp = (i[1], float(i[2]) / 5)    temp = (i[1], float(i[2])) ##   temp = (i[1], i[2])    # 計算userDict {'用戶id':[(電影id,評分),(2,5)...],'2':[...]...}一個觀眾對每一部電影的評分集合    if(i[0] in self.userDict):     self.userDict[i[0]].append(temp)    else:     self.userDict[i[0]] = [temp]    # 計算ItemUser {'電影id',[用戶id..],...}同一部電影的觀眾集合    if(i[1] in self.ItemUser):     self.ItemUser[i[1]].append(i[0])    else:     self.ItemUser[i[1]] = [i[0]]     # 格式化userDict數據  def formatuserDict(self, userId, p):#userID為待查詢目標,p為近鄰對象   user = {}   #user數據格式為:電影id:[userID的評分,近鄰用戶的評分]   for i in self.userDict[userId]:#i為userDict數據中的每個括號同81行    user[i[0]] = [i[1], 0]   for j in self.userDict[p]:    if(j[0] not in user):     user[j[0]] = [0, j[1]]#說明目標用戶和近鄰用戶沒有同時對一部電影評分    else:     user[j[0]][1] = j[1]#說明兩者對同一部電影都有評分   return user        # 計算余弦距離  def getCost(self, userId, p):   # 獲取用戶userId和p評分電影的并集   # {'電影ID':[userId的評分,p的評分]} 沒有評分為0   user = self.formatuserDict(userId, p)   x = 0.0   y = 0.0   z = 0.0   for k, v in user.items():#k是鍵,v是值    x += float(v[0]) * float(v[0])    y += float(v[1]) * float(v[1])    z += float(v[0]) * float(v[1])   if(z == 0.0):    return 0   return z / sqrt(x * y)  #計算皮爾遜相似度 ##  def getCost(self, userId, p): ##   # 獲取用戶userId和l評分電影的并集 ##   # {'電影ID':[userId的評分,l的評分]} 沒有評分為0 ##   user = self.formatuserDict(userId, p) ##   sumxsq = 0.0 ##   sumysq = 0.0 ##   sumxy = 0.0 ##   sumx = 0.0 ##   sumy = 0.0 ##   n = len(user) ##   for k, v in user.items(): ##    sumx +=float(v[0]) ##    sumy +=float(v[1]) ##    sumxsq += float(v[0]) * float(v[0]) ##    sumysq += float(v[1]) * float(v[1]) ##    sumxy += float(v[0]) * float(v[1]) ##   up = sumxy -sumx*sumy/n ##   down = sqrt((sumxsq - pow(sumxsq,2)/n)*(sumysq - pow(sumysq,2)/n)) ##   if(down == 0.0): ##    return 0 ##   return up/down  # 找到某用戶的相鄰用戶  def getNearestNeighbor(self, userId):   neighbors = []   self.neighbors = []   # 獲取userId評分的電影都有那些用戶也評過分   for i in self.userDict[userId]:#i為userDict數據中的每個括號同95行#user數據格式為:電影id:[userID的評分,近鄰用戶的評分]    for j in self.ItemUser[i[0]]:#i[0]為電影編號,j為看同一部電影的每位用戶     if(j != userId and j not in neighbors):      neighbors.append(j)   # 計算這些用戶與userId的相似度并排序   for i in neighbors:#i為用戶id    dist = self.getCost(userId, i)    self.neighbors.append([dist, i])   # 排序默認是升序,reverse=True表示降序   self.neighbors.sort(reverse=True)   self.neighbors = self.neighbors[:self.k]#切片操作,取前k個 ##  print('neighbors',len(neighbors))    # 獲取推薦列表  def getrecommandList(self, userId):   self.recommandList = []   # 建立推薦字典   recommandDict = {}   for neighbor in self.neighbors:#這里的neighbor數據格式為[[dist,用戶id],[],....]    movies = self.userDict[neighbor[1]]#movies數據格式為[(電影id,評分),(),。。。。]    for movie in movies:     if(movie[0] in recommandDict):      recommandDict[movie[0]] += neighbor[0]####????     else:      recommandDict[movie[0]] = neighbor[0]    # 建立推薦列表   for key in recommandDict:#recommandDict數據格式{電影id:累計dist,。。。}    self.recommandList.append([recommandDict[key], key])#recommandList數據格式【【累計dist,電影id】,【】,。。。?!?  self.recommandList.sort(reverse=True) ##  print(len(self.recommandList))   self.recommandList = self.recommandList[:self.n] ##  print(len(self.recommandList))  # 推薦的準確率  def getPrecision(self, userId): ##  print("開始?。?!") #先運算test_data,這樣最終self.neighbors等保留的是后來計算train_data后的數據(不交換位置的話就得在gR函數中增加參數保留各自的neighbor)   (self.test_user,self.test_rec) = self.getRecommand(self.test_data,userId)#測試集的用戶userId所評價的電影和給該用戶推薦的電影列表   (self.train_user,self.train_rec) = self.getRecommand(self.train_data,userId)#訓練集的用戶userId所評價的所有電影集合(self.train_user)和給該用戶推薦的電影列表(self.train_rec) #西安電大的張海朋:基于協同過濾的電影推薦系統的構建(2015)中的準確率召回率計算   for i in self.test_rec:    if i in self.train_rec:     self.recommand.append(i)   self.pre[0] = len(self.recommand)/len(self.train_rec)   self.z[0] = len(self.recommand)/len(self.test_rec)   #北京交大黃宇:基于協同過濾的推薦系統設計與實現(2015)中的準、召計算   self.recommand = []#這里沒有歸零的話,下面計算初始recommand不為空   for i in self.train_rec:    if i in self.test_user:     self.recommand.append(i)   self.pre[1] = len(self.recommand)/len(self.train_rec)   self.z[1] = len(self.recommand)/len(self.test_user) ##  print(self.train_rec,self.test_rec,"20",len(self.train_rec),len(self.train_rec))   #對同一用戶分別通過訓練集和測試集處理  def getRecommand(self,train_or_test,userId):   self.formatRate(train_or_test)   self.getNearestNeighbor(userId)   self.getrecommandList(userId)   user = [i[0] for i in self.userDict[userId]]#用戶userId評分的所有電影集合   recommand = [i[1] for i in self.recommandList]#推薦列表僅有電影id的集合,區別于recommandList(還含有dist) ##  print("userid該用戶已通過訓練集測試集處理")   return (user,recommand)  #對test的電影進行評分預測  def foreCast(self):   self.forecast = {}#?????前面變量統一定義初始化后,函數內部是否需要該初始化????   same_movie_id = []   neighbors_id = [i[1] for i in self.neighbors] #近鄰用戶數據僅含用戶id的集合         for i in self.test_user:#i為電影id,即在test里的i有被推薦到    if i in self.train_rec:     same_movie_id.append(i)     for j in self.ItemUser[i]:#j為用戶id,即尋找近鄰用戶的評分和相似度      if j in neighbors_id:       user = [i[0] for i in self.userDict[j]]#self.userDict[userId]數據格式:數據格式為[(電影id,評分),(),。。。。];這里的userid應為近鄰用戶p       a = self.neighbors[neighbors_id.index(j)]#找到該近鄰用戶的數據【dist,用戶id】       b = self.userDict[j][user.index(i)]#找到該近鄰用戶的數據【電影id,用戶id】       c = [a[0], b[1], a[1]]       if (i in self.forecast):        self.forecast[i].append(c)       else:        self.forecast[i] = [c]#數據格式:字典{“電影id”:【dist,評分,用戶id】【】}{'589': [[0.22655856915174025, 0.6, '419'], [0.36264561173211646, 1.0, '1349']。。。} ##  print(same_movie_id)   #每個近鄰用戶的評分加權平均計算得預測評分   self.score = {}   if same_movie_id :#在test里的電影是否有在推薦列表里,如果為空不做判斷,下面的處理會報錯    for movieid in same_movie_id:     total_d = 0     total_down = 0     for d in self.forecast[movieid]:#此時的d已經是最里層的列表了【】;self.forecast[movieid]的數據格式[[]]      total_d += d[0]*d[1]      total_down += d[0]     self.score[movieid] = [round(total_d/total_down,3)]#加權平均后取3位小數的精度    #在test里但是推薦沒有的電影id,這里先按零計算    for i in self.test_user:     if i not in movieid:      self.score[i] = [0]   else:    for i in self.test_user:     self.score[i] = [0] ##  return self.score  #計算平均絕對誤差MAE  def cal_Mae(self,userId):   self.formatRate(self.test_data) ##  print(self.userDict)   for item in self.userDict[userId]:    if item[0] in self.score:     self.score[item[0]].append(item[1])#self.score數據格式[[預測分,實際分]] ##  #過渡代碼 ##  for i in self.score: ##   pass   return self.score     # 基于用戶的推薦  # 根據對電影的評分計算用戶之間的相似度 ## def recommendByUser(self, userId): ##  print("親,請稍等片刻,系統正在快馬加鞭為你運作中")   #人機交互輔助解讀, ##  self.getPrecision(self,userId)   # 獲取數據 def readFile(filename):  files = open(filename, "r", encoding = "utf-8")  data = []  for line in files.readlines():   item = line.strip().split("::")   data.append(item)  return data  files.close() def load_dict_from_file(filepath):  _dict = {}  try:   with open(filepath, 'r',encoding = "utf -8") as dict_file:    for line in dict_file.readlines():     (key, value) = line.strip().split(':')     _dict[key] = value  except IOError as ioerr:   print ("文件 %s 不存在" % (filepath))  return _dict def save_dict_to_file(_dict, filepath):  try:   with open(filepath, 'w',encoding = "utf - 8") as dict_file:    for (key,value) in _dict.items():     dict_file.write('%s:%s/n' % (key, value))   except IOError as ioerr:   print ("文件 %s 無法創建" % (filepath)) def writeFile(data,filename):  with open(filename, 'w', encoding = "utf-8")as f:   f.write(data)   # -------------------------開始-------------------------------  def start3():  start1 = time.clock()  movies = readFile("D:/d/movies.dat")  ratings = [readFile("D:/d/201709train.txt"),readFile("D:/d/201709test.txt")]  demo = CF(movies, ratings, k=20)  userId = '1000'  demo.getPrecision(userId) ## print(demo.foreCast())  demo.foreCast()  print(demo.cal_Mae(userId)) ## demo.recommendByUser(ID)  #上一句只能實現固定用戶查詢,這句可以實現“想查哪個查哪個”,后期可以加個循環,挨個查,查到你不想查  print("處理的數據為%d條" % (len(ratings[0])+len(ratings[1]))) ## print("____---",len(ratings[0]),len(ratings[1])) ## print("準確率: %.2f %%" % (demo.pre * 100)) ## print("召回率: %.2f %%" % (demo.z * 100))  print(demo.pre)  print(demo.z)  end1 = time.clock()  print("耗費時間: %f s" % (end1 - start1)) def start1():  start1 = time.clock()  movies = readFile("D:/d/movies.dat")  ratings = [readFile("D:/d/201709train.txt"),readFile("D:/d/201709test.txt")]  demo = CF(movies, ratings, k = 20)  demo.formatRate(ratings[0])  writeFile(str(demo.userDict),"D:/d/dd/userDict.txt")  writeFile(str(demo.ItemUser), "D:/d/dd/ItemUser.txt") ## save_dict_to_file(demo.userDict,"D:/d/dd/userDict.txt") ## save_dict_to_file(demo.ItemUser,"D:/d/dd/ItemUser.txt")  print("處理結束") ## with open("D:/d/dd/userDict.txt",'r',encoding = 'utf-8') as f: ##  diction = f.read() ##  i = 0 ##  for j in eval(diction): ##   print(j) ##   i += 1 ##   if i == 4: ##    break def start2():  start1 = time.clock()  movies = readFile("D:/d/movies.dat")  ratings = [readFile("D:/d/201709train.txt"),readFile("D:/d/201709test.txt")]  demo = CF(movies, ratings, k = 20)  demo.formatRate_toMovie(ratings[0])  writeFile(str(demo.movieDict),"D:/d/dd/movieDict.txt") ## writeFile(str(demo.userDict),"D:/d/dd/userDict.txt") ## writeFile(str(demo.ItemUser), "D:/d/dd/ItemUser.txt") ## save_dict_to_file(demo.userDict,"D:/d/dd/userDict.txt") ## save_dict_to_file(demo.ItemUser,"D:/d/dd/ItemUser.txt")  print("處理結束")   if __name__ == '__main__':  start1()             
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久18| xxav国产精品美女主播| 欧美影院在线播放| 日韩激情第一页| 亚洲人成电影网站色xx| 7m第一福利500精品视频| 欧美日韩亚洲精品一区二区三区| 国产美女精品免费电影| 国产精品第3页| 国产精品揄拍一区二区| 欧洲日本亚洲国产区| 国产日韩欧美在线| 欧美激情视频在线免费观看 欧美视频免费一| 日韩黄色av网站| 欧美亚洲激情在线| 亚洲人成电影在线播放| 精品国产31久久久久久| 亚洲成年人影院在线| 欧美激情欧美激情| 欧美极品美女视频网站在线观看免费| 久久99精品久久久久久青青91| 在线播放日韩精品| 久久中国妇女中文字幕| 久久久影视精品| 欧美精品一区在线播放| 欧美日本精品在线| 两个人的视频www国产精品| 日韩有码在线观看| 91福利视频网| 8090理伦午夜在线电影| 日韩h在线观看| 欧美又大粗又爽又黄大片视频| 成人欧美一区二区三区黑人孕妇| 欧美亚洲视频在线看网址| 日韩高清av一区二区三区| 欧美精品xxx| 日本精品性网站在线观看| 国产精品mp4| 97国产精品视频人人做人人爱| 日本精品中文字幕| 丝袜美腿精品国产二区| 国产精品国产三级国产aⅴ浪潮| 欧美大片在线免费观看| 久久影视电视剧免费网站| 国产一区二区视频在线观看| 国产精品久久久久影院日本| 欧美资源在线观看| 欧美激情性做爰免费视频| 国产精品久久97| 奇米一区二区三区四区久久| 日本久久中文字幕| 日韩中文字幕久久| 久久久黄色av| 国产综合色香蕉精品| 777国产偷窥盗摄精品视频| 欧美黑人性视频| 日韩一区二区三区在线播放| 欧美激情乱人伦| 久久精品中文字幕一区| 欧美精品在线网站| 欧美成人在线免费| 国产视频精品久久久| 97色在线视频| 欧美富婆性猛交| 国产区精品视频| 成人性生交大片免费看视频直播| 久久免费国产精品1| 中文字幕日韩欧美| 91精品视频一区| 69国产精品成人在线播放| 91av网站在线播放| 在线视频免费一区二区| 久久免费成人精品视频| 日韩黄色在线免费观看| 国产精品久久久久一区二区| 日韩中文字幕在线看| 欧美色播在线播放| 91国自产精品中文字幕亚洲| 成人免费福利在线| 国产精品久久久久久久久久新婚| 最近2019中文免费高清视频观看www99| 日韩欧美视频一区二区三区| 亚洲毛片在线观看.| 91欧美激情另类亚洲| 亚洲视频在线免费观看| 亚洲国产99精品国自产| 国产精品扒开腿爽爽爽视频| 中文字幕精品一区二区精品| 亚洲a级在线观看| 色爱精品视频一区| 亚洲精品欧美一区二区三区| 亚洲成人a级网| 日韩精品视频在线| 中文字幕成人精品久久不卡| 亚洲午夜av电影| 欧美色视频日本高清在线观看| 国产成人一区二区三区| 亚洲偷熟乱区亚洲香蕉av| 日本一区二区不卡| 成人黄色片在线| 亚洲人成电影网| 精品国产福利视频| 91影视免费在线观看| 国产视频久久久| 国外日韩电影在线观看| 亚洲成人黄色网址| 国产精品电影网| 欧美日韩国产一区二区三区| 久久久久久久久久久久av| 国产精品国产三级国产aⅴ浪潮| 日本欧美一二三区| 国产精品一区二区三区免费视频| 国产69精品久久久久9999| 久久精品亚洲精品| 中文字幕在线看视频国产欧美在线看完整| 久久免费国产精品1| 欧美日韩一区二区三区在线免费观看| 欧美贵妇videos办公室| 日韩精品视频观看| 久久久久久免费精品| 精品高清美女精品国产区| 日韩成人中文字幕在线观看| 欧美xxxx14xxxxx性爽| 国语自产在线不卡| 久久久久久噜噜噜久久久精品| 欧美香蕉大胸在线视频观看| 中文字幕亚洲综合| 国产精品av在线播放| 欧美一区二粉嫩精品国产一线天| 亚洲少妇激情视频| 成人网在线免费看| 91精品在线一区| 精品国产一区二区三区久久狼5月| 欧美精品手机在线| 国产精品高潮呻吟久久av无限| 78色国产精品| 日韩电影第一页| 成人欧美一区二区三区黑人孕妇| 在线播放精品一区二区三区| 一区三区二区视频| 日韩在线观看免费网站| 国产精品青青在线观看爽香蕉| 亚洲二区中文字幕| 日韩电影中文字幕av| 日本精品久久久| 久热精品视频在线免费观看| 高清一区二区三区日本久| 国模视频一区二区三区| 国产在线一区二区三区| 成人在线播放av| 美女久久久久久久久久久| 日韩中文字幕在线视频播放| 超在线视频97| 久久久久久久久久久人体| 国模叶桐国产精品一区| 亚洲第一在线视频| 成人免费网站在线| 欧美一区二区三区图| 2019av中文字幕| 日产精品久久久一区二区福利| 国产精品91久久久久久| 久久精品一区中文字幕| 欧美风情在线观看| 日韩视频免费在线观看|