Python實(shí)現(xiàn)感知機(jī)(PLA)算法
我們主要講解一下利用Python實(shí)現(xiàn)感知機(jī)算法。
算法一
首選,我們利用Python,按照上一節(jié)介紹的感知機(jī)算法基本思想,實(shí)現(xiàn)感知算法的原始形式和對(duì)偶形式。
#利用Python實(shí)現(xiàn)感知機(jī)算法的原始形式
# -*- encoding:utf-8 -*-
"""
Created on 2017.6.7
@author: Ada
"""
import numpy as np
import matplotlib.pyplot as plt
#1、創(chuàng)建數(shù)據(jù)集
def createdata():
samples=np.array([[3,-3],[4,-3],[1,1],[1,2]])
labels=[-1,-1,1,1]
return samples,labels
#訓(xùn)練感知機(jī)模型
class Perceptron:
def __init__(self,x,y,a=1):
self.x=x
self.y=y
self.w=np.zeros((x.shape[1],1))#初始化權(quán)重,w1,w2均為0
self.b=0
self.a=1#學(xué)習(xí)率
self.numsamples=self.x.shape[0]
self.numfeatures=self.x.shape[1]
def sign(self,w,b,x):
y=np.dot(x,w)+b
return int(y)
def update(self,label_i,data_i):
tmp=label_i*self.a*data_i
tmp=tmp.reshape(self.w.shape)
#更新w和b
self.w=tmp+self.w
self.b=self.b+label_i*self.a
def train(self):
isFind=False
while not isFind:
count=0
for i in range(self.numsamples):
tmpY=self.sign(self.w,self.b,self.x[i,:])
if tmpY*self.y[i]<=0:#如果是一個(gè)誤分類實(shí)例點(diǎn)
print '誤分類點(diǎn)為:',self.x[i,:],'此時(shí)的w和b為:',self.w,self.b
count+=1
self.update(self.y[i],self.x[i,:])
if count==0:
print '最終訓(xùn)練得到的w和b為:',self.w,self.b
isFind=True
return self.w,self.b
#畫圖描繪
class Picture:
def __init__(self,data,w,b):
self.b=b
self.w=w
plt.figure(1)
plt.title('Perceptron Learning Algorithm',size=14)
plt.xlabel('x0-axis',size=14)
plt.ylabel('x1-axis',size=14)
xData=np.linspace(0,5,100)
yData=self.expression(xData)
plt.plot(xData,yData,color='r',label='sample data')
plt.scatter(data[0][0],data[0][1],s=50)
plt.scatter(data[1][0],data[1][1],s=50)
plt.scatter(data[2][0],data[2][1],s=50,marker='x')
plt.scatter(data[3][0],data[3][1],s=50,marker='x')
plt.savefig('2d.png',dpi=75)
def expression(self,x):
y=(-self.b-self.w[0]*x)/self.w[1]#注意在此,把x0,x1當(dāng)做兩個(gè)坐標(biāo)軸,把x1當(dāng)做自變量,x2為因變量
return y
def Show(self):
plt.show()
if __name__ == '__main__':
samples,labels=createdata()
myperceptron=Perceptron(x=samples,y=labels)
weights,bias=myperceptron.train()
Picture=Picture(samples,weights,bias)
Picture.Show()
實(shí)驗(yàn)結(jié)果:
誤分類點(diǎn)為: [ 3 -3] 此時(shí)的w和b為: [[ 0.]
[ 0.]] 0
誤分類點(diǎn)為: [1 1] 此時(shí)的w和b為: [[-3.]
[ 3.]] -1
最終訓(xùn)練得到的w和b為: [[-2.]
[ 4.]] 0

