標籤:

VII.應用-推薦系統-基於RBM的推薦演算法

受限玻爾茲曼機-推導過程

受限玻爾茲曼機示意圖如下:

假設一個RBM有n個可見單元和m個隱單元,RBM作為一個系統所具備的能量定義為

Eleft(v,hmid 	heta
ight)=-sumlimits_{i=1}^{n}a_iv_i-sumlimits_{j=1}^{m}b_jh_j-sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}v_iW_{ij}h_j

同時(v,h)的聯合概率為

Pleft(v,hmid 	heta
ight)=frac{e^{-E(v,hmid	heta)}}{Z(	heta)},Z(	heta)=sumlimits_{v,h}e^{-E(v,hmid	heta)}

對於一個實際問題,我們最關心的是由RBM所定義的關於觀測數據v的分布P(vmid	heta),即聯合概率P(v,hmid	heta)的邊際分布,也稱為似然函數(likehood function),根據概率的加法原則可以得到P(vmid	heta)=frac{1}{Z(	heta)}sumlimits_{h}e^{-E(v,hmid	heta)}

egin{align} Pleft(h_j=1mid v,	heta
ight) &=frac{Pleft(h_j=1,vmid	heta
ight)}{P(vmid 	heta)} (bayes)cr &=frac{Pleft(h_j=1,vmid	heta
ight)}{Pleft(h_j=1,vmid	heta
ight)+Pleft(h_j=0,vmid	heta
ight)} cr &=frac{e^{-E(h_j=1,vmid	heta)}}{e^{-E(h_j=1,vmid	heta)}+e^{-E(h_j=0,vmid	heta)}} cr &=frac{1}{1+e^{-[E(h_j=0,vmid	heta)-E(h_j=1,vmid	heta)]}} cr &=frac{1}{1+e^{-(b_j+sumlimits_{i}v_iW_{ij})}} cr &=sigmoidleft(b_j+sumlimits_{i}v_iW_{ij}
ight) end{align}

同理:Pleft(v_i=1mid h,	heta
ight)=sigmoidleft(a_i+sumlimits_{j}W_{ij}h_j
ight)

RBM的任務就是求出參數	heta的值,參數	heta用最大似然方法求得(假設有T個樣本),即

	heta^{*}=arg underset{	heta}{max} L(	heta)=arg underset{	heta}{max}sumlimits_{t=1}^{T}logPleft(v^{(t)}mid	heta
ight)

由於:

egin{align} L(	heta) &=sumlimits_{t=1}^{T}logPleft(v^{(t)}mid	heta
ight)cr &=sumlimits_{t=1}^{T}logsumlimits_{h}Pleft(v^{(t)},hmid	heta
ight)cr &=sumlimits_{t=1}^{T}logfrac{sum_{h}expleft[-Eleft(v^{(t)},hmid	heta
ight)
ight]}{sum_vsum_hexpleft[-E(v,hmid	heta)
ight]}cr &=sumlimits_{t=1}^{T}left(logsumlimits_{h}expleft[-Eleft(v^{(t)},hmid	heta
ight)
ight]-logsumlimits_{v}sumlimits_{h}expleft[-Eleft(v,hmid	heta
ight)
ight]
ight) end{align}

則對數似然函數關於	heta的梯度為

egin{align} frac{partial L(	heta)}{partial	heta} &=sumlimits_{t=1}^{T}frac{partial}{partial	heta}left(logsumlimits_{h}expleft[-Eleft(v^{(t)},hmid	heta
ight)
ight]-logsumlimits_{v}sumlimits_{h}expleft[-Eleft(v,hmid	heta
ight)
ight]
ight)cr &=sumlimits_{t=1}^{T}left(A·frac{partialleft[-E(v^{(t)},hmid	heta)
ight]}{partial	heta}-B·frac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}
ight)cr &=sumlimits_{t=1}^{T}left(langlefrac{partialleft[-E(v^{(t)},hmid	heta)
ight]}{partial	heta}
angle_{P(hmid v^{(t)},	heta)}-langlefrac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}
angle_{P(v,hmid	heta)}
ight) end{align}

