本文簡述瞭如下內容:html
(一)生成式模型的非參數方法算法
(二)Parzen窗估計數據結構
(三)k近鄰估計ide
(四)k近鄰分類器(k-nearest neighbor,kNN)函數
對於生成式模型(Generative model)來講,重要的地方在於類條件機率密度 $p(\textbf x|\omega_i)$ 的估計。上一篇介紹的參數方法,假定其是一個固定的分佈密度形式,而後估計這個顯式表達的函數中未知的參數。但這裏存在兩個問題:首先,假定的形式多是不許確的,實際數據並不符合這個假設;其次,經典的密度函數的參數形式都是單模的(單個局部極大值),實際上經常會有多模的狀況。性能
非參數方法的作法是,不假定密度的形式,直接從樣原本估計類條件機率密度 $p(\textbf x|\omega_i)$ 。注意:有些地方會把判別式模型(Discriminative model)也稱爲非參數方法。若是講的泛一點的話,「非參」這個詞能夠用在不少地方,例如非參貝葉斯方法(Nonparametric Bayesian methods),就是指參數個數能夠隨着數據的變化而自適應變化。學習
考慮一個點 $\textbf x$ 落在區域 $\mathcal R$ 中的機率:測試
$$P=\int_{\mathcal R}p(\textbf x')\text d\textbf x'$$spa
其中 $p(\textbf x)$ 是機率密度函數。設有 $n$ 個服從 $p(\textbf x)$ 的iid樣本 $\textbf x_1,...,\textbf x_n$,而且有 $k$ 個樣本落在區域 $\mathcal R$ 。根據二項分佈的均值咱們能夠知道,$k$ 的指望值是 $nP$ 。3d
如今假設這個區域足夠小(體積 $V$ 、樣本數 $k$ ),使得該區域內部是等機率密度的,那麼能夠有
$$P=\int_{\mathcal R}p(\textbf x')\text d\textbf x'\simeq p(\textbf x)V$$
從以上式子,就能夠獲得 $p(\textbf x)$ 的估計爲
$$p(\textbf x)\simeq \frac{k/n}{V}$$
其實這個式子很好理解,就是「密度等於機率除以體積」。這裏不討論太理論化的東西了,直接說怎麼作。
爲了估計點 $\textbf x$ 處的機率密度 $p(\textbf x)$ ,採起的作法是構造一系列包含點 $\textbf x$ 的區域 $\mathcal R_1,...,\mathcal R_n$ ,進而產生一個估計序列,該序列收斂到的值就是真實的機率密度。那麼對 $p(\textbf x)$ 的第 $n$ 次估計可表示爲
$$p_n(\textbf x)=\frac{k_n/n}{V_n}$$
上式在 $n\rightarrow\infty$ 時收斂到 $p(\textbf x)$ 的條件有三個:$V_n\rightarrow 0$ 、$k_n\rightarrow\infty$ 、$k_n/n\rightarrow 0$ 。
很明顯,爲了獲得這個估計序列,能夠有兩種處理方式:
1. 固定局部區域的體積 $V$ ,$k$ 改變,這就是Parzen窗估計。換言之,就是當 $n$ 給定時,要求 $V_n$ 惟一肯定,再求出此時的 $k_n$ ,進而求得 $p_n(\textbf x)$ 。
2. 固定局部區域的樣本數 $k$ ,$V$ 改變,這就是k近鄰估計。也就是說,當 $n$ 給定時,要求 $k_n$ 惟一肯定,再求出此時的 $V_n$ ,進而求得 $p_n(\textbf x)$ 。
圖片來源:[1]
1、窗函數與窗寬
Parzen窗估計經過改變區域內的樣本數來得到估計序列。先舉一個簡單的例子:設 $\mathcal R_n$ 是一個窗寬爲 $h_n$ 的 $d$ 維超立方體,則局部區域的體積爲 $V_n=h_n^d$ 。定義窗函數 $\phi(\textbf u)$ :
$$\phi(\textbf u)=\begin{cases} 1,&\quad |u_j|\geq\dfrac12;\\0,&\quad\text{otherwise.} \end{cases}$$
對於一維的狀況,該函數的圖像以下圖所示。若是是高維的,那麼每一維都是這樣的。
圖片來源:[1]
顯然,$\phi(\textbf u)$ 表示的是一箇中心在原點的單位超立方體。在窗函數定義好以後,能夠求得以 $\textbf x$ 爲中心、體積爲 $V_n=h_n^d$ 的局部區域內的樣本數:
$$k_n=\sum_{i=1}^n\phi(\dfrac{\textbf x-\textbf x_i}{h_n})$$
這個式子中,$\textbf x$ 是特徵空間內任一點,$\textbf x_i$ 是 $n$ 個iid樣本點。當一個樣本 $\textbf x_i$ 落在局部區域內時,有 $\phi(\dfrac{\textbf x-\textbf x_i}{h_n})=1$ ,因此累加和可求得局部區域內的樣本數。
將上式代入 $p_n(\textbf x)$ 的表達式,即可估計機率密度函數:
$$p_n(\textbf x)=\frac{1}{nV_n}\sum_{i=1}^n\phi(\dfrac{\textbf x-\textbf x_i}{h_n})$$
例如,令 $h_n=\dfrac{h_1}{\sqrt n}$ ,這樣隨着 $n$ 的變化獲得了估計序列。
實際上,上式給出了一個通常化的估計方式,它規定了窗函數的做用在於:明確樣本點 $\textbf x_i$ 對於點 $\textbf x$ 的密度函數估計所起到的貢獻,貢獻大小由兩個點的距離來決定。所以,窗函數不必定是上面的形式,只要使得估計出來的密度函數 $p_n(\textbf x)$ 知足機率密度函數應有的性質(例如,積分爲1)便可。所以,要求窗函數知足:
$$\phi(\textbf x)\geq 0,\quad \int\phi(\textbf u)\text{d}\textbf u=1, \quad V_n=h_n^d$$
Parzen窗估計中,若是窗函數的形式是規定好的,那麼密度估計的效果好壞將取決於窗寬。例若有兩個模型,分別規定 $h_n=\dfrac{1}{\sqrt n}$ 、 $h_n=\dfrac{2}{\sqrt n}$ ,這就說明第一個模型的窗寬小於第二個模型( $n$ 相同時,第二個模型的窗寬老是大於第一個模型的)。
下面就討論窗寬是如何影響估計效果的。
2、不一樣的窗寬對密度函數的估計效果產生的做用
設 $h_n=\dfrac{h_1}{\sqrt n}$ ,那麼經過改變參數 $h_1$ 就可得到窗寬不一樣的模型( $n$ 相同時這些模型有着不一樣的窗寬)。固然了,窗寬序列的獲取固然不是隻有這一種途徑,通常原則是當 $n$ 越大時 $h_n$ 越小。[1]中首先討論的是有限樣本的狀況,使用高斯窗函數,獲得的結果是:在樣本數有限的狀況下,太大的窗寬會是高方差的,欠擬合;過小的窗寬會是低方差的,過擬合;窗寬較大時,平滑程度較大。理論上的證實這裏就不贅述了(其實我也沒細看。。。),;收斂性也不細說了,在 $p_n(\textbf x)$ 收斂到一個值後,這個值是 $p(\textbf x)$ 被窗函數平滑的結果,$p_n(\textbf x)$ 的指望是 $p(\textbf x)$ 的平滑(卷積)。
[1]裏繼續用高斯窗函數的狀況下討論樣本數無窮時去估計機率密度(有單模的高斯密度,也有多模的混合密度),獲得的結果是:當樣本數無窮時,無論窗寬多大,最後總能準確地估計出真實機率密度。
下面這張圖就展現了真實密度是多模的狀況下,取不一樣窗寬(每一列表明一個模型,從左到右窗寬依次減少)時,樣本數從有限到無限(從上到下樣本數依次增大)的估計效果,能夠對照上面兩個結論來看這張圖。可以估計多模的密度,這正是非參數方法能夠作到而參數方法所作不到的。
圖片來源:[1]
3、Parzen窗估計以後的分類器
其實咱們搞了半天,又是參數方法又是非參數方法的,最後的目的無非都是爲了獲得一個泛化性能好的分類器。對於Parzen窗估計來講,窗函數決定了決策區域。
上面的討論已經明確指出來Parzen窗估計的優缺點:優勢是通用性,無需假設數據分佈,即便真實密度函數是多模的,也可使用;缺點就是若是準確估計窗函數,須要大量的樣本,比參數方法所須要的樣本要多得多,這帶來很大的存儲和計算開銷。目前,尚未有效的方法能夠下降在知足準確估計的狀況下所須要的樣本數。
k近鄰估計經過改變包含相一樣本數所須要的區域大小來得到估計序列。假設給定 $n$ 時,近鄰個數 $k_n$ 是肯定的(例如,令 $k_n=k_1\sqrt n$ ) ,從而在這時須要的 $V_n$ 是恰好能夠「包進」 $k_n$ 個樣本的大小,而後即可利用估計序列 $p_n(\textbf x)=\frac{k_n/n}{V_n}$ 來估計機率密度函數。咱們但願的是當 $n$ 趨向無窮時,$k_n$ 也趨向無窮;而 $k_n$ 的增加又儘量慢,使 $V_n$ 能逐漸趨向於0。
k近鄰估計中,估計效果取決於近鄰數。
下圖是我寫程序畫的[1]上的圖(注意兩張圖的縱軸標度不同),代表了一維狀況下,有限個樣本點的k近鄰估計取不一樣的近鄰數時的估計結果(圖中的樣本數爲8)。畫的是 $n=8$ 時(恰好等於樣本數)的狀況,這裏直接取的 $k_n=3$ 和 $k_n=5$(通常來講 $k_n$ 應該是 $n$ 的函數,這裏爲了簡單起見直接取了兩個不一樣的值) ,因爲是一維,因此對於任一一點 $x$ ,其局部區域 $V_n$ 就是恰好包進 $k_n$ 個樣本時這 $k_n$ 個樣本兩兩間距的最大值除以2。例如對於 $k_n=3$ 的情形,考慮特徵空間中的點 $x=5$ ,因爲須要包進3個樣本,因此這個點的 $V_n$ 是左起第二個樣本到第四個樣本之間,$V_n$ 大小爲第二個樣本和第四個樣本的距離的一半。
可見當近鄰數較大時,平滑程度較大,這和Parzen窗估計中的窗寬較大時的效果是相似的。
與Parzen窗估計相同的是,當樣本量無窮時,k近鄰估計能夠準確地估計出真實機率密度,這裏就不貼圖啦。
將上述的k近鄰估計用於分類,因此須要根據密度的估計值求取後驗機率的估計值。根據貝葉斯公式,後驗等於似然乘先驗除以證據,
$$P_n(\omega_i|\textbf x)=\frac{p_n(\textbf x|\omega_i)P_n(\omega_i)}{\sum_{j=1}^cp_n(\textbf x|\omega_j)P_n(\omega_j)}=\frac{p_n(\textbf x,\omega_i)}{\sum_{j=1}^cp_n(\textbf x,\omega_j)}$$
由於 $p_n(\textbf x,\omega_i)=\frac{k_i/n}{V}$ ,若是再記 $k=\sum_{j=1}^ck_j$ ,那麼有
$$P_n(\omega_i|\textbf x)=\dfrac{k_i}{k}$$
由此引出了k近鄰分類器。
k近鄰分類器直接估計後驗機率,所以屬於判別式模型,是一種沒有顯式訓練過程的「懶惰學習(lazy learning)」算法,它既能夠用來分類也能夠用來回歸:給定一個測試樣本,從訓練樣本里找出與之最類似的k個(類似度能夠用歐氏距離、餘弦類似度等)訓練樣本做爲近鄰,而後投票。能夠是直接投票,也能夠用類似度做爲權重因子來加權投票。分類的話就是近鄰里出現次數最多的類別做爲該測試樣本的類別,或者用類似度加權;迴歸的話就是近鄰的值取平均值,或者用類似度加權。
能夠看出該算法的開銷很是大。有一些數據結構用來對近鄰的計算過程加速,如kd樹(k-d tree)等,能夠參考 [2] 以及數據結構相關書籍。
用不到10行Python就能夠實現一個最簡單的kNN(距離計算要用開源包,因此這個說法略標題黨哈:) )在MNIST數據集上作了點小實驗(數據沒有作預處理,就是原始的784維特徵,0到255的像素值),結果以下表:
能夠看出在這個數據集上,餘弦類似度比歐氏距離效果稍好但沒好太多;並且當近鄰個數太少時不能爲判別提供太多信息,而近鄰個數太多時則又引入了噪聲而不利於判別。
此外,一個比較有意思的結論是:最近鄰分類器(k=1)的錯誤率不超過貝葉斯最優分類器的兩倍;當k趨於無窮時k近鄰分類器成爲最優分類器。
再強調一下,貝葉斯分類器是最優分類器的前提是密度函數能夠被準確地估計。實際上這很難作到。
附上sklearn庫中對近鄰算法的介紹:1.6. Nearest Neighbors
參考資料:
[1] 《模式分類》及slides
[2] 《統計學習方法》