初识机器学习——感知机(Perceptron)+ Python代码实现鸢尾花分类

文章目录

  • 1、感知机学习模型
    • 1.1 感知机定义
  • 2、感知机学习策略
    • 2.1 线性可分数据集
    • 2.2 感知机学习策略
  • 3、感知机学习算法
      • 3.1 求解梯度
      • 3.2 更新参数 w w w b b b
  • 4、利用感知机进行鸢尾花分类(Python)
      • 4.1 Python库引用以及鸢尾花数据集的导入及预处理
      • 4.2. 感知机模型类的定义、具体方法的代码实现
      • 4.3 感知机模型实现
      • 4.4 感知机分类结果可视化


1、感知机学习模型

1.1 感知机定义

  假设输入空间 χ ⊆ R n \chi\subseteq R^n χRn,输出空间为 γ = { + 1 , − 1 } \gamma=\left \{ +1,-1\right \} γ={+1,1} 。其中每一个输入 x ⊆ χ x\subseteq \chi xχ表示对应于实例的特征向量,也就是对应于输入空间(特征空间)的一个点, y ⊆ γ y\subseteq \gamma yγ输出表示实例的类别。从输入空间至输出空间的函数 f ( x ) f(x) f(x)称为感知机。此处 R n R^n Rn,代表着n维空间,如果是 X O Y XOY XOY 坐标轴平面,即n=2,以此类推。初学者对于后续概念可以根据二维平面进行理解。
f ( x ) = s i g n ( w ⋅ x + b ) f(x)=sign(w\cdot x+b) f(x)=sign(wx+b)
其中,权值向量 w w w与偏置 b b b为感知机的模型参数, s i g n ( ) sign() sign()为符号函数,如下
s i g n = { +1,  x ≥ 0 - 1,  x < 0 sign=\begin{cases} & \text{+1, } x\ge 0 \\ & \text{- 1, } x< 0 \end{cases} sign={+1, x0- 1, x<0
  感知机是二分类的线性模型,其输入是实例的特征向量,输出的是事例的类别,分别是正实例(+1)和负实例(-1),属于判别模型。


2、感知机学习策略

2.1 线性可分数据集

  已知给定数据 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x n , y n ) } T=\left \{(x_{1},y_{1}), (x_{2},y_{2}),\dots ,(x_{n},y_{n}) \right \} T={(x1,y1),(x2,y2),,(xn,yn)},其中 y i ∈ { + 1 , − 1 } y_i\in \left \{ +1,-1 \right \} yi{+1,1},如果存在一个超平面 S S S: w x + b = 0 wx+b=0 wx+b=0
初识机器学习——感知机(Perceptron)+ Python代码实现鸢尾花分类_第1张图片
  由图可知,对于所有 y i = + 1 y_i=+1 yi=+1,有 w i x + b > 0 w_ix+b>0 wix+b>0;对于所有 y i = − 1 y_i=-1 yi=1,有 w i x + b < 0 w_ix+b<0 wix+b<0,则称为数据 T T T 为线性可分数据集 ( L i n e a r l y s e p a r a b l e d a t a s e t ) (Linearly \quad separable \quad data set) (Linearlyseparabledataset)