#利用Python實(shí)現(xiàn)感知機(jī)算法的對(duì)偶形式
# -*- encoding:utf-8 -*-
"""
Created on 2017.6.7
@author: Ada
"""
import numpy as np
import matplotlib.pyplot as plt
#1、創(chuàng)建數(shù)據(jù)集
def createdata():
samples=np.array([[3,-3],[4,-3],[1,1],[1,2]])
labels=np.array([-1,-1,1,1])
return samples,labels
#訓(xùn)練感知機(jī)模型
class Perceptron:
def __init__(self,x,y,a=1):
self.x=x
self.y=y
self.w=np.zeros((1,x.shape[0]))
self.b=0
self.a=1#學(xué)習(xí)率
self.numsamples=self.x.shape[0]
self.numfeatures=self.x.shape[1]
self.gMatrix=self.cal_gram(self.x)
def cal_gram(self,x):
gMatrix=np.zeros((self.numsamples,self.numsamples))
for i in xrange(self.numsamples):
for j in xrange(self.numsamples):
gMatrix[i][j]=np.dot(self.x[i,:],self.x[j,:])
return gMatrix
def sign(self,w,b,key):
y=np.dot(w*self.y,self.gMatrix[:,key])+b
return int(y)
def update(self,i):
self.w[i,]=self.w[i,]+self.a
self.b=self.b+self.y[i]*self.a
def cal_w(self):
w=np.dot(self.w*self.y,self.x)
return w
def train(self):
isFind=False
while not isFind:
count=0
for i in range(self.numsamples):
tmpY=self.sign(self.w,self.b,i)
if tmpY*self.y[i]<=0:#如果是一個(gè)誤分類實(shí)例點(diǎn)
print '誤分類點(diǎn)為:',self.x[i,:],'此時(shí)的w和b為:',self.cal_w(),',',self.b
count+=1
self.update(i)
if count==0:
print '最終訓(xùn)練得到的w和b為:',self.cal_w(),',',self.b
isFind=True
weights=self.cal_w()
return weights,self.b
#畫圖描繪
class Picture:
def __init__(self,data,w,b):
self.b=b
self.w=w
plt.figure(1)
plt.title('Perceptron Learning Algorithm',size=14)
plt.xlabel('x0-axis',size=14)
plt.ylabel('x1-axis',size=14)
xData=np.linspace(0,5,100)
yData=self.expression(xData)
plt.plot(xData,yData,color='r',label='sample data')
plt.scatter(data[0][0],data[0][1],s=50)
plt.scatter(data[1][0],data[1][1],s=50)
plt.scatter(data[2][0],data[2][1],s=50,marker='x')
plt.scatter(data[3][0],data[3][1],s=50,marker='x')
plt.savefig('2d.png',dpi=75)
def expression(self,x):
y=(-self.b-self.w[:,0]*x)/self.w[:,1]
return y
def Show(self):
plt.show()
if __name__ == '__main__':
samples,labels=createdata()
myperceptron=Perceptron(x=samples,y=labels)
weights,bias=myperceptron.train()
Picture=Picture(samples,weights,bias)
Picture.Show()
實(shí)驗(yàn)結(jié)果:
誤分類點(diǎn)為: [ 3 -3] 此時(shí)的w和b為: [[ 0. 0.]] , 0
最終訓(xùn)練得到的w和b為: [[-5. 9.]] , -1

