统计学习方法第二章:感知机(Perceptron)

本文介绍了感知机的基本概念,包括模型设定、随机梯度下降算法,以及如何在Python的sklearn库中使用Perceptron模型对Iris数据集进行分类。通过实例展示了如何设置实验数据集、调整模型参数和观察分离结果。
摘要由CSDN通过智能技术生成

目录

感知机的基本知识点:

代码分析:

实验数据集的设置

 感知机模型的设定:

分离结果: 

运用scikit-learn Perceptron :

 分离结果:


工大菜凯,希望通过做笔记记录自己学的知识,也希望能帮助到同样在入门的同学 ❥侵权立删~

感知机的基本知识点:

注:实例点(x_{i},y_{i})更新的次数越多,意味着它距离分离超平面越近,也就越难分类。(对学习的结果影响最大)

若(x_{i},y_{i})实例点更新了n_{i}次,\Delta w=n_{i}\eta y_{i}x_{i}\Delta b=n_{i}\eta y_{i}

w的变换过程如:

w=w_{0}+n_{1}\eta y_{1} x_{1}+n_{2}\eta y_{2} x_{2}+n_{3}\eta y_{3} x_{3}.....+n_{i}\eta y_{i} x_{i}  其中:w_{0}的初始值 w_{0}=0 

其中a_{i}=a_{i}+\eta 等价于w=w+\eta y_{i} x_{i}

感知机的模型函数:𝑓(𝑥)=𝑠𝑖𝑔𝑛(𝑤∗𝑥+𝑏)

损失函数 𝐿(𝑤,𝑏)=−Σ𝑦𝑖(𝑤∗𝑥𝑖+𝑏)

算法:随机梯度下降法,随机抽取一个误分类点使其梯度下降。

           w=w+\eta y_{i} x_{i} 、b=b+\eta y_{i}

当实例点被误分类,即位于分离超平面的错误侧,则调整w,b,使分离超平面向该误分类点的一侧移动,直至误分类点被正确分类。

代码分析:

  拿出iris数据集中两个分类的数据和[sepal length,sepal width]作为特征

实验数据集的设置

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris # 利用python自带的数据库
import matplotlib.pyplot as plt
# Iris 数据集是机器学习任务中常用的分类实验数据集
# Iris 数据集一共包含150个样本,分成3类,每类50个数据(样本),每个数据(样本)包含4个特征
sklearn.datasets.load_iris()  sklearn中的小数据集

4个特征分别为: Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、Petal.Width(花瓣宽度),根据4个特征预测鸢尾花属于 Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾)

# load data
iris = load_iris()
# 通过iris.data可以获得数据集中的样本特征 
# 通过iris.target可以获得每个样本对应的标签信息(目标变量)
# pd.DataFrame 将iris数据集中的样本特征存储在名为df的pandas的数据框中,每列的名称对应于iris数据集# 中的特征名称
df = pd.DataFrame(iris.data, columns=iris.feature_names)
# 将数据集中的标签信息(目标变量)添加到数据框df中,将标签信息赋给一个名为label的新列,这样df数据框就# 包含了每个样本的标签信息
df['label'] = iris.target
#最终得到一个pandas数据框df,其中每一行代表一个样本,每一列代表一个特征,最后一列是样本的标签


# 设置df数据框的每一列的特征标签
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
# 对样本标签进行统计
df.label.value_counts()
 sklearn中导入的数据框为150*5的矩阵
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()
画出前50个样本花瓣长度、宽度(标签为0)和50-100的样本花瓣长度、宽度(标签为1)
# iloc函数表示对数据进行位置索引,从而在数据表中提出相应的数据
# 将df数据框中的前100行数据的第0列、1列、最后一列的数据提取出来,并将其转化为numpy数组存储在data变# 量中
data = np.array(df.iloc[:100, [0, 1, -1]])
# data[:,:-1] 提取data中除了最后一列,所有列的数据  
# data[:,-1] 只提取data数组的最后一列数据
# X代表两个特征 y代表标签变量
X, y = data[:,:-1], data[:,-1]

