第二節--感知機

第二節–感知機

感知機(perceptron)是二類分類的線性分類模型,其輸入爲實例的特徵向量,輸出爲實例的類別,取+1和-1二值.感知機對應於輸入空間(特徵空間)中將實例劃分爲正負兩類的分離超平面,屬於判別模型.感知機學習旨在求出將訓練數據進行線性劃分的分離超平面,爲此,導入基於誤分類的損失函數,利用梯度降低法對損失函數進行極小化,求得感知機模型.感知機學習算法具備簡單而易於實現的優勢,分爲原始形式和對偶形式.感知機預測是用學習獲得的感知機模型對新的輸入實例進行分類html


一.感知機模型

假設輸入空間(特徵空間)是image.png,輸出空間是image.png,輸入image.png表示實例的特徵變量,對應於輸入空間(特徵空間)的點;輸出image.png表示實例的類別.由輸入空間到輸出空間的以下函數:

image.pngpython

稱爲感知機.其中,w和b爲感知機模型函數,image.png叫做權值(weight)或權值向量(weight vector),image.png叫做偏置(bias)image.png表示w和x的內積,sign是符號函數,即:

image.pngweb

感知機是一種線性分類模型,屬於判別模型.感知機模型的假設空間時定義在特徵空間(linear classification model)或線性分類器(linear classifier),即函數集合image.png算法

感知機有以下幾何解釋,線性方程:

image.png

對應於特徵空間image.png中的一個超平面S,其中w是超平面的法向量,b是超平面的截距.這個超平面將特徵空間劃分爲兩個部分.位於兩部分的點(特徵向量)分爲正,負兩類.所以.超平面S稱爲分離超平面(separating hyperplane):app

from IPython.display import Image
Image(filename="./data/2_1.png",width=500)

output_8_0.png

感知機學習,由訓練數據集(實例的特徵向量機類別):

image.pngdom

其中,image.png,求得感知機模型.即求得模型參數w,b.感知機預測,經過學習獲得的感知機模型.對於新的輸入實例給出其對應的輸出示例svg


二.感知機學習策略


1.數據集的線性可分性

給定一個數據集:

image.png函數

其中image.png,若是存在某個超平面S:

image.png學習

可以將數據集的正實例點和負實例點徹底正確地劃分到超平面的兩側,即對全部 y i = + 1 y_{i}=+1 的實例i,有 w x i + b > 0 w \cdot x_{i}+b>0 ,多全部 y i = 1 y_{i}=-1 的實例i,有 w x i + b < 0 w \cdot x_{i}+b<0 ,則稱數據集T爲線性可分數據集(linearly separable data set);不然,稱數據集T線性不可分優化


2.感知機學習策略

假設訓練數據集是線性可分的,感知機學習的目標是求得一個可以將訓練集正實例點和負實例點徹底正確分開的分離超平面.爲了找出這樣的超平面.即肯定感知機模型參數w,b,須要肯定一個學習策略.即定義損失函數並將損失函數最小化

損失函數的一個目標選擇是誤分類點的總數.可是這樣的損失函數不是參數w,b的連續可導函數.損失函數的另外一個選擇是誤分類點到超平面S的總距離,這是感知機所採用的.爲此首先輸入空間image.png中任一點image.png到超平面S的距離

image.png

對於誤分類的數據image.png來講:

image.png

image.png時,image.png.而當image.png時,image.png.所以誤分類點image.png到超平面S的距離是:

image.png假設超平面S的誤分類點集合爲M,那麼全部誤分類點到超平面S的總距離爲:

image.png

不考慮image.png,就獲得感知機學習的損失函數

給定訓練數據集:

image.png

其中image.png,感知機image.png學習的損失函數定義爲:

image.png

其中M爲誤分類點的集合,這個損失函數就是感知機學習的經驗風險函數

顯然,損失函數L(w, b)是非負的,若是沒有誤分類點,損失函數值是0.並且誤分類點越少,誤分類點離超平面越近,損失函數值就越小.一個特定的樣本點的損失函數,在誤分類時是參數w,b的線性函數,在正確分類時是0.所以給定訓練數據集T,損失函數L(w, b)是w,b的連續可導函數


三.感知機學習算法

感知機學習問題轉化爲求解損失函數的最優化問題,最優化的方法是隨機梯度降低法.具體方法包括原始形式和對偶形式,並證實在訓練數據線性可分條件下感知機學習算法的收斂性


1.感知機學習算法的原始形式

感知機學習算法是對如下最優化問題的算法,給定一個訓練數據集:

image.png

其中,image.png,求參數w,b使其爲如下損失函數極小化問題的解:

