Según el conjunto de datos del iris, el perceptrón se utiliza para implementar una clasificación binaria lineal.
Breve descripción del tema:
Según el conjunto de datos del iris (cuatro características, tres categorías), seleccione dos características y dos categorías, use el perceptrón Perceptron para implementar una clasificación binaria lineal, visualice los resultados de la clasificación y dibuje la relación entre el número de iteraciones y la tasa de precisión. Nota: El código implementa un análisis previo de datos y explica los motivos de la selección de dos características y dos categorías.
conjunto de datos del iris:
El enlace está aquí: Introducción al conjunto de datos del iris
Introducción al uso del código:
- Aquí muestra1 = 0, muestra2 = 1 significa que entre las cuatro características del iris, seleccioné la primera característica y la segunda característica, es decir, las características de longitud y ancho del sépalo en la imagen.
- Las cuatro características o tres categorías del iris son las siguientes
-
A continuación, ejecute el siguiente código y obtenga los siguientes resultados:
draw_relation(df,sample1,sample2)
Como se puede ver en la figura anterior, la Categoría 0 y la Categoría 1 son linealmente separables, y la Categoría 0 y la Categoría 2 son linealmente separables. A continuación, solo necesitamos seleccionar dos de las categorías separables para la clasificación. Aquí elijo Distinguir entre la Categoría 0. y categoría 1
-
Como distinguimos entre clase 0 y clase 1, configuro class1=0 y class2=1 en la función trains() para indicar la clase que quiero elegir. Después de ejecutar, obtienes los siguientes resultados:
trains(df,sample1,sample2,class1=0,class2=1,epoch=400)
Clasificar nuevamente:
-
En este momento, si necesita seleccionar otras características, como muestra1 = 1, muestra = 2, obtendrá los siguientes resultados después de ejecutar: Se puede ver que la categoría 0 y la categoría 1 son linealmente separables, y la categoría 0 y la categoría 2 son linealmente separables.
-
draw_relation(df,sample1,sample2)
-
-
Según los resultados anteriores, elegí clase1=0, clase2=2 para clasificarlos y obtuve los siguientes resultados:
-
trains(df,sample1,sample2,class1=0,class2=1,epoch=400)
-
El código se muestra a continuación:
import pandas as pd
import numpy as np
from pylab import *
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron
from sklearn.model_selection import train_test_split
# 通过图像的方式得到可分类的特征,默认为第0,1类特征
def draw_relation(df,sample1=0,sample2=1):
x = np.array(df.iloc[:, [sample1, sample2]])
y = np.array(df.iloc[:, -1])
lenth = len(x)
n11 = [x[i, 0] for i in range(lenth) if y[i] == 0]
n12 = [x[i, 1] for i in range(lenth) if y[i] == 0]
n21 = [x[i, 0] for i in range(lenth) if y[i] == 1]
n22 = [x[i, 1] for i in range(lenth) if y[i] == 1]
n31 = [x[i, 0] for i in range(lenth) if y[i] == 2]
n32 = [x[i, 1] for i in range(lenth) if y[i] == 2]
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 添加这条可以让图形显示中文
plt.figure()
plt.xlim(0, 8)
plt.ylim(0, 8)
plt.title(f"特征{sample1}和特征{sample2}的三个种类分布")
plt.xlabel(f'{df.columns[sample1]}')
plt.ylabel(f'{df.columns[sample2]}')
plt.scatter(n11, n12, label='0', c='r', marker='v')
plt.scatter(n21, n22, label='1', c='b', marker='x')
plt.scatter(n31, n32, label='2', c='g',marker='o')
plt.legend('012')
plt.show()
#对数据类别进行选择并训练
def trains(dfs,sample1=0,sample2=1,class1=0,class2=1,epoch=50):
data1 = np.array(df.iloc[50*class1:50*class1+50, [sample1, sample2, -1]])
data2 = np.array(df.iloc[50*class2:50*class2+50, [sample1, sample2, -1]])
#将选择的两个类的数据合并在一起
data = np.concatenate((data1, data2), axis = 0)
x, y = data[:, :-1], data[:, -1]
lenth = len(x)
# 将选择的两个类分为正例和反例
positive_x1 = [x[i, 0] for i in range(lenth) if y[i] == class1]
positive_x2 = [x[i, 1] for i in range(lenth) if y[i] == class1]
negetive_x1 = [x[i, 0] for i in range(lenth) if y[i] == class2]
negetive_x2 = [x[i, 1] for i in range(lenth) if y[i] == class2]
# 测试集和训练集都用所有的数据
x_data_train,y_data_train = x,y
x_data_test,y_data_test = x,y
# x_data_train, x_data_test, y_data_train, y_data_test = train_test_split(x, y, test_size=0.4,random_state=False)
# 用于存储损失结果
y_data = []
x_data = []
# 中文
mpl.rcParams['font.sans-serif'] = ['SimHei']
plt.figure()
# 将图表和颜色设定为与draw_relation()画出的图像一致
class_pic = ['v','x','o']
class_color = ['r','b','g']
for i in range(1, epoch, 5):
# 使用Perceptron进行训练
clf = Perceptron(fit_intercept=False, n_iter_no_change=i, shuffle=False)
# 使用训练数据进行训练
clf.fit(x_data_train, y_data_train)
# 得到训练结果
print("训练结果w:", clf.coef_) # w 参数
print("训练结果b:", clf.intercept_) # b 参数
# clf.n_iter_ #迭代次数
print("迭代次数:", clf.n_iter_)
# 使用测试集进行验证
acc = clf.score(x_data_test, y_data_test)
print("测试集评估:", acc)
x_data.append(i)
y_data.append(acc)
# 画出正例和反例的散点图
plt.cla()
plt.title(f"第{class1}类和{class2}类的超平面和散点图")
plt.xlabel(f'{df.columns[sample1]}')
plt.ylabel(f'{df.columns[sample2]}')
plt.xlim(0, 8)
plt.ylim(0, 8)
plt.scatter(positive_x1, positive_x2, c=class_color[class1],marker=class_pic[class1])
plt.scatter(negetive_x1, negetive_x2, c=class_color[class2],marker=class_pic[class2])
# 画出超平面(在本例中即是一条直线)
line_x = np.arange(2, 8)
line_y = line_x * (-clf.coef_[0][0] / clf.coef_[0][1]) - clf.intercept_ / clf.coef_[0][1]
plt.plot(line_x, line_y)
plt.legend(f'线{class1}{class2}')
plt.pause(0.005)
# 显示标签
plt.figure()
plt.plot(x_data, y_data, 'o-',color="g", alpha=0.8, linewidth=0.8)
plt.title("迭代次数与正确率", fontsize=10)
plt.xlabel('迭代次数')
plt.ylabel('正确率')
x_ticks = np.arange(0, 401, 50)
y_ticks = np.arange(0.5, 1.01, 0.05)
plt.xticks(x_ticks)
plt.yticks(y_ticks)
plt.show()
if __name__ == '__main__':
#加载鸢尾花数据集
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names) # iris.data包含一个(150, 4)的数据,设置列名为iris.feature_names
df['label'] = iris.target # iris.target为类别标签(150, 1)
#此处sample1=0,sample2=1表示鸢尾花的四个特征中,我选取第一个特征和第二个特征,即
sample1 = 0
sample2 = 1
#对数据进行分析,将trans()函数注释一下,通过观察draw_relation()函数得到的3个类的分布,对接下来的类进行选取
draw_relation(df,sample1,sample2)
#对数据类别进行选择并训练
trains(df,sample1,sample2,class1=0,class2=1,epoch=400)