感知机(perceptron)代码实现

(书面内容参考《统计学习方法》李航)

感知机(perceptron)是二分类的线性模型,旨在求出将训练数据进行线性划分的分离超平面。

感知机模型:

        假设输入空间(特征空间)是x⊆Rn,输出空间是y=\left \{ -1,+1\right \}输入x∊x表示实例的特征向量,对应于输入空间(特征空间)的点;输出y∊y表示实例的类别。

由输入空间到输出空间的如下函数:

f(x) = sign\left ( w\cdot x+b \right )

称为感知机。

其中,w和b为感知机模型参数,w∊Rn叫作权值(weight)或权值向量(weight vector),b∊R叫作偏置(bias),w·x表示w和x的内积。

sign是符号函数,即

sign\left ( x \right ) = \left\{ \begin{aligned} +1 & , & x\geqslant 0 \\ -1 & , & x< 0 \\ \end{aligned} \right.

感知机是一种线性分类模型,属于判别模型。

感知机模型的假设空间是定义在特征空间中的所有线性分类模型(linear classification model)或线性分类器(linear classifier),即函数集合\left \{ f|f(x) = w\cdot x+b \right \}

感知机有如下几何解释:线性方程w\cdot x+b = 0

对应于特征空间Rn中的一个超平面S,其中w是超平面的法向量,b是超平面的截距。

这个超平面将特征空间划分为两个部分。位于两部分的点(特征向量)分别被分为正、负两类。

因此,超平面S称为分离超平面(separating hyperplane)

 

  

(图片来自《统计学习方法》) 

代码实现:

# -*- coding: UTF-8 -*-

# 导入iris数据集
from sklearn.datasets import load_iris
# 导入数据划分包
from sklearn.model_selection import train_test_split
# 导入感知机模型包
from sklearn.linear_model import Perceptron
# 导入基本函数库
import matplotlib.pyplot as plt 
import pandas as pd
import numpy as np

# 定义样本数量
global Sample_num 
Sample_num = 100

iris = load_iris()

## 取出iris的标签
iris_target = iris.target

iris_features = pd.DataFrame(iris.data, columns=iris.feature_names)
## 将标签并入数组
iris_features['target'] = iris_target
iris_features.columns=['sepal length', 'sepal width', 'petal length', 'petal width', 'label']

# 取出样本集,使用前两个特征
x = np.array(iris_features.iloc[:Sample_num,0:2])
y = iris_target[:Sample_num]

# 切分数据集,70%训练集,30%测试集
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.3)

# 定义感知机
pla = Perceptron(
    fit_intercept=False, # 不计算偏置
    shuffle = False # 在每个epoch重新打乱洗牌
)
# 模型训练
pla.fit(x_train,y_train)
# 输出权重和偏差
w = pla.coef_
b = pla.intercept_
print(f"权重(w) = {w}\n偏差(b) = {b}")

# 模型测试
result = pla.score(x_test,y_test)
print(f"测试结果准确率为:{result}")

#—————————————————————————— 画图——————————————————————————————
# 分开正例反例
# 正例横坐标
positive_x = [x[i,0] for i in range(Sample_num) if y[i] == 1]
# 正例纵坐标
positive_y = [x[i,1] for i in range(Sample_num) if y[i] == 1]
# 反例横坐标
negetive_x = [x[i,0] for i in range(Sample_num) if y[i] == 0]
# 反例纵坐标
negetive_y = [x[i,1] for i in range(Sample_num) if y[i] == 0]

# 画出散点图
plt.scatter(positive_x,positive_y,c='r')
plt.scatter(negetive_x,negetive_y,c='b')

# 画出超平面
line_x = np.arange(4,8)
# w[0][0]x+w[0][1]y+b=0 => 斜率:-w[0][0]/w[0][1]) 截距:-b/w[0][1]
line_y = line_x*(-w[0][0]/w[0][1])-b/w[0][1]
plt.plot(line_x,line_y)
plt.show()

结果:  

 

权重(w) = [[ 20.  -36.9]]
偏差(b) = [0.]
测试结果准确率为:0.9666666666666667

 

权重(w) = [[  7.9 -13.2]]
偏差(b) = [0.]
测试结果准确率为:0.9666666666666667

 

 

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值