image.png

其中M爲誤分類點的集合

感知機學習算法是誤分類驅動的,具體採用隨機梯度降低法(stochastic gradient descent).首先任意選取一個超平面image.png,而後用梯度降低法不斷地極小化目標函數.極小化過程不是一次使M中全部誤分類點的梯度降低,而是一次隨機選取一個2誤分類點使其梯度降低

假設誤分類集合M是固定的,那麼損失函數image.png的梯度由:

image.png

image.png

隨機選取一個誤分類點image.png,對w,b進行更新:

image.png

image.png

式中image.png是步長,在統計學習中又稱爲學習率(learning rate).經過迭代能夠期待損失函數image.png不斷減少,直到爲0.綜上所述,獲得以下算法:

感知機學習算法的原始形式

輸入:訓練數據集image.png,其中image.png, 學習率image.png

輸出:w,b;感知機模型image.png

  1. 選取初值image.png
  2. 在訓練集中選取數據image.png
  3. 若是image.png

    image.png

image.png

  1. 轉至2,直至訓練集中沒有誤分類點

這種學習算法直觀上有以下解釋:當一個實例點被誤分類,即位於分離超平面的錯誤一側時,則調整w,b的值,使分離超平面向該誤分類點的一側移動,以減小該誤分類點與超平面間的距離.直至超平面越過該誤分類點使其被正確分類

實例1:以下數據集,其正實例點是image.pngimage.png.試用感知機學習算法的原始形式求感知機模型image.png.這裏image.png

from IPython.display import Image
Image(filename="./data/3_1.png",width=500)

output_32_0.png

解:構建最優化問題

image.png

求解w,b,image.png

  1. 取初值image.png
  2. image.png,未能被正確分類,更新w,b

    image.png

    獲得線性模型:image.png
  3. image.png,顯然image.png被正確分類,不修改w,b;對image.png被誤分類,更新w,b

    image.png

如此繼續下去,直到:

image.png

image.png

對全部數據點image.png,沒有誤分類點,損失函數達到極小

分離超平面爲:image.png

感知機模型爲:image.png

Image(filename="./data/2_3.png")

output_35_0.png

Image(filename="./data/2_4.png")

output_36_0.png

迭代次數 誤分類點 w b w.x+b
0 0 0 0 0
1 x1 (3,3) 1 3x1+3x2+1
2 x3 (2,2) 0 2x1+2x2
3 x3 (1,1) -1 x1+x2-1
4 x3 (0,0) -2 -2
5 x1 (3,3) -1 3x1+3x2-1
6 x3 (2,2) -2 3x1+3x2-2
7 x3 (1,1) -3 x1+x2-2
8 x1 (1,1) -3 x1+x2-3

這是在計算中誤分類點前後取image.png獲得的分離超平面和感知機模型.若是在計算中誤分類點依次取image.png,那麼獲得的分離超平面是$2 image.png

可見,感知機學習算法因爲採用不一樣的初值或選取不一樣的誤分類點,解能夠不一樣


2.算法的收斂性

對於線性可分數據集感知學習算法原始形式收斂,即通過有限次迭代能夠獲得一個將訓練數據集徹底正確劃分的分離超平面及感知機模型

誤分類的次數k是有上界的,通過有限次搜索能夠找到將訓練集數據徹底正確分開的分離超平面


3.感知機學習算法的對偶形式

對偶形式的基本想法是,將w和b表示爲實例x_和標記y_的線性組合的形式.經過求解其係數而求得w和b,不失通常性.在原始形式的算法中可假設初始值image.png均爲0,對誤分類點image.png經過:

image.png

image.png

逐步修改w,b,設修改n次,則w,b關於image.png的增量分別是image.pngimage.png,這裏image.png.這樣學習過程不難看出最後學習到的w,b能夠分別表示爲:

image.png

image.png

這裏,image.png,當image.png時,表示第i個實例點因爲誤分而進行更新的次數,實例點更新次數越多,意味着它距離分離超平面越近,也就越難正確分類,換句話說,這樣的實例對學習結果影響最大

感知機學習算法的對偶形式

輸入:線性可分的數據集image.png,其中image.png學習率image.png

輸出:a,b;感知機模型image.png

其中image.png

  1. image.png

  2. 在訓練集中選取數據image.png

  3. 若是
    image.png

image.png

image.png

image.png

  1. 轉置2,直到沒有誤分類數據

對偶形式中訓練實例僅之內積的形式出現,爲了方便,能夠預先將訓練集中實例間的內積計算出來並以矩陣的形式存儲,這個存儲就是所謂的Gram矩陣(Gram matrix)

