推薦系統中的特征工程

在多數數據和機器學習的blog里,特征工程 Feature Engineering 都很少被提到。做模型的或者搞Kaggle比賽的人認為這些搞feature工作繁瑣又不重要不如多堆幾個模型,想入手實際問題的小朋友又不知道怎么提取feature來建模型。我就用個性化推薦系統做個例子,簡單說說特征工程在實際的問題里是怎么做。

定義

特征工程 Feature Engineering 在一篇Kaggle bloghttp://blog.kaggle.com/2014/08/01/learning-from-the-best/上有很好的定義:

By feature engineering, I mean using domain specific knowledge or automatic methods for generating, extracting, removing or altering features in the data set.

基本上說是,用目標問題所在的特定領域知識或者自動化的方法來生成、提取、刪減或者組合變化得到特征。這些特征可能是顯而易見比如說商品的品牌,也有可能需要復雜的模型計算,比如Facebook上用戶A和用戶B之間關系的緊密程度(FB使用了一個決策樹來生成一個描述這個程度的向量,這個向量決定了他們News Feed推薦內容。)。這篇blog覆蓋了一些用領域知識的方法,自動化方法在這里沒有提及。

背景

個性化推薦系統 Personalized recommender system 比其他的機器學習方法更依賴特征工程,所以我拿它來當作問題的背景,結合我之前做過的一個推薦系統里相關經驗來說說特征工程具體是個什么東西。

關于推薦系統和個性化推薦系統,可以參看 wikipediahttp://en.wikipedia.org/wiki/Recommender_system具體不贅述,以下的要點也盡量點到為止,否則這篇又成了“收藏了Mark了”但是不會讀的冗余長文。以下如果不特別指出,我就用推薦系統作為“個性化商品推薦系統”的簡稱。簡單來說,推薦系統就是你買了商品A,我們給你算出來個推薦列表 B C D E 等等。商業上來說個性化的推薦比一般化的推薦更能吸引顧客點擊或購買,所以利用特征功能提取這些“個性化”的特征放到推薦模型里就很重要,比如在我們的推薦系統里,把“品牌”的特征加進去,相對于 baseline 提高了20%左右的nDCG。推薦系統可以是機器學習的模型也可以是基于關聯或者統計規則的模型,對后者來說特征對推薦效果的提升占的比重更大。

利用領域知識生成和提取特征

這幾乎是特征工程里占大半時間的工作了:如何描述個性化并且用變量表示成特征。一般方法就是,想想你就是該商品的目標用戶,你會想要什么樣的個性化。

比如說我們做一個女性衣服類的推薦引擎,這個網站賣各種牌子顏色尺寸等。我們列出可能相關的一些特征,然后在實際購買數據里面檢查他們是否對購買結果產生影響和關聯性。比如,從購買數據里可以看出,女性對衣服的品牌多數有固定偏好,比如我太太就很喜歡LOFT的衣服。這些能對購買產生影響的因素都可以成為特征。

這部分工作需要很多領域知識,一般需要一組的研究人員討論,要認真的思考這個特定問題有些什么和別的問題不同的特征,也建議和市場部銷售部等有領域知識的專家討論。經驗上來說,這些特征提取的越多越好,并不用擔心特征過多,因為推薦系統的數據量都比較大,并且基于一些規則可以很好的篩選特征。

很多機器學習的方法也可以拿來提取一些比較不容易得到的直接特征,比如說原始數據里面沒有人工標記過商品的顏色,這些顏色可以通過圖像識別得到。統計規則也可以從銷售數據里得到一些特征,比如該商品的流行程度。

注意,這些特征可能是固定不變的,比如顏色,品牌等。它也有可能隨著時間變化,比如商品的銷售排名。實際經驗來說,時間變化采樣的顆粒度要按照實際推薦效果來決定,很可能過去三個月的銷售排名對推薦效果來說可以很穩定,也或許昨天的排名對今天的推薦效果比三個月平均更好。

特征的表達

