Python实现感知机(PLA)算法


Posted in Python onDecember 20, 2017

我们主要讲解一下利用Python实现感知机算法。

算法一

首选,我们利用Python,按照上一节介绍的感知机算法基本思想,实现感知算法的原始形式和对偶形式。

#利用Python实现感知机算法的原始形式
# -*- encoding:utf-8 -*-

"""
Created on 2017.6.7

@author: Ada
"""

import numpy as np
import matplotlib.pyplot as plt

#1、创建数据集
def createdata():
 samples=np.array([[3,-3],[4,-3],[1,1],[1,2]])
 labels=[-1,-1,1,1]
 return samples,labels

#训练感知机模型
class Perceptron:
 def __init__(self,x,y,a=1):
  self.x=x
  self.y=y
  self.w=np.zeros((x.shape[1],1))#初始化权重,w1,w2均为0
  self.b=0
  self.a=1#学习率
  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:#如果是一个误分类实例点
     print '误分类点为:',self.x[i,:],'此时的w和b为:',self.w,self.b
     count+=1
     self.update(self.y[i],self.x[i,:])
   if count==0:
    print '最终训练得到的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当做两个坐标轴,把x1当做自变量,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()

实验结果:

    误分类点为: [ 3 -3] 此时的w和b为: [[ 0.]
                                     [ 0.]] 0
    误分类点为: [1 1] 此时的w和b为: [[-3.]
                                    [ 3.]] -1
    最终训练得到的w和b为: [[-2.]
                         [ 4.]] 0

Python实现感知机(PLA)算法

#利用Python实现感知机算法的对偶形式
# -*- encoding:utf-8 -*-

"""
Created on 2017.6.7

@author: Ada
"""

import numpy as np
import matplotlib.pyplot as plt

#1、创建数据集
def createdata():
 samples=np.array([[3,-3],[4,-3],[1,1],[1,2]])
 labels=np.array([-1,-1,1,1])
 return samples,labels

#训练感知机模型
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#学习率
  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:#如果是一个误分类实例点
     print '误分类点为:',self.x[i,:],'此时的w和b为:',self.cal_w(),',',self.b
     count+=1
     self.update(i)
   if count==0:
    print '最终训练得到的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()

实验结果:

误分类点为: [ 3 -3] 此时的w和b为: [[ 0.  0.]] , 0
最终训练得到的w和b为: [[-5.  9.]] , -1

Python实现感知机(PLA)算法

通过以上实验结果可以看出,两种方法的结果是不同的,一方面,是由于两种优化方法不同;二是,因为在选择实例点的顺序上有关系。但是无论用哪种方法,都可以找到一条直线,把数据完全分开。实际上,就算使用同一算法,如果改变初始值w0,b0,或者改变选择实例点的顺序,也可以使得结果不同。

算法二

Python的机器学习包sklearn中也包含了感知机学习算法,我们可以直接调用,因为感知机算法属于线性模型,所以从sklearn.linear_model中import下面给出例子。

# -*- encoding:utf-8 -*-

"""
利用sklearn中的感知机学习算法进行实验
Created on 2017.6.7

@author: Ada
"""

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Perceptron

#创建数据,直接定义数据列表
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):
 #定义感知机
 clf=Perceptron(fit_intercept=True,n_iter=30,shuffle=False)
 #训练感知机
 clf.fit(samples,labels)
 #得到权重矩阵
 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 '最终训练得到的w和b为:',weights,',',bias
 Picture=Picture(samples,weights,bias)
 Picture.Show()

实验结果:

    最终训练得到的w和b为: [[-2.  4.]] , [ 0.]

Python实现感知机(PLA)算法

算法三

利用sklearn包中的感知器算法,并进行测试与评估

# -*- encoding:utf-8 -*-
'''
利用sklearn中的的Perceptron进行实验,并进行测试
'''
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
#利用算法进行创建数据集
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:生成样本的数量

 #n_features=2:生成样本的特征数,特征数=n_informative() + n_redundant + n_repeated

 #n_informative:多信息特征的个数

 #n_redundant:冗余信息,informative特征的随机线性组合

 #n_clusters_per_class :某一个类别是由几个cluster构成的

 make_calssification默认生成二分类的样本,上面的代码中,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_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]

 #定义感知机
 clf=Perceptron(fit_intercept=True,n_iter=50,shuffle=False)
 # 使用训练数据进行训练
 clf.fit(x_train,y_train)
 #得到训练结果,权重矩阵
 weights=clf.coef_
 #得到截距
 bias=clf.intercept_

 #到此时,我们已经得到了训练出的感知机模型参数,下面用测试数据对其进行验证
 acc=clf.score(x_test,y_test)#Returns the mean accuracy on the given test data and labels.
 print '平均精确度为:%.2f'%(acc*100.0)

 #最后,我们将结果用图像显示出来,直观的看一下感知机的结果
 #画出正例和反例的散点图
 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()

