Nonlinear Component Analysis as a Kernel Eigenvalue Problem

Scholkopf B, Smola A J, Muller K, et al. Nonlinear component analysis as a kernel eigenvalue problem[J]. Neural Computation, 1998, 10(5): 1299-1319.

普通的PCA將下式進(jìn)行特征分解(用論文的話講就是對角化):
C = \frac{1}{M} \sum \limits_{j=1}^M x_j x_j^T
其中x_j \in \mathbb{R}^{N}, j = 1, \ldots, M葵萎,且\sum \limits_{j=1}^M x_j = 0(中心化)导犹。

而kernel PCA試圖通過一個非線性函數(shù):
\Phi:\mathbb{R}^N \rightarrow F, x \rightarrow X
其中F是一個高維空間(甚至是無限維)。
所以我們要解決這么一個問題:
\bar{C} = \frac{1}{M} \sum_{j=1}^M \Phi (x_j) \Phi(x_j)^T

其實我們面對的第一個問題不是維度的問題而是\Phi的選擇或者說構(gòu)造羡忘。我們?yōu)槭裁匆褦?shù)據(jù)映射到高維的空間谎痢?因為當(dāng)前數(shù)據(jù)的結(jié)構(gòu)(或者說分布)并不理想。

比如滿足(x-1)^2+(y-1)^2=4的點卷雕,我們可以擴充到高維空間(x^2, x, y, y^2)节猿,在高維空間是線性的(雖然這個例子用在kernel SVM 比較好)。

因為\Phi(\cdot)的構(gòu)造蠻麻煩的漫雕,即便有一些先驗知識滨嘱。我們來看一種比較簡單的泛用的映射:
(x_1, x_2, x_3) \rightarrow (x_1^3, x_2^3, x_3^3, x_1^2x_2,x_1^2x_3,x_1x_2^2,x_1x_3^2,x_2^2x_3,x_2x_3^2,x_1x_2x_3)
這種樣子的映射,很容易把維度擴充到很大很大蝎亚,這個時候求解特征問題會變得很麻煩九孩。

kernel PCA

假設(shè)\sum \limits_{i=1}^M \Phi(x_i)=0(如何保證這個性質(zhì)的成立在最后講,注意即便\sum \limits_{i=1}^M x_i = 0发框,\sum \limits_{i=1}^M \Phi(x_i)=0也不一定成立)躺彬。

假設(shè)我們找到了\bar{C}的特征向量V \ne 0:
\bar{C}V = \lambda V
因為V\Phi(x_i),i=1,\ldots, M的線性組合(這個容易證明),所以梅惯,V可以由下式表示:
V = \sum \limits_{i=1}^M \alpha_i \Phi(x_i)

所以:
\lambda V^T \Phi(x_j) = V^T\bar{C} \Phi(x_j), \quad for \: all \: j=1,\ldots, M
等價于(記\Phi = [\Phi(x_1), \ldots, \Phi(x_M)]):
\begin{array}{ll} \lambda \sum \limits_{i=1}^M \alpha_i (\Phi^T(x_i)\Phi(x_j)) &= \lambda \{ \Phi^T \Phi(x_j)\} ^T \alpha \\ & =\frac{1}{M} \sum \limits_{i=1}^M \alpha_i \Phi^T(x_i) \Phi \Phi^T \Phi(x_j) \\ & = \frac{1}{M} \{\Phi^T \Phi \Phi^T \Phi(x_j)\}^T \alpha \end{array}
對于j=1,\ldots, M均成立宪拥,其中\alpha = [\alpha_1, \ldots, \alpha_M]^T

等價于:
M \lambda \Phi^T \Phi \alpha = \Phi^T \Phi \Phi^T \Phi \alpha
K = \Phi^T \Phi铣减,那么可寫作:
M \lambda K \alpha = K^2\alpha
其中K_{ij} = \Phi^T(x_i) \Phi(x_j)

所以她君,我們可以通過下式來求解\alpha:
M\lambda \alpha = K \alpha
\alphaK的特征向量(注意,當(dāng)\alpha為特征向量的時候是一定符合M \lambda K \alpha = K^2\alpha的葫哗,反之也是的缔刹,即二者是等價的)球涛。

假設(shè)\lambda_1 \ge \lambda_2 \ge \ldots \ge \lambda_M對應(yīng)\alpha^1, \ldots, \alpha^M,那么相應(yīng)的V也算是求出來了校镐。

