FM初步理解&代碼實現

0.Reference

美團FFM: https://tech.meituan.com/2016/03/03/deep-understanding-of-ffm-principles-and-practices.html
CMUpdf: http://www.cs.cmu.edu/~wcohen/10-605/2015-guest-lecture/FM.pdf
CSDN: http://www.52caml.com/head_first_ml/ml-chapter9-factorization-family/
知乎: https://zhuanlan.zhihu.com/p/37963267

1.FM理解

核心思想: 二階特徵組合
FM = LR + Wij<xi,xj> 對於特徵xi,xj的組合
Wij只能被xi,xj非零項計算,而原始類別轉爲的ont-hot數據非常稀疏
如何有效計算Wij?
W矩陣 = VTV, W(nn大小)用V(nK計算)
轉化爲N
K的權重矩陣
1.W矩陣的參數量減少爲nk個,原來是n(n-1)/2
2.推導化簡:
轉化線性求解問題
http://www.algo.uni-konstanz.de/members/rendle/pdf/Rendle2010FM.pdf
3.FM 和 二次多項式的SVM區別在哪裏?
超參數k(隱向量長度),反映FM模型的表達力

2.FFM理解

核心:每一位特徵和其他field關係都用一個隱向量表徵
FM: 屬於FFM的特殊情況,每一維特徵都相當於一個field
e.g. 特徵i,對於特徵j的組合關係爲:
特徵i對於類別j的隱向量Vi,fj (dot點乘) 特徵j對於類別i的隱向量Vj,fi
隱向量的參數矩陣可以理解爲:
f個field,n維原始特徵,隱向量的長度是k; 參數數量=fnk

note:
1.一個類別特徵可能意味着500維的one-hot特徵,非常稀疏
2.FFM輸入可以省去值爲0的特徵index(其對於模型的訓練不起作用)
3.將源特徵歸一化,主要使得數值特徵歸一化到(0,1)之間 (歸一化方法??)

3.1 FM圖片

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

3.2 FFM圖片

在這裏插入圖片描述

4.代碼實現

# demo0: https://www.jiqizhixin.com/articles/2018-07-16-17
# demo1:  https://realxuan.github.io/2018/10/18/FM(Factorization%20Machine)%E6%A8%A1%E5%9E%8B/  
# demo2: http://nowave.it/factorization-machines-with-tensorflow.html
class FM(Model):
    def __init__(self,input_dim=None,output_dim=1,factor_orider=10,opt_algo='gd',learning_rate=le-2,l2_w=0,l2_v=0,random_seed=23):
        super().__init__(self)	
        #定義計算圖
        self.graph = tf.Graph()
        with self.graph.as_default():
            if random_seed is not None:
                tf.set_random_seed(random_seed)
        #定義參數節點
        self.X = tf.sparse_placeholder(tf.float32, shape=[None, input_dim], name="X")
        self.y = tf.placeholder(tf.float32, shape=[None, output_dim], name="y")
        self.V = tf.get_variable("v", shape=[input_dim, factor_orider], dtype=tf.float32, initializer=tf.truncated_normal_initializer(stddev=0.3))
        self.W = tf.get_variable("Weights", shape=[n, 1], dtype=tf.float32, initializer=tf.truncated_normal_initializer(stddev=0.3))
        self.b = tf.get_variable("Biases", shape=[1, 1], dtype=tf.float32, initializer=tf.zeros_initializer())
        #定義模型
        #一階部分
        xw = tf.sparse_tensor_dense_matmul(self.X, self.W)
        xv = tf.square(tf.sparse_tensor_dense_matmul(self.X, self.V))
        #二階部分 multiply是矩陣對應元素相乘,matmul是矩陣乘法
        fm_hat = tf.reduce_sum(tf.square(tf.sparse_tensor_dense_matmul(self.X ,self.V)) - (tf.sparse_tensor_dense_matmul(tf.multiply(self.X,self.X), tf.multiply(self.V,self.V))), axis=1, keep_dims=True) / 2
        #fm函數
        logits = tf.reshape(b+xw+fm_hat,[-1])
        #通過sigmoid函數計算預測值
        self.y_ = tf.sigmoid(logits)
        #Loss = 交叉熵Error + l2正則
        self.loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=self.y)) +l2_w * tf.nn.l2_loss(xw) + l2_v * tf.nn.l2_loss(xv)
        #模型的優化器
        self.optimizer = get_optimizer(opt_algo, learning_rate, self.loss)
        #初始化模型參數
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章