从0开始,使用豆瓣数据集做一个基于FM和逻辑回归的电影推荐系统
推薦算法在互聯網行業的應用非常廣泛,今日頭條、美團點評等都有個性化推薦,推薦算法抽象來講,是一種對于內容滿意度的擬合函數,涉及到用戶特征和內容特征,作為模型訓練所需維度的兩大來源,而點擊率,頁面停留時間,評論或下單等都可以作為一個量化的 Y 值,這樣就可以進行特征工程,構建出一個數據集,然后選擇一個合適的監督學習算法進行訓練,得到模型后,為客戶推薦偏好的內容,如頭條的話,就是咨詢和文章,美團的就是生活服務內容。
可選擇的模型很多,如協同過濾,邏輯斯蒂回歸,基于DNN的模型,FM等。我們使用的方式是,基于內容相似度計算進行召回,之后通過FM模型和邏輯斯蒂回歸模型進行精排推薦,下面就分別說一下,我們做這個電影推薦系統過程中,從數據準備,特征工程,到模型訓練和應用的整個過程。
我們實現的這個電影推薦系統,爬取的數據實際上維度是相對少的,特別是用戶這一側的維度,正常推薦系統涉及的維度,諸如頁面停留時間,點擊頻次,收藏等這些維度都是沒有的,以及用戶本身的維度也相對要少,沒有地址、年齡、性別等這些基本的維度,這樣我們爬取的數據只有打分和評論這些信息,所以之后我們又從這些信息里再拿出一些統計維度來用。我們爬取的電影數據(除電影詳情和圖片信息外)是如下這樣的形式:
這里的數據是有冗余的,又通過如下的代碼,對數據進行按維度合并,去除冗余數據條目:
# 處理主函數,負責將多個冗余數據合并為一條電影數據,將地區,導演,主演,類型,特色等維度數據合并 def mainfunc():try:unable_list = []with connection.cursor() as cursor:sql='select id,name from movie'cout=cursor.execute(sql)print("數量: "+str(cout))for row in cursor.fetchall():#print(row[1])movieinfo = df[df['電影名'] == row[1]]if movieinfo.shape[0] == 0:disable_movie(row[0])print('disable movie ' + str(row[1]))else:g = lambda x:movieinfo[x].iloc[0]types = movieinfo['類型'].tolist()types = reduce(lambda x,y:x+'|'+y,list(set(types)))traits = movieinfo['特色'].tolist()traits = reduce(lambda x,y:x+'|'+y,list(set(traits)))update_one_movie_info(type_=types, actors=g('主演'), region=g('地區'), director=g('導演'), trait=traits, rat=g('評分'), id_=row[0])connection.commit()finally:connection.close()之后開始準備用戶數據,我們從用戶打分的數據中,統計出每一個用戶的打分的最大值,最小值,中位數值和平均值等,從而作為用戶的一個附加屬性,存儲于userproex表中:
'insert into userproex(userid, rmax, rmin, ravg, rcount, rsum, rmedian) values(\'%s\', %s, %s, %s, %s, %s, %s)' % (userid, rmax, rmin, ravg, rcount, rsum, rmedium)'update userproex set rmax=%s, rmin=%s, ravg=%s, rmedian=%s, rcount=%s, rsum=%s where userid=\'%s\'' % (rmax, rmin, ravg, rmedium, rcount, rsum, userid)以上兩個SQL是最終插入表的時候用到的,代表準備用戶數據的最終步驟,其余細節可以參考文末的github倉庫,不在此贅述,數據處理還用到了一些SQL,以及其他處理細節。
系統上線運行時,第一次是全量的數據處理,之后會是增量處理過程,這個后面還會提到。
我們目前把用戶數據和電影的數據的原始數據算是準備好了,下一步開始特征工程。做特征工程的思路是,對type, actors, director, trait四個類型數據分別構建一個頻度統計字典,用于之后的one-hot編碼,代碼如下:
def get_dim_dict(df, dim_name):type_list = list(map(lambda x:x.split('|') ,df[dim_name]))type_list = [x for l in type_list for x in l]def reduce_func(x, y):for i in x:if i[0] == y[0][0]:x.remove(i)x.append(((i[0],i[1] + 1)))return xx.append(y[0])return xl = filter(lambda x:x != None, map(lambda x:[(x, 1)], type_list))type_zip = reduce(reduce_func, list(l))type_dict = {}for i in type_zip:type_dict[i[0]] = i[1]return type_dict涉及到的冗余數據也要刪除
df_ = df.drop(['ADD_TIME', 'enable', 'rat', 'id', 'name'], axis=1)將電影數據轉換為字典列表,由于演員和導演均過萬維,實際計算時過于稀疏,當演員或導演只出現一次時,標記為冷門演員或導演
movie_dict_list = [] for i in df_.index:movie_dict = {}#typefor s_type in df_.iloc[i]['type'].split('|'):movie_dict[s_type] = 1#actorsfor s_actor in df_.iloc[i]['actors'].split('|'):if actors_dict[s_actor] < 2:movie_dict['other_actor'] = 1else:movie_dict[s_actor] = 1#regiosmovie_dict[df_.iloc[i]['region']] = 1#directorfor s_director in df_.iloc[i]['director'].split('|'):if director_dict[s_director] < 2:movie_dict['other_director'] = 1else:movie_dict[s_director] = 1#traitfor s_trait in df_.iloc[i]['trait'].split('|'):movie_dict[s_trait] = 1movie_dict_list.append(movie_dict)使用DictVectorizer進行向量化,做One-hot編碼
v = DictVectorizer() X = v.fit_transform(movie_dict_list)這樣的數據,下面做余弦相似度已經可以了,這是特征工程的基本的一個處理,模型所使用的數據,需要將電影,評分,用戶做一個數據拼接,構建訓練樣本,并保存CSV,注意這個CSV不用每次全量構建,而是除第一次外都是增量構建,通過mqlog中類型為'c'的消息,增量構建以comment(評分)為主的訓練樣本,拼接之后的形式如下:
USERID cf2349f9c01f9a5cd4050aebd30ab74f movieid 10533913 type 劇情|奇幻|冒險|喜劇 actors 艾米·波勒|菲利絲·史密斯|理查德·坎德|比爾·哈德爾|劉易斯·布萊克 region 美國 director 彼特·道格特|羅納爾多·德爾·卡門 trait 感人|經典|勵志 rat 8.7 rmax 5 rmin 2 ravg 3.85714 rcount 7 rmedian 4 TIME_DIS 15這個數據的actors等字段和上面的處理是一樣的,為了之后libfm的使用,在這里需要轉換為libsvm的數據格式
dump_svmlight_file(train_X_scaling, train_y_, train_file)有很多細節不在這里描述,這樣大概的特征工程工作就做好了,之后使用相似度計算,FM,LR進行推薦模型的訓練。 具體訓練的過程不在這里進行闡述了。模型使用上遵循先召回,后精排的策略,先通過余弦相似度計算一個相似度矩陣,然后根據這個矩陣,為用戶推薦相似的M個電影,在通過訓練好的FM,LR模型,對這個M個電影做偏好預估,FM會預估一個用戶打分,LR會預估一個點擊概率,綜合結果推送給用戶作為推薦電影。
https://github.com/GavinHacker/recsys_core
這個地址上面有詳細的上線的項目截圖和說明,大家有興趣可以看一下,這里介紹了系統方面的結構,即,如何把推薦系統簡單的應用到一個網站中。
做了這個電影推薦系統后,感覺算是對自己這么長時間學習機器學習知識做一個綜合的實踐,有不少的感悟,現在有很多學習機器學習的同學,建議在大家刷論文的同時,也注重在項目中實踐,計算機科學,雖然叫做科學,實際卻是一門實踐性學科,一些AI頂級大牛,他們并不是數學家,也不是理論家,大多是從理論和實踐結合這條路成就的,和金庸小說中的武林絕技是一個道理。說到這,大家都知道,最近朋友圈被《94射雕英雄傳》AI換臉楊冪刷屏了,看來AI視頻換臉技術發展已經相當快,仔細想想,這已經是AI進入藝術創作領域的一個表象,筆者認為AI之后的發展一定是從互聯網行業擴展出去,變成IT產業當中的一個重要的技術支柱。
轉載于:https://blog.51cto.com/14318032/2389980
總結
以上是生活随笔為你收集整理的从0开始,使用豆瓣数据集做一个基于FM和逻辑回归的电影推荐系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西威变频器avo下载调试资料_西门子变频
- 下一篇: dos从优盘启动计算机,制作U盘dos启