大家都知道特征可以是“紅”“綠”“藍”這些離散特征,也可以是1.57這樣的連續值特征。一個特征具體如何表達,要看在它在具體模型上怎么用。某些特定問題更傾向于離散特征,因為像推薦系統這樣數據很大的情況可以利用模型訓練這些特征得到比連續值表達更好的效果。

比如說,商品的流行度可以是一個特征,因為對于某些流行的商品大家都搶著買,喜歡跟風買熱門商品這一特性可以作為推薦的特征。我們可以按照銷量排名然后歸一化得到每個商品的流行度值,但是直接用這個連續值會有一些問題,比如說用戶甲買了流行度分數為 0.75 0.5 0.2 0.1的四個商品,用戶乙買了流行度為0.7的一個商品,他們兩個怎么比?

如果還記得算法書上說的,定義幾個桶buckets,把流行度分到這幾個buckets里面,可以解決這個問題。比如定義三個桶:很流行1-0。95,較流行0.95-0.75,普通0.75-0.4。這樣用戶甲的特征就是[0,1,1]用戶乙的特征就是[0,1,0],這樣你的推薦模型就可以做一些對比他們倆的相似度或者其他推薦計算了。

順道提一下就是,為什么在這里直接把0.4之后的丟掉了以及為什么取了三個buckets。這個要看具體問題里面具體特征的用處。

如果這個模型是學習訓練出來的,可以用一些feature selection的辦法自動去掉一些不需要的bucket。對于那些不是學習出來的模型比如是簡單的相似性模型,按照實際推薦效果思考一下用戶的行為特征,需要丟棄一些特征。我之前包含過0.4以下的部分但是實際測試的時候發現推薦結果會惡化,也就是說對于我們的問題,用戶喜歡跟風買熱門的,但是不喜歡一直買冷門的。

特征需要按照實際購買數據進行修正和理解。三個buckets是我們系統里效果最好的。

一個比較高級的例子是 Facebook 在他們的 Machine Learning meetup 上提到的推薦News feed的特征。每個用戶對于其他用戶的 news 的點贊和留言以及其他的動作都會得到一個評價值,這是一系列的連續值,直接拿來訓練模型效果不好。他們的做法是做了一個簡單的決策樹,訓練的輸入是這些連續值,訓練目標是看對于用戶A是否應該顯示用戶B的 news 。這個決策樹顯然很粗糙,但是樹的每個葉子節點可以成為一個特征,那么這些葉子節點就可以當作用戶A的特征向量,拿來訓練其他模型比如Logistic Regression,效果不錯。

直接特征和間接特征

直接特征 Extacted Feature 就是比如商品的品牌,間接特征 Derived Feature 可以是從直接特征或者各種數據組合里計算推導出來的。

間接特征的一個例子還是品牌特征,拿女性服飾類舉例。比如我太太很喜歡LOFT的衣服,但如果一個推薦引擎使勁給推薦LOFT牌的衣服,她也會很煩。所以品牌并不完全是一個直接特征,它可以有一些變化。比如從購買數據里面看到,購買了LOFT牌衣服的,有20%也購買了J Crew牌,15%也購買了Ann Taylor牌。所以 LOFT 這個特征應該變成一個向量?[LOFT:1, J_Crew:0.2, Ann_Taylor:0.15,?…?]。實際效果上它提高了推薦的多樣性,在多個測試函數中都有不錯的提升。

間接特征另外一個高級一些的例子就是用戶職業。絕大多數用戶都不會填自己的職業等個人相關信息,主要是因為隱私或者就是因為麻煩。從用戶的購買記錄和瀏覽記錄里面,我們可以定義幾個預設的職業類型然后用戶的職業預測到這幾個類型里。比如用戶買過一些轉換插頭和充電器還有旅行電腦包,所以他可能常外出旅行,所以以后推薦的商品可能是輕便攜帶;又比如用戶買過母嬰用品就知道該用戶可能自己是媽媽或者家里有小孩。

關于間接特征我印象最深的是美國亞馬遜上的性別特征。我有一次給我太太買了給女生修眉毛的剃刀,亞馬遜的推薦內容就立刻從推薦相機鼠標鍵盤等男性特征較強的變成了推薦時尚雜志這種有女性特征的東西。

