推薦系統遇上深度學習(四)--多值離散特徵的embedding解決方案
來自專欄大數據分析挖掘12 人贊了文章
作者:石曉文 Python愛好者社區專欄作者
個人公眾號:小小挖掘機 博客專欄: wenwen
推薦系統遇上深度學習系列:
推薦系統遇上深度學習(一)--FM模型理論和實踐:https://www.jianshu.com/p/152ae633fb00
推薦系統遇上深度學習(二)--FFM模型理論和實踐:https://www.jianshu.com/p/781cde3d5f3d推薦系統遇上深度學習(三)--DeepFM模型理論和實踐:https://www.jianshu.com/p/6f1c2643d31b1、背景
在本系列第三篇文章中,在處理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 | 機器學習 | 數據挖掘 |