实验结果为:平均精确度为:96.00

Python实现感知机(PLA)算法

通过算法三和算法四可以看出,直接调用开源包里面的算法还是比较简单的,思路是通用的。

算法四

我们利用sklearn包中的感知机算法进行分类算法的实现。

# -*- encoding:utf-8 -*-
import numpy as np


'''
以scikit-learn 中的perceptron为例介绍分类算法

应用及其学习分类算法的五个步骤
(1)选择特征
(2)选择一个性能指标
(3)选择一个分类器和一个优化算法
(4)评价模型的性能
(5)优化算法

以scikit-learn 中的perceptron为例介绍分类算法
1 读取数据-iris
2 分配训练集和测试集
3 标准化特征值
4 训练感知器模型
5 用训练好的模型进行预测
6 计算性能指标
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

#训练数据和测试数据分为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)

#标准化数据
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并进行训练
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 '错误分类数:%d'%(y_test!=y_pred).sum()

from sklearn.metrics import accuracy_score
print '准确率为:%.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):
 #设置标记点和颜色
 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:
  # 绘制所有数据点
  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()

实验结果为:错误分类数:4;准确率为:0.91

Python实现感知机(PLA)算法

<完>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python编写的com组件发生R6034错误的原因与解决办法
Apr 01 Python
从Python的源码浅要剖析Python的内存管理
Apr 16 Python
python实现复制整个目录的方法
May 12 Python
Python3搜索及替换文件中文本的方法
May 22 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
Dec 15 Python
Python实现感知机(PLA)算法
Dec 20 Python
Python中实现变量赋值传递时的引用和拷贝方法
Apr 29 Python
python导入pandas具体步骤方法
Jun 23 Python
python for和else语句趣谈
Jul 02 Python
Kears+Opencv实现简单人脸识别
Aug 28 Python
Python爬取腾讯视频评论的思路详解
Dec 19 Python
python 双循环遍历list 变量判断代码
May 04 Python
详解Python nose单元测试框架的安装与使用
Dec 20 #Python
使用python实现knn算法
Dec 20 #Python
python实现kNN算法
Dec 20 #Python
解析Python中的eval()、exec()及其相关函数
Dec 20 #Python
详解Python中 sys.argv[]的用法简明解释
Dec 20 #Python
简单了解Django模板的使用
Dec 20 #Python
python机器学习之决策树分类详解
Dec 20 #Python
You might like
咖啡历史、消费和行业趋势
2021/03/03 咖啡文化
php中对2个数组相加的函数
2011/06/24 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
PHP PDOStatement::fetchColumn讲解
2019/01/31 PHP
由prototype_1.3.1进入javascript殿堂-类的初探
2006/11/06 Javascript
利用jq让你的div居中的好方法分享
2013/11/21 Javascript
JavaScript获取客户端计算机硬件及系统等信息的方法
2014/01/02 Javascript
JavaScript的事件代理和委托实例分析
2015/03/25 Javascript
微信小程序实战之仿android fragment可滑动底部导航栏(4)
2020/04/16 Javascript
AngularJS实现注册表单验证功能
2017/10/16 Javascript
Vue组件化开发之通用型弹出框的实现
2020/02/28 Javascript
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
2021/02/24 Javascript
[01:03:56]Mineski vs TNC 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
一个计算身份证号码校验位的Python小程序
2014/08/15 Python
使用httplib模块来制作Python下HTTP客户端的方法
2015/06/19 Python
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
python实现感知器
2017/12/19 Python
Python+selenium实现自动循环扔QQ邮箱漂流瓶
2018/05/29 Python
python3 对list中每个元素进行处理的方法
2018/06/29 Python
python函数的万能参数传参详解
2019/07/26 Python
python代码xml转txt实例
2020/03/10 Python
Tensorflow tf.nn.atrous_conv2d如何实现空洞卷积的
2020/04/20 Python
浅谈Python中文件夹和python package包的区别
2020/06/01 Python
python在地图上画比例的实例详解
2020/11/13 Python
俄罗斯Sportmarket体育在线商店:用于旅游和户外活动
2019/11/12 全球购物
ktv总经理岗位职责
2014/02/17 职场文书
大学生暑期实践感言
2014/02/26 职场文书
财务部总监岗位职责
2014/03/12 职场文书
购房协议书
2014/04/11 职场文书
差生评语大全
2014/05/04 职场文书
干部对照检查材料范文
2014/08/26 职场文书
交警正风肃纪剖析材料
2014/10/29 职场文书
新闻发布会新闻稿
2015/07/17 职场文书
python实现腾讯滑块验证码识别
2021/04/27 Python
go设置多个GOPATH的方式
2021/05/05 Golang
Centos环境下Postgresql 安装配置及环境变量配置技巧
2021/05/18 PostgreSQL