需要注意的是亿扁,\|\alpha\|往往不為1,因為我們希望\|V\|=1鸟廓,所以:
V^TV = \alpha^T K \alpha = \lambda \|\alpha\|^2 = 1
所以\|\alpha\| = \frac{1}{\sqrt{\lambda}}

PCA當(dāng)然需要求主成分从祝,假設(shè)有一個新的樣本x,我們需要求:
\Phi(x)^TV = \Phi^T(x) \Phi \alpha = \sum \limits_{i=1}^M \alpha_i \Phi^T(x_i) \Phi(x)

注意引谜,我們只需要計算\Phi^T(x_i) \Phi(x)牍陌。

現(xiàn)在回到kernel PCA 上的關(guān)鍵kernel上。注意到员咽,無論是K毒涧,還是最后計算主成分,我們都只需要計算\Phi^T(x)\Phi(y)就可以了骏融,所以如果我們能夠找到一個函數(shù)k(x,y)來替代就不必顯示將x映射到\Phi(x)了链嘀,這就能夠避免了\Phi(\cdot)的選擇問題和計算問題萌狂。

kernel 的選擇

顯然档玻,PCA的\lambda \ge 0,所以我們也必須保證K為半正定矩陣茫藏,相應(yīng)的核函數(shù)k稱為正定核误趴,Mercer定理有相應(yīng)的構(gòu)建。

也有現(xiàn)成的正定核:

多項式核

k(x, y) = (x^Ty + 1)^d
論文中是(x^Ty)^d

高斯核函數(shù)

k(x, y) = \exp \{\ -\frac{\|x-y\|^2}{2\sigma^2}\}

性質(zhì)

在這里插入圖片描述

論文用上面的一個例子來說明务傲,kernel PCA可能更準(zhǔn)確地抓住數(shù)據(jù)的結(jié)構(gòu)凉当。

kernel PCA具有普通PCA的性質(zhì),良好的逼近(從方差角度)售葡,以及擁有最多的互信息等等看杭。并且,如果k(x, y) = k(x^Hy)挟伙,那么kernel PCA還具有酉不變性楼雹。

因為普通的PCA處理的是一個N \times N的協(xié)方差矩陣,所以尖阔,至多獲得N個載荷向量贮缅,而kernel PCA至多獲得M個載荷向量(特征值非零)。所以介却,kernel PCA有望比普通PCA更加精準(zhǔn)谴供。

一些問題

中心化

PCA處理的是協(xié)方差矩陣,正如我們最開始所假設(shè)的齿坷,\sum \limits_{i=1}^{M} \Phi(x_i)=0,即中心化桂肌。因為\Phi(\cdot)并不是線性函數(shù)数焊,所以,即便\sum \limits_{i=1}^M x_i = 0也不能保證\sum \limits_{i=1}^{M} \Phi(x_i)=0崎场,不過有別的方法處理昌跌。

\tilde{\Phi}(x_i) = \Phi(x_i) - \frac{1}{M}\sum \limits_{k=1}^M \Phi(x_k) \\ \tilde{K}_{ij} = \tilde{\Phi}^T(x_i) \Phi(x_j) \\ 1_{M} = \{1\}_{ij}^{M \times M}
可以得到:
\begin{array}{ll} \tilde{K}_{ij} &= \tilde{\Phi}^T(x_i) \Phi(x_j) \\ &= \big(\Phi(x_i) - \frac{1}{M}\sum \limits_{k=1}^M \Phi(x_k)\big)^T \big(\Phi(x_j) - \frac{1}{M}\sum \limits_{k=1}^M \Phi(x_k)\big) \\ &= K_{ij} - \frac{1}{M} \sum \limits_{k=1}^M K_{kj} - \frac{1}{M} \sum \limits_{k=1}^M K_{ik} + \frac{1}{M^2} \sum \limits \limits_{m,n=1}^M K_{mn} \\ &= (K - 1_MK - K1_M + 1_MK1_M)_{ij} \end{array}
于是,我們通過K可以構(gòu)造出\tilde{K}照雁。只需再求解\tilde{K}\tilde{\alpha} = M \lambda \tilde{\alpha}即可蚕愤。

恢復(fù)