2.2 感知机学习策略

  根据上述线性可分数据集的定义我们就可以得到 正确分类点错误分类点 所满足的条件,如下:
{ 正确分类点: y i ( w x + b ) > 0 错误分类点: − y i ( w x + b ) > 0 \left\{\begin{matrix} 正确分类点:&y_i(wx+b)>0\\ 错误分类点:&-y_i(wx+b)>0 \end{matrix}\right. {正确分类点:错误分类点:yi(wx+b)>0yi(wx+b)>0

  感知机学习的目标是求得一个能将训练集正点和负点完全分开的分离超平面,即也就是确定感知机模型参数 w w w b b b

  超平面:如果是n维空间,那么超平面就是n维空间里的n-1个子空间,如果是二维平面,那么超平面就是一条直线,因此超平面并不是一个狭义上的平面。

  如下图,二维平面的情况下,超平面所对应的即是 w x + b = 0 wx+b=0 wx+b=0 这条直线,该直线将正实例点与负实例点完全划分开,其中 w w w是直线的斜率, b b b是直线的截距,这两个参数是我们通过数据训练所得到的。
初识机器学习——感知机(Perceptron)+ Python代码实现鸢尾花分类_第2张图片

  故需要确定一个学习策略:定义损失函数并将损失函数极小化
  损失函数:一般选择是误分类点的总数,但这样的损失函数不是参数的连续可导函数,不易对其进行优化。
  :感知机所采用的损失函数是**误分类到超平面 S S S的总距离**

(1)首先写出输入空间中任一点到超平面 S S S的距离:
1 ∥ W ∥ ∣ w ⋅ x 0 + b ∣ \frac{1}{\left \| W \right \| } \left |w\cdot x_{0}+b \right | W1wx0+b
其中 ∥ W ∥ \left \| W \right \| W w w w的2范式,也是超平面法向量 w w w的模。

  此处如果对于超平面的定义不理解的话,暂时可以类比2维平面点到直线距离公式进行理解: 已知二维平面中的一条直线: A x + B y + C = 0 已知二维平面中的一条直线:Ax+By+C=0 已知二维平面中的一条直线:Ax+By+C=0
点到直线的距离为: ∣ A x + B y + C ∣ A 2 + B 2 \frac{\left | Ax+By+C \right | }{\sqrt{A^2+B^2} } A2+B2 Ax+By+C
上述的 ∥ W ∥ \left \| W \right \| W类似于二维平面中点到直线距离公式中的 A 2 + B 2 \sqrt{A^2+B^2} A2+B2

(2)错误分类点满足: − y i ( w x + b ) > 0 -y_i(wx+b)>0 yi(wx+b)>0
证明:
  由线性可分数据集的概念我们得知 正实例点满足 : y i = + 1 且 w x i + b > 0 正实例点满足: y_i=+1且wx_i+b>0 正实例点满足:yi=+1wxi+b>0 负实例点满足 : y i = − 1 且 w x i + b < 0 负实例点满足:y_i=-1且wx_i+b<0 负实例点满足:yi=1wxi+b<0  故错误分类点有两种情况: 情况 1 : y i = + 1 且 w x i + b < 0 = > − y i ( w x + b ) > 0 情况1:y_i=+1且wx_i+b<0=>-y_i(wx+b)>0 情况1yi=+1wxi+b<0=>yi(wx+b)>0 情况 2 : y i = − 1 且 w x i + b > 0 = > − y i ( w x + b ) > 0 情况2:y_i=-1且wx_i+b>0=>-y_i(wx+b)>0 情况2yi=1wxi+b>0=>yi(wx+b)>0
(3)得到错误分类点距离超平面的距离: ∣ − y i ( w ⋅ x 0 + b ) ∣ ∥ w ∥ = ∣ w ⋅ x 0 + b ∣ ∥ w ∥ \frac{\left | -y_i(w\cdot x_0+b) \right | }{\left \| w \right \| } =\frac{\left | w\cdot x_0+b \right | }{\left \| w \right \| } wyi(wx0+b)=wwx0+b

(4)假设超平面 S S S的误分类点集合为 M M M,则所有错误分类点到超平面 S S S的总距离为:
− 1 ∥ w ∥ ∑ x i ∈ M y i ( w ⋅ x i + b ) -\frac{1}{\left \| w \right \| } \sum_{x_i\in M}^{} y_i(w\cdot x_i+b) w1xiMyi(wxi+b)
(5)得到感知机学习的损失函数: L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) L(w,b)=- \sum_{x_i\in M}^{} y_i(w\cdot x_i+b) L(w,b)=xiMyi(wxi+b)
其中, M M M是错误分类点的集合。

最终得到感知机的学习策略为极小化损失函数:
m i n L ( w , b ) = − ∑ x i ∈ M y i ( w ⋅ x i + b ) minL(w,b)=- \sum_{x_i\in M}^{} y_i(w\cdot x_i+b) minL(w,b)=xiMyi(wxi+b)


3、感知机学习算法

  感知机的算法是通过错误分类驱动进行学习的,具体采用的是随机梯度下降法,在极小化目标函数的过程中,每次随机一个误分类点使其的梯度下降。
  具体步骤:
初识机器学习——感知机(Perceptron)+ Python代码实现鸢尾花分类_第3张图片

3.1 求解梯度

  求解梯度实际上是求损失函数求于某个参数的偏导

假设误分类点的集合为 M M M,则损失函数 L ( w , b ) L(w,b) L(w,b)的梯度为:
  对于 w w w 的梯度:
∇ w L ( w , b ) = − ∑ x i ∈ M y i x i \nabla _{w} L(w,b)=-\sum_{x_i\in M}^{}y_ix_i wL(w,b)=xiMyixi
  对于 b b b 的梯度:
∇ b L ( w , b ) = − ∑ x i ∈ M y i \nabla _{b} L(w,b)=-\sum_{x_i\in M}^{}y_i bL(w,b)=xiMyi

3.2 更新参数 w w w b b b

随机选取一个误分类的点,对 w w w b b b进行更新
w → w + η ∇ w w\to w+\eta \nabla _{w} ww+ηw b → b + η ∇ b b\to b+\eta \nabla _{b} bb+ηb
其中 η \eta η 为学习率。


4、利用感知机进行鸢尾花分类(Python)

4.1 Python库引用以及鸢尾花数据集的导入及预处理

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

#加载鸢尾花数据集
iris = load_iris()
#转换为DataFrame格式并设置列标签
df = pd.DataFrame(iris.data,columns=['sepal length', 'sepal width', 'petal length', 'petal width'])  
#为数据设置label,转化为二分类问题
df['label'] = iris.target 
# 提取前100条数据
data = np.array(df.iloc[0:100,[0,1,-1]])
# 得到x(特征向量)、y(分类标签)
x,y = data[:,:-1],data[:,-1]
# 将两类分类标签分别替换为1与-1,便于感知机处理
y=np.array([1 if i == 1 else -1 for i in y])

4.2. 感知机模型类的定义、具体方法的代码实现

class Model:
    def __init__(self):
        # 初始化权重,特征向量长度为2,故在初始化中故将其分别赋予1的权重
        self.w = np.ones(len(data[0])-1) 
        # 初始化偏置为0
        self.b = 0
        # 初始化学习率为0.1
        self.rate = 0.1
    
    # 定义sign函数,用于判断当前点是否分类正确
    def sign(self,x,w,b):
        y = np.dot(x,w) + b
        return y
    
    def fit(self,X_train,Y_train):
        Classfication_status = False # 用于判断当前点是否分类正确,默认不正确
        while not Classfication_status:
            wrong_count = 0 # 错误分类点计数器
            for i in range(len(X_train)): # 遍历每个点进行分类
                x = X_train[i]
                y = Y_train[i]
                if y*self.sign(x, self.w, self.b) <= 0:  # 错误分类点的判断条件
                   self.w = self.w + self.rate * np.dot(y,x) # 更新权重w
                   self.b = self.b + self.rate * y # 更新偏置b
                   wrong_count += 1 # 错误点计数器+1
            if wrong_count == 0: #当损失函数为0时,分类结束
                Classfication_status = True
        return self.w,self.b

4.3 感知机模型实现

# 实例化模型
perceptron = Model()
# 训练模型
w,b = perceptron.fit(x,y)

4.4 感知机分类结果可视化

x = np.linspace(4,7,10)
y_ = -(w[0]*x_points + b)/w[1]

# 绘制散点图
plt.scatter(x[:50,0],x[:50,1],label='0')
plt.scatter(x[50:,0],x[50:,1],label='1')
plt.plot(x_points,y_)
plt.xlabel("sepal length")
plt.ylabel("sepal width")
plt.legend()

得到经过分类后的结果图:
初识机器学习——感知机(Perceptron)+ Python代码实现鸢尾花分类_第4张图片

你可能感兴趣的:(机器学习,python,大数据,深度学习,数据分析)