推薦系統遇上深度學習(四)--多值離散特徵的embedding解決方案

推薦系統遇上深度學習(四)--多值離散特徵的embedding解決方案

來自專欄大數據分析挖掘12 人贊了文章

作者:石曉文 Python愛好者社區專欄作者

個人公眾號:小小挖掘機

博客專欄: wenwen

推薦系統遇上深度學習系列:

推薦系統遇上深度學習(一)--FM模型理論和實踐:jianshu.com/p/152ae633f

推薦系統遇上深度學習(二)--FFM模型理論和實踐:jianshu.com/p/781cde3d5

推薦系統遇上深度學習(三)--DeepFM模型理論和實踐:

jianshu.com/p/6f1c2643d

1、背景

在本系列第三篇文章中,在處理DeepFM數據時,由於每一個離散特徵只有一個取值,因此我們在處理的過程中,將原始數據處理成了兩個文件,一個記錄特徵的索引,一個記錄了特徵的值,而每一列,則代表一個離散特徵。

但假如,我們某一個離散特徵有多個取值呢?舉個例子來說,每個人喜歡的NBA球隊,有的人可能喜歡火箭和湖人,有的人可能只喜歡勇士,也有的人喜歡騎士、綠軍、猛龍等一大堆。對於這種特徵,我們本文將其稱為多值離散特徵。

根據DeepFM的思想,我們需要將每一個field的特徵轉換為定長的embedding,即使有多個取值,也是要變換成定長的embedding。

那麼,一種思路來了,比如一個用戶喜歡兩個球隊,這個field的特徵可能是[1,1,0,0,0,0,0.....0],那麼我們使用兩次embedding lookup,再取個平均不就好了嘛。

嗯,這的確也許可能是一種思路吧,在tensorflow中,其實有一個函數能夠實現我們上述的思路,那就是tf.nn.embedding_lookup_sparse。別著急,我們一步一步來實現多值離散特徵的embedding處理過程。

2、解決方案

輸入數據

假設我們有三條數據,每條數據代表一個user所喜歡的nba球員,比如有登哥,炮哥,杜老四,慕斯等等:

csv = [ "1,harden|james|curry", "2,wrestbrook|harden|durant", "3,|paul|towns",]

我們建立一個所有球員的集合:

TAG_SET = ["harden", "james", "curry", "durant", "paul","towns","wrestbrook"]

數據處理

這裡我們需要一個得到一個SparseTensor,即多為稀疏矩陣的一種表示方式,我們只記錄非0值所在的位置和值。

比如說,下面就是我們對上面數據處理過後的一個SparseTensor,indices是數組中非0元素的下標,values跟indices一一對應,表示該下標位置的值,最後一個表示的是數組的大小。

處理得到SparseTensor的完整代碼如下:

def sparse_from_csv(csv): ids, post_tags_str = tf.decode_csv(csv, [[-1], [""]]) table = tf.contrib.lookup.index_table_from_tensor( mapping=TAG_SET, default_value=-1) ## 這裡構造了個查找表 ## split_tags = tf.string_split(post_tags_str, "|") return tf.SparseTensor( indices=split_tags.indices, values=table.lookup(split_tags.values), ## 這裡給出了不同值通過表查到的index ## dense_shape=split_tags.dense_shape)

定義embedding變數

定義我們的embedding的大小為3:

TAG_EMBEDDING_DIM = 3embedding_params = tf.Variable(tf.truncated_normal([len(TAG_SET), TAG_EMBEDDING_DIM]))

得到embedding值

將我們剛才得到的SparseTensor,傳入到tf.nn.embedding_lookup_sparse中,我們就可以得到多值離散特徵的embedding值。

tags = sparse_from_csv(csv)embedded_tags = tf.nn.embedding_lookup_sparse(embedding_params, sp_ids=tags, sp_weights=None)

sp_ids就是我們剛剛得到的SparseTensor,而sp_weights=None代表的每一個取值的權重,如果是None的話,所有權重都是1,也就是相當於取了平均。如果不是None的話,我們需要同樣傳入一個SparseTensor,代表不同球員的喜歡權重。大家感興趣可以自己去嘗試。

測試輸出

最後我們來看看得到的效果:

with tf.Session() as s: s.run([tf.global_variables_initializer(), tf.tables_initializer()]) print(s.run([embedded_tags]))

這只是一種解決方案,大家可以去探索更多的方法喲。


推薦閱讀:

pytorch中如何處理RNN輸入變長序列padding
Hulu機器學習問題與解答系列 | 第七彈:非監督學習演算法與評估
合成逼真圖像,試試港中大&英特爾的半參數方法 | CVPR 2018 oral
logistic regression 邏輯回歸
重拾基礎 - 線性回歸

TAG:深度學習DeepLearning | 機器學習 | 數據挖掘 |