感知机算法在鸢尾花数据集上的实践

  • 1 问题背景
  • 2 数据集的微处理
  • 3 导数据,并进行简单可视化
  • 4 模型算法的训练部分


1 问题背景

感知机作为一个比较经典的处理线性二分类的算法,今天想着实践一下,并把最后的分类结果可视化出来,选用的数据集就选个比较简单的鸢尾花数据集好了。

2 数据集的微处理

鸢尾花数据集原本有150个样本,标签有3类,每类在样本上都拥有50个样例。这里我们就选用setosa和versicolor这两类中的100个样本作为我们进行感知机二分类的样本吧,然后为了可视化的方便性,就选择Length和Width这两个特征进行试验。主要用到的python库是pandas和plotly这两个库。

3 导数据,并进行简单可视化

这是鸢尾花数据集的网盘下载地址(csv格式) 代码如下

# 这是库
import pandas as pd
# 这是路径
fpath = "./iris.csv"
# 这是读数据
df_iris = pd.read_csv(fpath)
# 看一下前面几行的数据
df_iris.head()
# 简单处理下,留一组可视化能力强,符合题意的数据
df_iris = df_iris.loc[0:99, ['Sepal.Length', 'Sepal.Width', 'Species']] 
# 导入可视化的库
import plotly.express as px
# 先绘制散点图
fig = px.scatter(df_iris, x = 'Sepal.Length', y = 'Sepal.Width', color = 'Species')
fig.update_layout(
    title = 'data of iris',
    xaxis_title = 'Length',
    yaxis_title = 'Width'
)
fig.show()

一副简单的原数据的散点图就做好了,如下:

基于随机森林模型对鸢尾花数据集进行分类_人工智能

4 模型算法的训练部分

感知机这个算法也特别大众了,想看数学原理搜一搜就有了,我这里就不贴详细的科普了,只把和算法设计有关的部分贴出来,感知机的参数迭代过程靠如下伪代码进行:

decision_plane: wx + b = 0 
//标签预测
if(wx + b >0):	label_predict = 1
else:			label_predict = -1
//参数迭代, α为学习率
α = 0.001
if(label_predict != label_true):	w = w + label_true*α*x

好了,以上就是算法的参数迭代部分的核心思想,完整的代码如下:

# 先把label换成+1与-1
species_to_label = {
    'setosa' : 1,
    'versicolor' : -1
}
df_iris['label'] = df_iris['Species'].map(species_to_label)
# 开始做感知机算法部分, 我们设平面的表达形式为wx+b=0, 先初始化参数
import numpy as np
w = np.array([1.0, 1.0, 1.0]) # 三个参数:w1, w2, b
x = np.array([0.0, 0.0, 1.0]) # 自变量, 第三个参数不能动, Length, Width
a = 0.001 # 学习率先设为0.001,后面再调
# 开始算法的参数更新
for i in range(1000):
    x[0] = df_iris.loc[i%100, 'Sepal.Length']
    x[1] = df_iris.loc[i%100, 'Sepal.Width']
    label_predict = np.dot(w, x)
    if(label_predict > 0):
        label_predict = 1
    else:
        label_predict = -1
    if(label_predict != df_iris.loc[i%100, 'label']):
        w[0] = w[0] + df_iris.loc[i%100, 'label']*a*x[0]
        w[1] = w[1] + df_iris.loc[i%100, 'label']*a*x[1]
        w[2] = w[2] + df_iris.loc[i%100, 'label']*a
# 按Length为自变量x, 把y做出来
df_iris['x'] = df_iris['Sepal.Length']
df_iris['y'] = (-1*w[0]*df_iris['x'] - w[2])/w[1]
# 导库,准备绘制感知机决策面
import plotly.graph_objects as go
# 绘图
line = go.Scatter(x = df_iris['x'], y = df_iris['y'], name = 'decision_plane')
point_setosa = go.Scatter(x = df_iris.loc[df_iris['Species'] == 'setosa']['Sepal.Length'], y = df_iris.loc[df_iris['Species'] == 'setosa']['Sepal.Width'], mode = 'markers', name = 'setosa')
point_versicolor = go.Scatter(x = df_iris.loc[df_iris['Species'] == 'versicolor']['Sepal.Length'], y = df_iris.loc[df_iris['Species'] == 'versicolor']['Sepal.Width'], mode = 'markers', name = 'versicolor')
fig = go.Figure([line, point_setosa, point_versicolor])
fig.update_layout(
    title = 'data of iris',
    xaxis_title = 'Length',
    yaxis_title = 'Width'
)
fig.show()

最后可视化出来的算法结果如下图:

基于随机森林模型对鸢尾花数据集进行分类_python_02


效果不错,都分类对了

以上