什么是感知機
感知機(preceptron)是線性分類的二分類模型,輸入為實例的特征向量,輸出為實例的類別,分別用 1 和 -1 表示。感知機將輸入空間(特征空間)中的實例劃分為正負兩類分離的超平面,旨在求出將訓練集進行線性劃分的超平面,為此,導入基于誤分類的損失函數(shù),利用梯度下降法對損失函數(shù)進行極小化,求得最優(yōu)解。感知機是神經(jīng)網(wǎng)絡(luò)和支持向量機的基礎(chǔ)。
感知機模型
感知機的函數(shù)公式為:
其中, w和 b 為感知機模型參數(shù),叫做權(quán)值或者權(quán)值向量,
叫做偏差,
表示 w 和 x 的內(nèi)積, sign 是符號函數(shù),即:
感知機的假設(shè)空間是定義在特征空間中所有線性分類模型的函數(shù)集合,即.
感知機的幾何解釋:線性方程對應特征空間
中的一個超平面 S,其中 w 是超平面的法向量,b 是超平面的截距。該超平面將特征空間分為兩個部分,將特征向量分為正負兩類。因此,超平面 S 成為分離超平面。

感知機學習策略
假設(shè)訓練數(shù)據(jù)集是線性可分的,感知機的學習目標就是找到能夠?qū)⒄搶嵗c完全分開的超平面,即確定感知機模型參數(shù) w 和 b,因此就是確定(經(jīng)驗)損失函數(shù)并求損失函數(shù)的最優(yōu)解,即最小化。
感知機 學習的損失函數(shù) 定義為:
下面給出推導:
1.首先寫入輸入空間中任意點
到超平面 S 的距離:
其中,是 w 的 L2 范數(shù)。
2.當時,
, 而當
時,
。因此,對于誤分類的數(shù)據(jù)
來說,
成立。
3.另外,誤差分類點到超平面 S 的距離是
設(shè) M 為超平面 S 的誤分類點的集合,則所有誤分類點到超平面 S 的總距離為:
不考慮,則得到感知機的損失函數(shù) L(w, b),即公式(1)
顯然,損失函數(shù) L(w, b)是非負的。如果有所分類都正確,則損失函數(shù)值為 0。而且,分類越正確,則誤分類的點離超平面越近,損失函數(shù)值越小。
因此,一個特定的樣本的損失函數(shù),在誤分類時時參數(shù) w, b 的線性函數(shù),正確分類時時 0,可以得出給定訓練數(shù)據(jù)集 T,損失函數(shù) L(w, b)是 w,b 的連續(xù)可導函數(shù)。
感知機學習算法
下面我們來看感知機的學習算法。給定一個訓練數(shù)據(jù)集
感知機的算法是誤分類驅(qū)動的,具體采用 隨機梯度下降法(stochastic gradient descent). 在極小化目標函數(shù)的過程中,并不是一次使 M 中所有誤分類的點梯度下降,而是每次隨機一個誤分類的點使其梯度下降。
具體步驟為:
1.假設(shè)誤分類點的集合為 M,那么損失函數(shù)L(w, b)的梯度為:
2.隨機選取一個誤分類的點,對 w, b 更新:
式中是步長,又稱為學習率(learning_rate),這樣,通過迭代可以使損失函數(shù)不斷減小,直到為 0.
當訓練數(shù)據(jù)集線性可分的時候,感知機學習算法是收斂的,并且存在無窮多個解,解會由于不同的初值或不同的迭代順序不同而有所不同。
實戰(zhàn)
下面使用 sklearn 包中感知機來訓練和分類 Iris(鳶尾花) 數(shù)據(jù)集。
from sklearn import datasets
import pandas as pd
from sklearn import Perceptron
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.utils import shuffle
iris = datasets.load_iris()
先導入數(shù)據(jù),然后使用shuffle打亂數(shù)據(jù)順序,
X, y = shuffle(iris.data, iris.target,random_state=7)
接下來分割訓練集和測試集:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)
然后進行樣本特征的標準化縮放,為了讓特征同步變化。標準化縮放就是將樣本特征轉(zhuǎn)化成均值為 0 ,方差為 1 的正態(tài)分布。
sc_X = StandardScaler()
X_train_std = sc_X.fit_transform(X_train)
X_test_std = sc_X.fit_transform(X_test)
創(chuàng)建感知機模型,進行訓練,最終對測試集預測結(jié)果。
model = Perceptron()
model.fit(X_train_std, y_train)
y_pred = model.predict(X_test_std)
訓練完成以后評價一下訓練結(jié)果,
print ("Accuracy score on test data: {:.4f}".format(accuracy_score(y_test, y_pred)))
print ("F-score on test data: {:.4f}".format(fbeta_score(y_test, y_pred, beta = 0.5,average='weighted')))
結(jié)果如下:

效果不太好,我們嘗試用網(wǎng)格搜索法來優(yōu)化一下,設(shè)置好參數(shù)集,代碼如下:
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.metrics import fbeta_score, accuracy_score
clf = Perceptron(random_state=7)
parameters = {'eta0':[0.1,1,10], 'max_iter':[30,40,50]}
scorer = make_scorer(fbeta_score, beta=0.5, average='weighted')
#在分類器上使用網(wǎng)格搜索,使用'scorer'作為評價函數(shù)
grid_obj = GridSearchCV(clf, parameters, scoring=scorer)
grid_obj.fit(X_train_std, y_train)
# 得到estimator
best_clf = grid_obj.best_estimator_
# 使用沒有調(diào)優(yōu)的模型做預測
predictions = (clf.fit(X_train_std, y_train)).predict(X_test_std)
best_predictions = best_clf.predict(X_test_std)
最后我們將優(yōu)化前和優(yōu)化后的結(jié)果打印出來比較一下效果:
# 匯報調(diào)參前和調(diào)參后的分數(shù)
print ("\nUnoptimized model\n------")
print ("Accuracy score on test data: {:.4f}".format(accuracy_score(y_test, predictions)))
print ("F-score on test data: {:.4f}".format(fbeta_score(y_test, predictions, beta = 0.5,average='weighted')))
print ("\nOptimized Model\n------")
print ("Final accuracy score on the test data: {:.4f}".format(accuracy_score(y_test, best_predictions)))
print ("Final F-score on the test data: {:.4f}".format(fbeta_score(y_test, best_predictions, beta = 0.5,average='weighted')))
運行一下,得到下圖:

最終可以看到,我們的模型預測效果已經(jīng)有明顯進步了。
如果你喜歡我的文章,歡迎掃碼關(guān)注公眾號:機器學習Club.聚焦機器學習,關(guān)注自我管理。
[圖片上傳失敗...(image-d73933-1534854404075)]