我們知道,根據(jù)PCA選出的載荷向量以及主成分饺蚊,我們能夠恢復(fù)出原數(shù)據(jù)(或者近似萍诱,如果我們只選取了部分載荷向量)。對于kernel PCA污呼,比較困難裕坊,因為我們并沒有顯式構(gòu)造\Phi(\cdot),也就沒法顯式找到V燕酷,更何況籍凝,有時候我們高維空間找到V在原空間中并不存在原像。
或許苗缩, 我們可以通過:
\min \limits_{x} \quad \|\Phi(x) - \Phi(\hat{x})\|^2
來求解饵蒂,注意到,上式也只和核函數(shù)k(x,y)有關(guān)酱讶。

代碼


import numpy as np

class KernelPCA:

    def __init__(self, data, kernel=1, pra=3):
        self.__n, self.__d = data.shape
        self.__data = np.array(data, dtype=float)
        self.kernel = self.kernels(kernel, pra)
        self.__K = self.center()

    @property
    def shape(self):
        return self.__n, self.__d

    @property
    def data(self):
        return self.data

    @property
    def K(self):
        return self.__K

    @property
    def alpha(self):
        return self.__alpha

    @property
    def eigenvalue(self):
        return self.__value

    def kernels(self, label, pra):
        """
        數(shù)據(jù)是一維的時候可能有Bug
        :param label: 1:多項式;2:exp
        :param pra:1: d; 2: sigma
        :return: 函數(shù) 或報錯
        """
        if label is 1:
            return lambda x, y: (x @ y) ** pra
        elif label is 2:
            return lambda x, y: \
                np.exp(-(x-y) @ (x-y) / (2 * pra ** 2))
        else:
            raise TypeError("No such kernel...")

    def center(self):
        """中心化"""
        oldK = np.zeros((self.__n, self.__n), dtype=float)
        one_n = np.ones((self.__n, self.__n), dtype=float)
        for i in range(self.__n):
            for j in range(i, self.__n):
                x = self.__data[i]
                y = self.__data[j]
                oldK[i, j] = oldK[j, i] = self.kernel(x, y)
        return oldK - 2 * one_n @ oldK + one_n @ oldK @ one_n

    def processing(self):
        """實際上就是K的特征分解,再對alpha的大小進(jìn)行一下調(diào)整"""
        value, alpha = np.linalg.eig(self.__K)
        index = value > 0
        value = value[index]
        alpha = alpha[:, index] * (1 / np.sqrt(value))
        self.__alpha = alpha
        self.__value = value / self.__n

    def score(self, x):
        """來了一個新的樣本退盯,我們進(jìn)行得分"""
        k = np.zeros(self.__n)
        for i in range(self.__n):
            y = self.__data[i]
            k[i] = self.kernel(x, y)
        return k @ self.__alpha





"""

import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y = x ** 2 + [np.random.randn() * 0.1 for i in range(100)]
data = np.array([x, y]).T

test = KernelPCA(data, pra=1)
test.processing()
print(test.alpha.shape)
print(test.alpha[:, 0])

"""

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泻肯,隨后出現(xiàn)的幾起案子渊迁,更是在濱河造成了極大的恐慌,老刑警劉巖灶挟,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琉朽,死亡現(xiàn)場離奇詭異,居然都是意外死亡稚铣,警方通過查閱死者的電腦和手機箱叁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榛泛,“玉大人蝌蹂,你說我怎么就攤上這事〔芟牵” “怎么了孤个?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沛简。 經(jīng)常有香客問我齐鲤,道長斥废,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任给郊,我火速辦了婚禮牡肉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘淆九。我一直安慰自己统锤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布炭庙。 她就那樣靜靜地躺著饲窿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪焕蹄。 梳的紋絲不亂的頭發(fā)上逾雄,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音腻脏,去河邊找鬼鸦泳。 笑死,一個胖子當(dāng)著我的面吹牛永品,可吹牛的內(nèi)容都是我干的做鹰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腐碱,長吁一口氣:“原來是場噩夢啊……” “哼誊垢!你這毒婦竟也來了掉弛?” 一聲冷哼從身側(cè)響起症见,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎殃饿,沒想到半個月后谋作,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡乎芳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年遵蚜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奈惑。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吭净,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肴甸,到底是詐尸還是另有隱情寂殉,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布原在,位于F島的核電站友扰,受9級特大地震影響彤叉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜村怪,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一秽浇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧甚负,春花似錦柬焕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碰辅,卻和暖如春懂昂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背没宾。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工轧简, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人勤讽。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓待错,卻偏偏與公主長得像,于是被迫代替她去往敵國和親会钝。 傳聞我的和親對象是個殘疾皇子伐蒋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355