2017年2月25日 星期六

機器學習(7)--利用核主成分分析(Kernel PCA)處理非線性對應


    在這之前所探討的輸入數據都是假設為可線性分離的,如果輸入數據不是線性可分離的,實務上的數據往往是這樣,那麼標準PCA,所設計的線性轉換技術就不是最好的選擇,在本節介紹核PCA(kernel PCA),它與核支援向量機(kernel SVM)類似,利用核技巧來將非線性分離的數據轉換到一個新的特徵子空間,而轉換之後便可以做線性分離。


核函數與核技巧:

    類似核SVM的作法,透過核函數與核技巧,將原始數據投影到更高維的新特徵空間,而在新特徵空間,數據類別是可以線性分離的。要轉換d維空間的樣本到更高維的k維空間,我們需要定義一個非線性對應函數Φ:
    如下方式,原本數據X有兩個特徵行向量,為2維d=2。利用函數Φ可以對應到3維空間k=3。
       

    整體上來說就是,透過核PCA,我們執行一個非線性對應函數將數據轉換到一個更高維的空間,並在這個高維的空間,使用標準PCA,再將數據投影回到一個較低維度的子空間,在這個低維度的子空間中,樣本即可使用線性分類器來分離。
    這個方法的缺點是非常耗費計算資源,因此我們可以使用核技巧,使用核技巧,我們可以計算兩個由原始的特徵空間所產生的高維特徵向量之間的相似度。
    套用之前標準PCA的推導(此略),我們可以定義一核矩陣(相似度矩陣)K:
核函數k則可以替代原本需使用的非線性對應函數Φ:
    這樣我們就不用去計算原本需由非線性對應函數Φ去處理的樣本中兩兩數據點的內積(公式右側),因此核函數也可以理解為,一個計算兩個向量內積的函數,也就是計算相似度的函數。而不像標準PCA,會建立一個轉換矩陣,經過核PCA處理之後,所得到的是已經投影完成的樣本。
 
    在此我們使用的核函數為RBF(Radial Basis Function Kernel):
實作一個「RBF核」(Radial Basis Function Kernel)PCA,我們可以定義如下的三個步驟:



2017年2月23日 星期四

機器學習(6)--主成分分析(Principal component analysis,PCA)



    這一篇介紹主成分分析(Principal component analysis,PCA),是一種特徵提取的技術,利用特徵降維來避免因維度災難所造成的過度適合(Overfitting)現象。就是說假如訓練資料集裡有很多個特徵數據,我們可以利用主成分分析(Principal component analysis,PCA)來選取最有影響的幾個特徵來做分類器模型的訓練而不需要使用所有的特徵數據來做訓練。
    在這個範例裡,我們將使用葡萄酒數據集來做示範,把原本有的13個特徵,利用PCA分析後只找出兩個主要的特徵值作為分類器模型分類的特徵依據。

    PCA著眼在高維度的數據,"最大化變異數"並投影到與原數據及相同維數或較低維數的"新特徵子空間"。新特徵子空間的正交軸即是"主成分"。

<圖一>x1,x2軸維原本的,PC1,PC2為主成分




2017年2月18日 星期六

機器學習(5)--邏輯斯迴歸,過度適合與正規化( Logistic regression,overfitting and regularization)


  本節介紹邏輯斯迴歸模型(Logistic regression)過度適合(overfitting)正規化(regularization)。邏輯斯迴歸模型(Logistic regression)能處裡線性和二元分類的問題,要注意的是這裡所要說的邏輯斯迴歸模型(Logistic regression)是分類模型而無關於"迴歸"。

邏輯斯迴歸模型(Logistic regression):

首先來看一下邏輯斯迴歸模型(Logistic regression),如下圖跟前一章所介紹的
適應線性神經元模型類似,但是其所使用的啟動函數不同,成本函數也不同。

<圖一>邏輯斯迴歸模型(Logistic regression)


2017年2月15日 星期三

機器學習(4)--資料標準常態化與隨機梯度下降法( standardization & Stochastic Gradient descent)


    這篇承接上一篇適應線性神經元與梯度下降法,講述隨機梯度下降法(Stochastic Gradient descent,簡稱SGD)與資料標準常態化(standardization)
    有關適應線性神經元與梯度下降法可先閱讀底下連結:
機器學習(3)--適應線性神經元與梯度下降法(Adaline neuron and Gradient descent)

首先資料標準常態化(standardization)是一種特徵縮放方法,標準化後,特徵值會滿足標準常態分佈,並且每個平均值都是0,標準差都是1。例如,若要標準化樣本x第j個特徵,只要將樣本減去平均值μ,再除以標準差σ,就完成了,計算方式如下:

