網際網路中,對一個内容實體的模組化,如新聞,商品,通常有兩個方向:1,content-based,如該文章屬于哪個類别、文章标題、關鍵字、作者、新聞字數等等資訊,這些屬于從内容上描述文章資訊;2,另一塊是action-based,即從使用者與内容之間的各種不同行為來模組化使用者的關系。今天我們就來重點關注下基于使用者行為的内容表示的一些有意思的東西。
協同過濾相信很多做推薦的人經常接觸的一個算法,是一種經典的集體智慧的算法:在大量的人群行為資料中收集資訊,得到大部分人群的統計結論來表示人群中某種趨勢,或者我們稱為共性的部分。
為幫助了解,這裡簡單舉幾個栗子:比如我等屌絲程式猿,大部分會是下面這種情況:

除了程式猿的裝扮,程式猿的timeline很多時候也有下面這個特點:
特點人群,會更大幾率對他相關或者有興趣的内容産生行為,同理,轉換下使用者和内容的彼此身份,如果某個内容,被相似的人群産生行為是否能夠書名這些内容有一些實體會引起這一類人群的興趣,這就是action-based的假設前提,action-based和content-based屬于一個硬币的兩面,應該綜合考慮才能算是比較合理的某個内容實體的表征方式。
很顯然一些公共的資訊如一個出生湖北武漢,年紀29歲的未婚女演員并不能表征她就是劉亦菲,但是如果加上她的action資訊,她參演過功夫之王、銅雀台、四大名鋪等等那就八九不離十了。
是的,content-based的資料就是那麼重要,而協同過濾就是使用的比較多的方法。
一句話描述基于使用者的協同過濾,就是找到和目标使用者最相思的使用者,然後把該使用者産生過的物品,收集為候選清單,濾除掉已産生行為物品,并考慮使用者相似度為權重,進行權重排序,大體如下:
對使用者A進行推薦,因為與使用者行為相似度較大1,1,0,0與1,1,0,1,其相似度為sim(A,D),B,C使用者0,0,1,0,其相似度為sim(B,c),其值為0,是以最終對使用者A的推薦為商品D。
一句話描述基于Item的協同過濾就是計算Item的相似度,然後推薦使用者已購買的商品相似度比較大的物品。
很明顯商品D與商品A的和商品B的相似度都比較高,濾除已産生行為商品,對使用者A推商品D。
基于模型的協同過濾的方法,大體是用模型來替代比較粗糙的相似度計算法方式,這裡描述下比較經典的Matrix Factorization方法, 前面基于使用者和Item的方法在實際場景中會出現資料稀疏、計算複雜的問題,Matrix Factorization是一個比較好的方法,采用了矩陣分解的思路,将原始的使用者對Item的行為矩陣轉換為兩個dense矩陣用來表示使用者、Item的隐向量表示,然後在隐向量空間來度量使用者或者Item的相似度。
等号左邊的矩陣記錄不同使用者對不同商品的行為分布,通常在實際系統中,矩陣很大,而且通常十分稀疏,Matrix Factorization方法就是将這個矩陣分解為兩個比較小的矩陣,分别為使用者和Item的隐向量矩陣,然後利用這些隐向量矩陣計算使用者對Item的偏好得分,或者計算Item與Item或者使用者與用于之間的相似性,在不同場景下來進行各種需求的計算。
前面提到了使用協同過濾來模組化,得到action_based的方式,那麼是否有其他的方法呢? 回歸到資料來源,使用者對各種不同的行為如果組成一個有一個的序列,如果我能模組化序列内,元素之間的相似度,是不是就能很好的表征這些元素。好吧,大家可能發現了,這tm不就是Word2Vec嗎?每個序列不就是Word2Vec的語料語句嗎?是的,就是這樣, 其實說了前面許多,什麼協同過濾,Matrix Factorization,就是想引出這個,使用Word2Vec來模組化Action資料,下面我将較長的描述,我是怎麼在實際資料中做這些嘗試的。
Word2Vec的原理,有很多文章都講過了,這裡就不較長的描述了,想進一步了解的可以去Google一下, 這裡一句話解釋下:利用cbow或skip-gram收集視窗上下文資訊,來模組化詞與詞之間的共現關系。
用于閱讀資訊相關内容,通常在一個有效時間内,如一個session,所有文章會形成一個文章序列,通常文章與Tag詞的映射,(何為Tag?如黃忠垃圾?
這盤《王者榮耀》竟打了195分鐘,手機充三次電!這篇文章可能就會提取到王者榮耀這個Tag詞),形成Tag詞的序列,收集到有效使用者的所有行為,即可拿到所Tag詞的序列,這個序列中包含了使用者在閱讀比如Tag詞為王者榮耀後,更可能去閱讀王者榮耀英雄的資料如李白、諸葛亮的文章内容,也就是說在一個序列内,其共現機率應該比較高,那麼其向量化後的相似度也應該更大,這個是content-based可能需要話很大力氣才能模組化的。Ok,話不多說,我們用實際資料實驗一下,說明一下,以下所有資料均來自于team内部,無法共享,老鐵們不要私信來求資料啦,給你們我就會被開除的。
一個Session資料的收集理論上應該包括Tag詞序列,還有先後關系,才能比較合理的模組化一個可用的Tag2Vec模型,但是,資料收集難度問題。
我們這裡使用的是使用者每天在Tag詞上的行為序列,也沒考慮Tag詞的先後,是以這裡其實有一個風險,可能達不到我們預先想要的類似Word2Vec的結果,因為Word2Vec理論上是有一個window size限制,然後視窗了上下文來和中間詞做一個推斷,其實質是一個分類問題(正樣本為中間詞,負樣本為視窗外詞), 是以其實這裡如果沒有時間先後,還有視窗太大為天,本身在模型上是有風險的,但是,又稍微一想,其實語義的依賴關系本身就也有可能不在windows size内,随機性的順序,丢失的資訊應該不多,考慮了很多,和小夥伴也讨論,感覺問題不大,直接先上看看,最後的資料如下:
需要說明的是這裡的資料做過基本的去髒處理,包括設定門檻值,排除行為過少的使用者,大概能拿到500w+的資料。
模型訓練
Tag2Vec on Gensim
在Gensim上實作Word2Vec很容易,隻需要幾行就可以完成:
Tag2Vec on TensorFlow
現在在TensorFlow實作的WordVec,效果不是很好,這裡先占個坑,後面等搞好了再來填。
Tag2Vec結果
這裡我們對Tag2Vec做一些展示:
以下是一些例子, 感覺還是蠻有意思的:
如王者榮耀,相似度最高的是天美工作室, 然後就是很多相關的英雄以及一些主播資訊,還有一些有意思的如宋喆、車曉、張靜初、鄭則仕,這類看起來相關性不大的實體,應該是因為看王者榮耀的小夥伴們更偏向于娛樂化的新聞,是以更優可能露出車曉、張靜初、宋喆這些娛樂圈人物。
500個tag的t-sne分布:
Tag2Vec産生的向量表示,原則上可以用來表征Tag詞,由于資料來源于Action,可以加上Content-based的資料,然後放在諸如CTR模型,在文章點選率預估,又或者模型的部分Feature,提升模型準确性;還可以在一些相關文章推薦時,通過Tag2Vec來露出其他相關的Tag,推薦這些Tag的文章;甚至可以和word2vec相同的用法,作為embedding的一種初始化表示,在任務中retrain這些參數。
所有代碼都在tensorflow-101/Tag2Vec,有興趣想在一些資料上測試的可以重制下。