間接特征的提取可以用到很多機器學習的技術,比如根據商品的文本描述提取它的文本向量,以這些文本向量為特征訓練多分類的分類器,可以把商品分類對應到各種用戶職業特征上。它也可以利用人工標記的類型列表,比如時尚雜志的女性特征。它也可以利用一些統計規則,比如單反相機的購買記錄里,男性的比例會高于女性,所以單反相機的性別特征向量可以是購買人數性別的比例值。

特征選擇

這部分的工作就看起來比較高級一些,比較貼近機器學習的研究工作。一般來說是兩個方法:基于領域知識的手工選擇以及自動選擇方法。

對于關聯規則和統計規則的模型來說,手工選擇的比重要大一些。比如我們已有了baseline的特征向量,現在加進去品牌偏好,給一定的權值,看評價函數輸出的結果是否增強了推薦效果。對于學習的模型來說,可以通過模型自動選擇每個特征的權值,按照和效果的關聯來調整模型的參數。這里需要提醒的是,這個選擇過程不是單增單減,很可能遇到兩個特征組合A+B效果很好,A+C效果也很好,但是A+B+C效果就呵呵了。個人建議在關聯和統計規則里面把最重要的幾個特征放進去然后優化關于這幾個特征的規則,把復雜的特征選擇留給學習出來的模型。

自動選擇方法就很多了,用的也是常用的各種自動選擇方法,什么forward selection啊backward selection啊各種regularization等等,全寫在這里篇幅就太長,推薦看看一些其他關于機器學習里 feature selection 的blog和綜述。值得提醒的是選擇方法和評價函數的關聯。推薦系統的評價函數一般不是AUC曲線等按照error計算的函數,也就是說推薦的效果并不是按照“精準”來衡量,要遵循特定問題需要的評價函數比如nDCG,所以以error matrix為標準的一些方法可能效果會不好。比如說用PCA降低特征的維度很可能把那些對推薦效果很重要的長尾特征給舍棄了。

特征的組合變化

這部分工作看起來就比較碉堡,可發揮的空間就看你的想像力和經驗了。這里的組合變化遠不限于把已有的特征加減乘除(比如Kernel Tricks之類),我舉個比較有想像力的例子。

現在市面上社交網絡里面“你可能認識的人”的推薦算法幾乎都是基于補全網絡的辦法,這樣推薦的人可能只是單純的補充和完善朋友圈,推薦的人可能很無趣,這樣會導致推薦效果不好讓用戶失去接受推薦的興趣。目測新浪微博用的還是這種補全的方法,因為整天向我推薦丁一晨李開復姚晨等人或者最近關注的人的共同關注人,所以推薦的人很無趣幾乎都不會點關注。

斯坦福小帥哥教授 Jure Leskovec 在2010年的一篇文章“Predicting Positive and Negative Links in Online Social Networks”說到過一種基于用戶反饋的推薦“你可能認識的人”的推薦算法,他把鄰近三人之間的三角關系總共16種正負反饋的組合當作特征向量用來表達用戶A和被推薦目標用戶C之間的正負反饋,在圖里去掉一些已知正負反饋的邊來構建訓練數據,用簡單的Logistic Regression訓練模型達到了不錯的效果。可以谷歌找到這篇文章的幻燈片,里面有圖示講解。

結語

這篇文章就簡單提及一些特征工程的常用方法,說的是手工提取特征,從這些入手可以深入研究研究具體問題的具體做法,這是一個很細致的工作可以多鉆研鉆研。這里面沒有說到自動提取方法比如深度學習和卷積網絡等等,也沒說到推薦系統的其他方面比如大規模用戶聚類。構建一個推薦系統需要涉及很多東西,絕對不是GraphLab或者Mahout跑個協同過濾就能上馬的,這里面特征工程是很重要的一部分工作,在很多其他數據和機器學習的工作里面特征工程也差不多是從根本上改變模型效果的重要辦法之一。大家在歡樂調參的過程中不妨考慮考慮搞搞特征。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容