可以簡單的使用Numpy的mean與std方法便可快速,簡單的完成標準化工作,程式如下:
X_std[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
X_std[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()
print("標準化特徵值0:X_std[:, 0]",X_std[:, 0] )
print("標準化特徵值1:X_std[:, 1]",X_std[:, 1] )

結果如下圖一:特徵值0及特徵值1分別是上一篇所使用鳶尾花的花萼長及花瓣長。原本的資料單位為公分,可以看出原始資料比1.0或0.0大很多,而標準化後的資料皆在正負0~2之間,以直觀的數學來說這會比原本的資料容易做訓練及運算。因此資料在做過標準常態化的特徵縮放後可以獲得較佳的效能。

<圖一>未標準化與標準化後的資料


下圖二是使用上一節適應線性神經元與梯度下降法做資料標準化後的收斂速度比較,在上半
圖為標準化後的資料,學習速率設定為0.01在15輪的迭代後,成本即收斂至最佳化,而在下
圖為資料未標準化,學習速率設定為0.0001,需要150輪迭代後,成本才收斂至最佳化,為
何學習速率設定不也設定在0.01呢?因這個例子來講當資料未標準化,將學習速率設定為0.01,會發現成本函數無法收斂至最佳化也就是上一節所說的,當學習速率過大時會衝過全域最小值而無法收斂。故資料標準化後配合適當的學習速率便可得到好的訓練效能。


<圖二>未標準化與標準化後訓練資料收斂的速度比較




2017年2月14日 星期二

機器學習(3)--適應線性神經元與梯度下降法(Adaline neuron and Gradient descent)

        這一節要介紹另一種類型的單層神經網路:適應線性神經元(Adaline)。並以梯度下降法
(Gradient descent)最小化成本函數。適應線性神經元(Adaline)在實務上是非常吸引人的,因為它清楚的說明了如何定義"成本函數",以及如何最小化"成本函數"的觀念,奠定了機器學習的理論基礎。在本文中主要還要介紹幾個機器學習或是深度學習裡都會出現的名詞,包括梯度下降法(Gradient descent)批次(batch)學習速率啟動函數(activation function)、以及偏誤(bias),在文末會以Python實作適應線性神經元(Adaline)。


     適應線性神經元(Adaline)可以算是Rosenblatt感知器改進方法,Adaline規則(也稱Widrow-Hoff規則)與Rosenblatt感知器之間最主要的差異在於,權重更新是基於"線性啟動函數"(Linear activation function),不像感知器是使用"單位階梯函數"(unit step function),在Adaline規則中它的線性啟動函數Φ(z)就是淨輸入,因此
並使用單位階梯函數量化器(quantizer)來預測類別標籤。可看以下圖示:
比較下圖差異,Adaline使用連續值的線性啟動函數來計算誤差及更新權重,而不是用它來預測二元類別標籤。

<圖一>適應線性神經元(Adaline)


2017年2月10日 星期五

演算法(2)--使用Numpy.bincount來實作簡單的桶子排序法



        會注意到Numpy.bincount()這個函數,其實是在閱讀機器學習的程式碼裡常常出現。常用來
處理類別標籤的向量。它是內建在Python Numpy裡。原文的解釋其實有點難懂,故我把我的心得
記下來,發現它原始設計的概念就是類似桶子排序法的基本概念,是一個很有趣的函數,所以也
特別用它實作一簡單的桶子排序。

理解Numpy.bincount()
numpy.bincount(x, weights=None, minlength=None)

 1.假設輸入X=[0,1,2,2,3,4,4],那麼產生bins(桶子)的數量為該X最大值4
 再加1=5,於是我們產生了5個bins(桶子)的排序編號為indx0~indx4,
 可以視為一向量[indx0,indx1,indx2,indx3,indx4]

 2.接著來看如何放原本的資料到這5的桶子(bins,分別indx0~indx4)
 原本的輸入X=[0,1,2,2,3,4,4]裡有"一個"資料0,表示要放到indx0桶子的只有一個
 故indx0=1。
 接著,原本的輸入X=[0,1,2,2,3,4,4]裡有"一個"資料,表示要放到indx1桶子的只有
 一個,故indx1=1。
 接著,原本的輸入X=[0,1,2,2,3,4,4]裡有"兩個"資料,表示要放到indx2桶子的有
 兩個,故indx1=2。
    依序放完所以桶子,indx3及 indx4桶子,可以得到indx3=1,indx4=2
    故得到輸出結果為[1,1,2,1,2]即:[indx0=1,indx1=1,indx2=2,indx3=1,indx4=2]
 使用Python語言程式如下:
   EX1:
 import numpy as np
 X=[0,1,2,2,3,4,4]
 print(np.bincount(X))
   結果是:[1,1,2,1,2]

  EX2:
   import numpy as np
 X=[0,5,3,2,3,1,4,2,4]
 print(np.bincount(X))
 結果是:[1,1,2,2,2,1]

  注意:輸入的X數值不可以為負,否則報錯
 若有實數值,實際測試會被無條件捨去後當整數使用