image.png

實例2:正樣本點是image.png負樣本點是image.png,試用感知機學習算法對偶形式求感知機模型

解:

  1. image.png
  2. 計算Gram矩陣

    image.png
  3. 誤分條件

    image.png

    參數更新

    image.png
  4. 迭代,過程以下圖
  5. image.pngimage.png

    分離超平面:image.png

    感知機模型:image.png

與原始形式同樣,感知機學習算法的對偶形式迭代是收斂的,存在多個解


四.感知機實現

當實例點被誤分類,即位於分離超平面的錯誤側,則調整w,b的值,使分離超平面向該無分類點的一側移動,直至誤分類點被正確分類

拿出iris數據集中兩個分類的數據和[speal length,speal width]做爲特徵


1.自定義感知機

%matplotlib inline
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
# load iris
iris=load_iris()
df=pd.DataFrame(iris.data,columns=iris.feature_names)
df["label"]=iris.target
df.columns=["sepal length","sepal width","petal length","petal width","label"]
df.label.value_counts()
2    50
1    50
0    50
Name: label, dtype: int64
plt.scatter(df[:50]["sepal length"],df[:50]["sepal width"],label="0")
plt.scatter(df[50:100]["sepal length"],df[50:100]["sepal width"],label="1")
plt.xlabel("sepal length")
plt.ylabel("sepal width")
plt.legend()
<matplotlib.legend.Legend at 0x25ffdd3b6a0>

output_57_1.png

data=np.array(df.iloc[:100,[0,1,-1]])
X,y=data[:,:-1],data[:,-1]
y=np.array([1 if i==1 else -1 for i in y])
# 數據線性可分,二分類數據
# 此處爲一元一次線性方程
class Model(object):
    def __init__(self):
        self.w=np.ones(len(data[0])-1,dtype=np.float32)
        self.b=0
        self.l_rate=0.1
        
    def sign(self,x,w,b):
        y=np.dot(x,w)+b
        return y
    
    # 隨機梯度降低法
    def fit(self,X_train,y_train):
        is_wrong=False
        while not is_wrong:
            wrong_count=0
            for d in range(len(X_train)):
                X=X_train[d]
                y=y_train[d]
                if y*self.sign(X,self.w,self.b)<=0:
                    self.w=self.w+self.l_rate*np.dot(y,X)
                    self.b=self.b+self.l_rate*y
                    wrong_count+=1
            if wrong_count==0:
                is_wrong=True
        return "Perceptron Model!"
    
    def score(self):
        pass
perceptron=Model()
perceptron.fit(X,y)
'Perceptron Model!'
x_points=np.linspace(4,7,10)
y_=-(perceptron.w[0]*x_points+perceptron.b)/perceptron.w[1]
plt.plot(x_points,y_)

plt.plot(data[:50,0],data[:50,1],"bo",color="blue",label="o")
plt.plot(data[50:100,0],data[50:100,1],"bo",color="orange",label="l")
plt.xlabel("sepal length")
plt.ylabel("sepal width")
plt.legend()
<matplotlib.legend.Legend at 0x25fff517fd0>

output_63_1.png


2.sklearn Perceptron

from sklearn.linear_model import Perceptron

clf=Perceptron(fit_intercept=False,max_iter=1000,shuffle=False)
clf.fit(X,y)
E:\Anaconda\envs\mytensorflow\lib\site-packages\sklearn\linear_model\stochastic_gradient.py:183: FutureWarning: max_iter and tol parameters have been added in Perceptron in 0.19. If max_iter is set but tol is left unset, the default value for tol in 0.19 and 0.20 will be None (which is equivalent to -infinity, so it has no effect) but will change in 0.21 to 1e-3. Specify tol to silence this warning.
  FutureWarning)





Perceptron(alpha=0.0001, class_weight=None, early_stopping=False, eta0=1.0,
      fit_intercept=False, max_iter=1000, n_iter=None, n_iter_no_change=5,
      n_jobs=None, penalty=None, random_state=0, shuffle=False, tol=None,
      validation_fraction=0.1, verbose=0, warm_start=False)
# weight assigned to the features
print(clf.coef_)
[[  74.6 -127.2]]
print(clf.intercept_)
[0.]
x_ponits = np.arange(4, 8)
y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]
plt.plot(x_ponits, y_)

plt.plot(data[:50, 0], data[:50, 1], 'bo', color='blue', label='0')
plt.plot(data[50:100, 0], data[50:100, 1], 'bo', color='orange', label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
<matplotlib.legend.Legend at 0x25fff8b8a90>

output_68_1.png

相關文章
相關標籤/搜索