通過以上實(shí)驗(yàn)結(jié)果可以看出,兩種方法的結(jié)果是不同的,一方面,是由于兩種優(yōu)化方法不同;二是,因?yàn)樵谶x擇實(shí)例點(diǎn)的順序上有關(guān)系。但是無論用哪種方法,都可以找到一條直線,把數(shù)據(jù)完全分開。實(shí)際上,就算使用同一算法,如果改變初始值w0,b0,或者改變選擇實(shí)例點(diǎn)的順序,也可以使得結(jié)果不同。
算法二
Python的機(jī)器學(xué)習(xí)包sklearn中也包含了感知機(jī)學(xué)習(xí)算法,我們可以直接調(diào)用,因?yàn)楦兄獧C(jī)算法屬于線性模型,所以從sklearn.linear_model中import下面給出例子。
# -*- encoding:utf-8 -*-
"""
利用sklearn中的感知機(jī)學(xué)習(xí)算法進(jìn)行實(shí)驗(yàn)
Created on 2017.6.7
@author: Ada
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Perceptron
#創(chuàng)建數(shù)據(jù),直接定義數(shù)據(jù)列表
def creatdata1():
samples=np.array([[3,-3],[4,-3],[1,1],[1,2]])
labels=np.array([-1,-1,1,1])
return samples,labels
def MyPerceptron(samples,labels):
#定義感知機(jī)
clf=Perceptron(fit_intercept=True,n_iter=30,shuffle=False)
#訓(xùn)練感知機(jī)
clf.fit(samples,labels)
#得到權(quán)重矩陣
weigths=clf.coef_
#得到截距bisa
bias=clf.intercept_
return weigths,bias
#畫圖描繪
class Picture:
def __init__(self,data,w,b):
self.b=b
self.w=w
plt.figure(1)
plt.title('Perceptron Learning Algorithm',size=14)
plt.xlabel('x0-axis',size=14)
plt.ylabel('x1-axis',size=14)
xData=np.linspace(0,5,100)
yData=self.expression(xData)
plt.plot(xData,yData,color='r',label='sample data')
plt.scatter(data[0][0],data[0][1],s=50)
plt.scatter(data[1][0],data[1][1],s=50)
plt.scatter(data[2][0],data[2][1],s=50,marker='x')
plt.scatter(data[3][0],data[3][1],s=50,marker='x')
plt.savefig('3d.png',dpi=75)
def expression(self,x):
y=(-self.b-self.w[:,0]*x)/self.w[:,1]
return y
def Show(self):
plt.show()
if __name__ == '__main__':
samples,labels=creatdata1()
weights,bias=MyPerceptron(samples,labels)
print '最終訓(xùn)練得到的w和b為:',weights,',',bias
Picture=Picture(samples,weights,bias)
Picture.Show()
實(shí)驗(yàn)結(jié)果:
最終訓(xùn)練得到的w和b為: [[-2. 4.]] , [ 0.]

算法三
利用sklearn包中的感知器算法,并進(jìn)行測(cè)試與評(píng)估
# -*- encoding:utf-8 -*- ''' 利用sklearn中的的Perceptron進(jìn)行實(shí)驗(yàn),并進(jìn)行測(cè)試 ''' from sklearn.datasets import make_classification from sklearn.linear_model import Perceptron from sklearn.cross_validation import train_test_split from matplotlib import pyplot as plt import numpy as np #利用算法進(jìn)行創(chuàng)建數(shù)據(jù)集 def creatdata(): x,y = make_classification(n_samples=1000, n_features=2,n_redundant=0,n_informative=1,n_clusters_per_class=1) ''' #n_samples:生成樣本的數(shù)量 #n_features=2:生成樣本的特征數(shù),特征數(shù)=n_informative() + n_redundant + n_repeated #n_informative:多信息特征的個(gè)數(shù) #n_redundant:冗余信息,informative特征的隨機(jī)線性組合 #n_clusters_per_class :某一個(gè)類別是由幾個(gè)cluster構(gòu)成的 make_calssification默認(rèn)生成二分類的樣本,上面的代碼中,x代表生成的樣本空間(特征空間) y代表了生成的樣本類別,使用1和0分別表示正例和反例 y=[0 0 0 1 0 1 1 1... 1 0 0 1 1 0] ''' return x,y if __name__ == '__main__': x,y=creatdata() #將生成的樣本分為訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù),并將其中的正例和反例分開 x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0) #正例和反例 positive_x1=[x[i,0]for i in range(len(y)) if y[i]==1] positive_x2=[x[i,1]for i in range(len(y)) if y[i]==1] negetive_x1=[x[i,0]for i in range(len(y)) if y[i]==0] negetive_x2=[x[i,1]for i in range(len(y)) if y[i]==0] #定義感知機(jī) clf=Perceptron(fit_intercept=True,n_iter=50,shuffle=False) # 使用訓(xùn)練數(shù)據(jù)進(jìn)行訓(xùn)練 clf.fit(x_train,y_train) #得到訓(xùn)練結(jié)果,權(quán)重矩陣 weights=clf.coef_ #得到截距 bias=clf.intercept_ #到此時(shí),我們已經(jīng)得到了訓(xùn)練出的感知機(jī)模型參數(shù),下面用測(cè)試數(shù)據(jù)對(duì)其進(jìn)行驗(yàn)證 acc=clf.score(x_test,y_test)#Returns the mean accuracy on the given test data and labels. print '平均精確度為:%.2f'%(acc*100.0) #最后,我們將結(jié)果用圖像顯示出來,直觀的看一下感知機(jī)的結(jié)果 #畫出正例和反例的散點(diǎn)圖 plt.scatter(positive_x1,positive_x2,c='red') plt.scatter(negetive_x1,negetive_x2,c='blue') #畫出超平面(在本例中即是一條直線) line_x=np.arange(-4,4) line_y=line_x*(-weights[0][0]/weights[0][1])-bias plt.plot(line_x,line_y) plt.show()
實(shí)驗(yàn)結(jié)果為:平均精確度為:96.00

通過算法三和算法四可以看出,直接調(diào)用開源包里面的算法還是比較簡(jiǎn)單的,思路是通用的。
算法四
我們利用sklearn包中的感知機(jī)算法進(jìn)行分類算法的實(shí)現(xiàn)。
# -*- encoding:utf-8 -*-
import numpy as np
'''
以scikit-learn 中的perceptron為例介紹分類算法
應(yīng)用及其學(xué)習(xí)分類算法的五個(gè)步驟
(1)選擇特征
(2)選擇一個(gè)性能指標(biāo)
(3)選擇一個(gè)分類器和一個(gè)優(yōu)化算法
(4)評(píng)價(jià)模型的性能
(5)優(yōu)化算法
以scikit-learn 中的perceptron為例介紹分類算法
1 讀取數(shù)據(jù)-iris
2 分配訓(xùn)練集和測(cè)試集
3 標(biāo)準(zhǔn)化特征值
4 訓(xùn)練感知器模型
5 用訓(xùn)練好的模型進(jìn)行預(yù)測(cè)
6 計(jì)算性能指標(biāo)
7 描繪分類界面
'''
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
iris=datasets.load_iris()
X=iris.data[:,[2,3]]
y=iris.target
#訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)分為7:3
from sklearn.cross_validation import train_test_split
x_train,x_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=0)
#標(biāo)準(zhǔn)化數(shù)據(jù)
from sklearn.preprocessing import StandardScaler
sc=StandardScaler()
sc.fit(x_train)
x_train_std=sc.transform(x_train)
x_test_std=sc.transform(x_test)
#引入skleran 的Perceptron并進(jìn)行訓(xùn)練
from sklearn.linear_model import Perceptron
ppn=Perceptron(n_iter=40,eta0=0.01,random_state=0)
ppn.fit(x_train_std,y_train)
y_pred=ppn.predict(x_test_std)
print '錯(cuò)誤分類數(shù):%d'%(y_test!=y_pred).sum()
from sklearn.metrics import accuracy_score
print '準(zhǔn)確率為:%.2f'%accuracy_score(y_test,y_pred)
#繪制決策邊界
from matplotlib.colors import ListedColormap
import warnings
def versiontuple(v):
return tuple(map(int,(v.split('.'))))
def plot_decision_regions(X,y,classifier,test_idx=None,resolution=0.02):
#設(shè)置標(biāo)記點(diǎn)和顏色
markers=('s','x','o','^','v')
colors=('red','blue','lightgreen','gray','cyan')
cmap=ListedColormap(colors[:len(np.unique(y))])
# 繪制決策面
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
alpha=0.8, c=cmap(idx),
marker=markers[idx], label=cl)
if test_idx:
# 繪制所有數(shù)據(jù)點(diǎn)
if not versiontuple(np.__version__) >= versiontuple('1.9.0'):
X_test, y_test = X[list(test_idx), :], y[list(test_idx)]
warnings.warn('Please update to NumPy 1.9.0 or newer')
else:
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0], X_test[:, 1], c='',
alpha=1.0, linewidth=1, marker='o',
s=55, label='test set')
def plot_result():
X_combined_std = np.vstack((x_train_std, x_test_std))
y_combined = np.hstack((y_train, y_test))
plot_decision_regions(X=X_combined_std, y=y_combined,
classifier=ppn, test_idx=range(105,150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()
plot_result()
實(shí)驗(yàn)結(jié)果為:錯(cuò)誤分類數(shù):4;準(zhǔn)確率為:0.91

<完>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
巧用Python裝飾器 免去調(diào)用父類構(gòu)造函數(shù)的麻煩
巧用Python裝飾器 免去調(diào)用父類構(gòu)造函數(shù)的麻煩,需要的朋友可以參考下2012-05-05
Python?async+request與async+aiohttp實(shí)現(xiàn)異步網(wǎng)絡(luò)請(qǐng)求探索
這篇文章主要介紹了Python?async+request與async+aiohttp實(shí)現(xiàn)異步網(wǎng)絡(luò)請(qǐng)求探索,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10
Python實(shí)現(xiàn)將通信達(dá).day文件讀取為DataFrame
今天小編就為大家分享一篇Python實(shí)現(xiàn)將通信達(dá).day文件讀取為DataFrame,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12
python實(shí)現(xiàn)支付寶當(dāng)面付(掃碼支付)功能
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)支付寶當(dāng)面付,掃碼支付功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Python中requests.session()的用法小結(jié)
這篇文章主要介紹了Python中requests.session()的用法小結(jié),可能大家對(duì)?session?已經(jīng)比較熟悉了,也大概了解了session的機(jī)制和原理,但是我們?cè)谧雠老x時(shí)如何會(huì)運(yùn)用到session呢,接下來要講到會(huì)話保持,需要的朋友可以參考下2022-11-11
Pandas中DataFrame的分組/分割/合并的實(shí)現(xiàn)
這篇文章主要介紹了Pandas中DataFrame的分組/分割/合并的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07

