Iris flower数据集是1936年由Sir Ronald Fisher引入的经典多维数据集,可以作为判别分析(discriminant analysis)的样本。该数据集包含Iris花的三个品种(Iris setosa, Iris virginica and Iris versicolor)各50个样本,每个样本还有4个特征参数(分别是萼片的长宽和花瓣的长宽,以厘米为单位),Fisher利用这个数据集开发了一个线性判别模型来辨别花朵的品种。
基于Fisher的线性判别模型,该数据集成为了机器学习中各种分类技术的典型实验案例。
现在我们要解决的分类问题是,当我们看到一个新的iris花朵,我们能否根据以上测量参数成功预测新iris花朵的品种。
我们利用给定标签的数据,设计一种规则进而应用到其他样本中做预测,这是基本的监督问题(分类问题)。
由于iris数据集样本量和维度都很小,所以可以方便进行可视化和操作。
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from scipy.io import loadmat
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
# 导入数据
path = '../Data/iris.data'
data = pd.read_csv(path, names=['Sepal.Length','Sepal.Width','Petal.Length','Petal.Width','Species'])
data.head(10)
# 绘制数据散点图
data.plot(kind = 'scatter', x = 'Sepal.Length', y = 'Species')
data.plot(kind = 'scatter', x = 'Sepal.Width', y = 'Species')
data.plot(kind = 'scatter', x = 'Petal.Length', y = 'Species')
data.plot(kind = 'scatter', x = 'Petal.Width', y = 'Species')
# 映射函数iris_type: 将string的label映射至数字label
def iris_type(s):
class_label = {'Iris-setosa':0, 'Iris-versicolor':1, 'Iris-virginica':2}
return class_label[s]
Data = pd.read_csv(path,names=['Sepal.Length','Sepal.Width','Petal.Length','Petal.Width','Species'], converters = {4:iris_type})
Data.head(10)
# 变量初始化
# 最后一列为y,其余为x
cols = Data.shape[1] #列数 shape[0]行数 [1]列数
X = Data.iloc[:,0:cols-1] #取前cols-1列,即输入向量
y = Data.iloc[:,cols-1:cols] #取最后一列,即目标变量
X = np.array(X)
y = np.array(y)
y = y.flatten() # 对y进行降维
# 划分训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)
X_train.shape,y_train.shape
# 调用sklearn逻辑回归LogisticRegression()函数
lr = LogisticRegression(penalty='l2',solver='newton-cg',multi_class='multinomial')
lr.fit(X_train,y_train)
print("训练集的准确率:%.3f" %lr.score(X_train, y_train))
print("测试集的准确率:%.3f" %lr.score(X_test, y_test))
y_hat = lr.predict(X_test)
accuracy = metrics.accuracy_score(y_test, y_hat) #错误率,也就是np.average(y_test==y_hat)
print("模型正确率:%.3f" %accuracy)
print(lr.get_params()) # 查看训练参数
print(lr.coef_) # 模型预测参数值
# 图例展示预测值与真实值的变化趋势
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.figure(facecolor='w')
t = np.arange(len(X_test)) #创建等差数组
plt.plot(t, y_test, 'r-', label=u'真实数据')
plt.legend(loc='upper right')
plt.title(u'鸢尾花分类真实值', fontsize=18)
plt.grid(b=True, linestyle='--')
# 图例展示预测值与真实值的变化趋势
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.figure(facecolor='w')
t = np.arange(len(X_test)) #创建等差数组
plt.plot(t, y_hat, 'b-', label=u'预测数据')
plt.legend(loc='upper right')
plt.title(u'鸢尾花分类预测值', fontsize=18)
plt.grid(b=True, linestyle='--')
# 为了可视化画图更加直观,故只取前两列特征值向量进行训练,
cols = Data.shape[1] #列数 shape[0]行数 [1]列数
X2 = Data.iloc[:,0:2] #取前cols-1列,即输入向量
y2 = Data.iloc[:,cols-1:cols] #取最后一列,即目标变量
X2 = np.array(X2)
y2 = np.array(y2)
y2 = y2.flatten() # 降维
X2.shape
# 划分训练集和测试集
X2_train,X2_test,y2_train,y2_test = train_test_split(X2,y2,test_size=0.3)
X2_train.shape,y2_train.shape
# 调用逻辑回归LogisticRegression()函数
lr2 = LogisticRegression(penalty='l2',solver='newton-cg',multi_class='multinomial')
lr2.fit(X2_train,y2_train)
print("训练集的准确率:%.3f" %lr2.score(X2_train, y2_train))
print("测试集的准确率:%.3f" %lr2.score(X2_test, y2_test))
# 可视化分类结果
# 1.确定坐标轴范围,x,y轴分别表示两个特征
x1_min, x1_max = X2[:,0].min() - .5, X2[:,0].max() + .5 # 第0列的范围
x2_min, x2_max = X2[:,1].min() - .5, X2[:,1].max() + .5 # 第1列的范围
h = .02
x1, x2 = np.meshgrid(np.arange(x1_min, x1_max, h), np.arange(x2_min, x2_max, h)) # 生成网格采样点
grid_test = np.stack((x1.flat, x2.flat), axis=1)
grid_hat = lr2.predict(grid_test)
grid_hat = grid_hat.reshape(x1.shape) # 使之与输入的形状相同
# 指定默认字体
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
# 绘制
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
alpha=0.5
plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light) # 预测值的显示
# plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', s=50, cmap=cm_dark) # 样本
plt.plot(X2_test[:, 0], X2_test[:, 1], 'o', alpha=alpha, color='blue', markeredgecolor='k')
plt.scatter(X2_test[:, 0], X2_test[:, 1], s=120, facecolors='none', zorder=10) # 圈中测试集样本
plt.xlabel(u'花萼长度', fontsize=13)
plt.ylabel(u'花萼宽度', fontsize=13)
plt.xlim(x1_min, x1_max)
plt.ylim(x2_min, x2_max)
plt.title(u'鸢尾花LogisticRegression分类结果', fontsize=15)
plt.grid() #显示网格
plt.show()