# 因为原本的y是分为0 1两个标签值的
# 为了对感知机更好的进行试验 我们将y的值进行了调整 将原本0 1 两个标签值 变换成 -1 1两个标签值
y = np.array([1 if i == 1 else -1 for i in y])

 感知机模型的设定:

# 数据线性可分,二分类数据
# 此处为一元一次线性方程
class Model:
    def __init__(self):
        # 感知机模型初始化操作
        # len(data[0] 即取出第一行的元素个数
        # 取数据集的列数(因为数据集的最后一列是标签列 所以我们需要-1处理) 
        # 创建一个长度与特征维度相匹配的全部为1的浮点数组作为初始权重向量,也就是参数w向量
        self.w = np.ones(len(data[0])-1, dtype=np.float32)
        self.b = 0
        self.l_rate = 0.1
        # self.data = data
    
    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:  
    # 因为is_wrong的初始值是False 所以直到is_wrong = True 才结束循环也就是没有误分类点出现
            wrong_count = 0  # 记录每次迭代中误分类的样本数量
            for d in range(len(X_train)): # 遍历整个训练数据集
                X = X_train[d]  # 样本特征向量X
                y = y_train[d]  # 样本标签y
                if y * self.sign(X, self.w, self.b) <= 0:  # <0 就表示该样本点为误分类点
                    self.w = self.w + self.l_rate*np.dot(y, X)
                    self.b = self.b + self.l_rate*y
                    wrong_count += 1
    # 当该次循环误分类点 ==0 没有出现误分类点,则将is_wrong设置为True 结束参数w和b的迭代更新
            if wrong_count == 0:  
                is_wrong = True

        return 'Perceptron Model!'   # 训练完成的提示
        
    def score(self):
        pass
perceptron = Model()
# 运行感知机模型,利用随机梯度下降法对参数进行优化 使得最后没有误分类点出现
perceptron.fit(X, y)

# 生成一个等间距的横坐标点x_points,范围是从4到7,共10个点
x_points = np.linspace(4, 7,10)
# 分离超平面 第二个变量的计算 w1*x1+w2*x2+b=0  
y_ = -(perceptron.w[0]*x_points + perceptron.b)/perceptron.w[1]
# 画出分离超平面  也就是分类线
plt.plot(x_points, y_)
# 画出标签为0的样本点(横轴一个特征 纵轴一个特征 组成一个样本点)
plt.plot(data[:50, 0], data[:50, 1], 'o', color='blue', label='0')
# 画出标签为1的样本点
plt.plot(data[50:100, 0], data[50:100, 1], 'o', color='orange', label='1')

plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()

分离结果: 

感知机模型得出的分离超平面的分离效果

运用scikit-learn Perceptron :

from sklearn.linear_model import Perceptron  # 从sklearn中引入感知机函数
# 创建一个感知机对象clf
# 参数fit_intercept:偏置项 决定分类线的位置 max_iter:最大的迭代次数 shuffle:打乱输入数据的顺序
clf = Perceptron(fit_intercept=True, max_iter=1000, shuffle=True)
# 给定训练数据X和对应的标签y对感知机模型进行训练
# X 是一个二维数组,表示训练样本的特征。每一行代表一个样本的特征向量,每一列代表不同的样本的不同特征
# y 是一个一维数组,表示训练样本的标签。
clf.fit(X, y)

# Weights assigned to the features.
# 返回一个数组,其中存储这感知机模型训练后得到的权重系数,数组中的每一个元素对应一个特征
print(clf.coef_)
# 截距b Constants in decision function.
print(clf.intercept_)

x_points = np.linspace(4, 7,10)
# 对权值参数w的取值w1:clf.coef_[0][0]、wclf.coef_[0][1]
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], 'o', color='blue', label='0')
plt.plot(data[50:100, 0], data[50:100, 1], 'o', color='orange', label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()

 分离结果:

sklearn 中含偏置项 乱序数据输入 迭代次数为1000的感知机模型的分离结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工大凯K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值