其中:

egin{align} A &=sumlimits_{h}frac{expleft[-Eleft(v^{(t)},hmid	heta
ight)
ight]}{sum_h expleft[-E(v^{(t)},hmid	heta)
ight]}cr &=sumlimits_{h}frac{Pleft(v^{(t)},hmid	heta
ight)}{Pleft(v^{(t)}mid	heta
ight)}cr &=sumlimits_{h}Pleft(hmid v^{(t)},	heta
ight) end{align}

egin{align} B &=sumlimits_{v}sumlimits_{h}frac{expleft[-Eleft(v,hmid	heta
ight)
ight]}{sum_vsum_h expleft[-E(v,hmid	heta)
ight]}cr &=sumlimits_{v}sumlimits_{h}Pleft(v,hmid	heta
ight) end{align}

第二個期望的求解過程如下:

egin{align} langlefrac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}
angle_{P(v,hmid	heta)} &=sumlimits_{v}sumlimits_{h}Pleft(v,hmid	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}cr &=sumlimits_{v}sumlimits_{h}P(vmid	heta)Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}cr &= sumlimits_{v}P(vmid	heta)sumlimits_{h}Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta}cr end{align}

求解上述公式中的sumlimits_{h}Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial	heta},因為	heta={W_{ij},a_i,b_j},所以需要分別求偏導:

egin{align} sumlimits_{h}Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial W_{ij}} &=sumlimits_{h}P(hmid v,	heta)v_ih_jcr &=sumlimits_{h_1...h_j=0,...}P(hmid v,	heta)v_ih_j+sumlimits_{h_1...h_j=1,...}P(hmid v,	heta)v_ih_jcr &=Pleft(h_j=1mid v,	heta
ight)v_i end{align}

egin{align} sumlimits_{h}Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial a_i} &=sumlimits_{h}P(hmid v,	heta)v_icr &=v_isumlimits_{h}P(hmid v,	heta)cr &=v_i end{align}

egin{align} sumlimits_{h}Pleft(hmid v,	heta
ight)frac{partialleft[-E(v,hmid	heta)
ight]}{partial b_{j}} & =Pleft(h_j=1mid v,	heta
ight) end{align}

求解第一個期望的過程與第二個很類似。

最後得到:

egin{align} frac{partial L(	heta)}{partial W_{ij}} &=sumlimits_{t=1}^{T}left(sumlimits_{h}Pleft(hmid v^{(t)},	heta
ight)·frac{partialleft[-E(v^{(t)},hmid	heta)
ight]}{partial W_{ij}}-sumlimits_{v,h}Pleft(v,hmid	heta
ight)·frac{partialleft[-E(v,hmid	heta)
ight]}{partial W_{ij}}
ight)cr &=sumlimits_{t=1}^{T}left(Pleft(h_j=1mid v^{(t)},	heta
ight)v^{(t)}_i-sum_vP(vmid	heta)Pleft(h_j=1mid v,	heta
ight)v_i
ight) end{align}

egin{align} frac{partial L(	heta)}{partial a_i} &=sumlimits_{t=1}^{T}left(sumlimits_{h}Pleft(hmid v^{(t)},	heta
ight)·frac{partialleft[-E(v^{(t)},hmid	heta)
ight]}{partial a_i}-sumlimits_{v,h}Pleft(v,hmid	heta
ight)·frac{partialleft[-E(v,hmid	heta)
ight]}{partial a_i}
ight)cr &=sumlimits_{t=1}^{T}left(v^{(t)}_i-sum_vP(vmid	heta)v_i
ight) end{align}

egin{align} frac{partial L(	heta)}{partial b_j} &=sumlimits_{t=1}^{T}left(sumlimits_{h}Pleft(hmid v^{(t)},	heta
ight)·frac{partialleft[-E(v^{(t)},hmid	heta)
ight]}{partial b_j}-sumlimits_{v,h}Pleft(v,hmid	heta
ight)·frac{partialleft[-E(v,hmid	heta)
ight]}{partial b_j}
ight)cr &=sumlimits_{t=1}^{T}left(Pleft(h_j=1mid v^{(t)},	heta
ight)-sum_vP(vmid	heta)Pleft(h_j=1mid v,	heta
ight)
ight) end{align}

受限玻爾茲曼機-對比散度

v_1=x

  1. 計算 P(h_1mid v_1)=sigma(b+v_1W)
  2. 計算 P(v_2mid h_1)=sigma(a+h_1W^T),然後進行採樣

  3. 計算 P(h_2mid v_2)=sigma(b+v_2W)
  4. 更新公式為:

W=W+alpha(v_1^T·P(h_1mid v_1)-v_2^T·P(h_2mid v_1))

a=a+alpha(v_1-v_2)

b=b+alpha(P(h_1mid v_1)-P(h_2mid v_1))

受限玻爾茲曼機-推薦演算法

# coding:utf-8import timeimport numpy as npimport pandas as pdclass BRBM(object): def __init__(self, n_visible, n_hiddens=2, learning_rate=0.1, batch_size=10, n_iter=300): self.n_hiddens = n_hiddens self.learning_rate = learning_rate self.batch_size = batch_size self.n_iter = n_iter self.components_ = np.asarray(np.random.normal(0, 0.01, (n_hiddens, n_visible)), order=fortran) self.intercept_hidden_ = np.zeros(n_hiddens, ) self.intercept_visible_ = np.zeros(n_visible, ) self.h_samples_ = np.zeros((batch_size, n_hiddens)) def transform(self, x): h = self._mean_hiddens(x) return h def reconstruct(self, x): h = self._mean_hiddens(x) v = self._mean_visible(h) return v def gibbs(self, v): h_ = self._sample_hiddens(v) v_ = self._sample_visibles(h_) return v_ def fit(self, x): n_samples = x.shape[0] n_batches = int(np.ceil(float(n_samples) / self.batch_size)) batch_slices = list(self._slices(n_batches * self.batch_size, n_batches, n_samples)) for iteration in xrange(self.n_iter): for batch_slice in batch_slices: self._fit(x[batch_slice]) return self def _sigmoid(self, x): return 1.0 / (1.0 + np.exp(-x)) def _mean_hiddens(self, v): p = np.dot(v, self.components_.T) p += self.intercept_hidden_ return self._sigmoid(p) def _mean_visible(self, h): p = np.dot(h, self.components_) p += self.intercept_visible_ return self._sigmoid(p) def _sample_hiddens(self, v): p = self._mean_hiddens(v) return np.random.random_sample(size=p.shape) < p def _sample_visibles(self, h): p = self._mean_visible(h) return np.random.random_sample(size=p.shape) < p def _free_energy(self, v): return (- np.dot(v, self.intercept_visible_) - np.logaddexp(0, np.dot(v, self.components_.T) + self.intercept_hidden_).sum(axis=1)) def _fit(self, v_pos): h_pos = self._mean_hiddens(v_pos) v_neg = self._sample_visibles(self.h_samples_) h_neg = self._mean_hiddens(v_neg) lr = float(self.learning_rate) / v_pos.shape[0] update = np.dot(v_pos.T, h_pos).T update -= np.dot(h_neg.T, v_neg) self.components_ += lr * update self.intercept_hidden_ += lr * (h_pos.sum(axis=0) - h_neg.sum(axis=0)) self.intercept_visible_ += lr * (np.asarray(v_pos.sum(axis=0)).squeeze() - v_neg.sum(axis=0)) h_neg[np.random.uniform(size=h_neg.shape) < h_neg] = 1.0 # sample binomial self.h_samples_ = np.floor(h_neg, h_neg) def _slices(self, n, n_packs, n_samples=None): start = 0 for pack_num in range(n_packs): this_n = n // n_packs if pack_num < n % n_packs: this_n += 1 if this_n > 0: end = start + this_n if n_samples is not None: end = min(n_samples, end) yield slice(start, end, None) start = end

推薦閱讀:

搜索結果排序原理

TAG:推薦演算法 |