[ML] Wide&Deep learning


Wide&Deep learning

最近調試了幾天WDL,留個筆記。
WDL是Google在2016年的paper,目標是用於自己Google play中的app推薦。

官方介紹
paper download
圖片描述

推薦系統

推薦系統主要分為兩個部分,檢索系統(Retrieval)排序系統(Ranking)
首先用檢索的方法對大數據集進行初步篩選,返回一個query list。這里retrieval通常會結合采用機器學習模型和人工定義規則兩種方法。
得到query list后,再使用排序系統對每個item進行打分和排序。

分數值P(y|x), y是采取的行為,x是特征,一般包括
User feature
Contextual feature
Impression feature

memorization & generalization

推薦系統重要問題之一,解決memorization(記憶)和generalization(歸納)。
memorization主要是基於歷史數據 學習頻繁共同出現的item,並且探索他們之間的相關性,也就是根據歷史行為數據,推薦相關的item(topical),由wide作為主導;
generalization主要是基於相關性之間的傳遞, 探索歷史上沒有出現的新的特征的組合,也就是實現了推薦的多樣性問題(diversity),deep作為主導。

wide model

wide model主要采用邏輯回歸(LR),LR的特征一般是二值且稀疏的,這里采用one-hot編碼。特征組合(cross-product transformation),只有當變量同時滿足時才會取值為1,否則為0。但是這存在局限,當訓練集里沒有出現過query-item pair,就不能進行泛化。
Linear model:。其中特征x包括原始的輸入特征以及組合特征。
cross-product transformation特征表示為:

是一個bool變量,如果第i個特征是第k個transformation 的一部分,那么值就是1,否則就是0。

deep model

deep就是deep learning了,模型輸入包括類型特征(embedding)+連續特征。
對於特殊興趣或者小眾用戶,query-item matrix非常稀疏,dense embedding的方法可以得到對所有query-item pair非零的預測,但是容易過度泛化over-generalize,這點正好和LR互補。
每一個隱層(hidden-layer):
f激活函數(default=ReLu), l是層數。

Joint Training

在論文實驗中,訓練部分,wide使用Follow-the-regularized-learder(FTRL)+L1正則, deep使用了AdaGrad。 ![圖片描述](https://i.loli.net/2017/09/07/59b0e0bbc986f.jpg)

TensorFlow實現

沒自己實現過的東西理解就是不深。代碼實現這塊google在github給出了DEMO and myself code
不過在自己套用時就會出現問題,畢竟應用場景不同了。
首先是特征維度這塊,DEMO中的維度較少,全list出來還能接受,如果是一個上百維或者千維的,那就崩了。。。。
將所有列定義為連續(continuous)或者分類(categorical)。categorical_columns,有限集的一部分(eg:sex,name)。
對於類別較多的categorical_columns,使用哈希值作為鍵值。continuous_columns使用的是真實值。
continuous_columns,連續范圍內的任何數值(eg:money or age)。
Bucketization(桶化),將連續值分組看待,而不是將所有的作為一個大整體,提高准確性。

def csv_head():
    categorical_columns = ["C"+str(i) for i in range(1,6)] #這里是5-dims, not 6-dims
    continuous_columns = ["I"+str(i) for i in range(1,5)]
    label_column = ["label"]
    feature_columns = categorical_columns + continuous_columns
    CSV_COLUMNS = feature_columns + label_column
    return feature_columns, label_column, CSV_COLUMNS
def process_feature():
    wide_columns = []
    for name in categorical_columns:
        wide_columns.append(tf.feature_column.categorical_column_with_hash_bucket(
            name, hash_bucket_size=1000))
    deep_columns = []
    for name in continuous_columns:
        deep_columns.append(tf.feature_column.numeric_column(name))
    for col in wide_columns:
        deep_columns.append(tf.feature_column.embedding_column(
            col, dimension=8))
    price_buckets = []
    for i in range(7):
        price_buckets.append( tf.feature_column.bucketized_column(deep_columns[i],
            boundaries=[10, 20, 30, 40, ]))
    wide_columns.extend(price_buckets)
    cross = [["C3", "C4"], ["C4", "C5"], ["C3","C4","C5"]]
    crossed_columns = []
    for name in cross:
        crossed_columns.append(tf.feature_column.crossed_column(name,hash_bucket_size=50))
    return wide_columns, deep_columns, crossed_columns

然后就是.predict那步。輸入特征x就好,不需要label,在input_fn的返回值處去掉y就好。返回結果是一個generator的格式,需要使用for來讀取,而且在DNNLinearCombinedRegressor和DNNLinearCombinedClassifier的輸出內容是不一樣的,需要自己打印出來看需要的是什么。
其他部分按照官方DEMO 來就行,還是給的挺好的。

最后預警一個TF的坑吧,也是很多人不用TF的一個重要原因,沒事亂改借口,並且相同功能的函數有好幾個,對之前版本的兼容性就更談不上了,只能兩個字回饋,任性!!!
在R1.3版本中,tf.contrib.learn.下的estimator很多都被remove了,在使用的時候會輸出很多沒用的log信息告訴你這玩意在哪個時間被移除了。所以推薦在使用的時候該用tf.estimator這個模塊下的內容。官方github上的DEMO也是這個模塊下的版本。強烈推薦!

Reference

https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/learn/wide_n_deep_tutorial.py
https://github.com/yufengg/widendeep/blob/master/trainer/task.py
[譯] 簡明 TensorFlow 教程 — 第二部分:混合學習
論文筆記 - Wide and Deep Learning for Recommender Systems
tensorflow學習筆記(六):TF.contrib.learn大雜燴
https://www.tensorflow.org/extend/estimators
tensorflow線性模型以及Wide deep learning
《Wide & Deep Learning for Recommender Systems 》筆記
http://blog.sina.com.cn/s/blog_61c463090102wjdc.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM