前言:
经典机器学习入门项目,使用逻辑回归、线性判别分析、KNN、分类与回归树、朴素贝叶斯、向量机、随机森林、梯度提升决策树对不同占比的训练集进行分类
原文摘要:
150行,5列,分三种鸢尾花类型,每种类型50个样本,每行数据包含花萼长度、花萼宽度、花瓣长度、花瓣宽度4个特征的信息
data:记录4个特征的信息和鸢尾花类型
target:以数值的形式记录鸢尾花的种类(0、1、2)
target_names:鸢尾花的种类名称,山鸢尾(Iris-setosa)、变色鸢尾(Iris-versicolor)、维吉尼亚鸢尾(Iris-virginica)
DESCR:备注信息
feature_names:鸢尾花的特征名称,sepal length (cm)、sepal width (cm)、petal length (cm)、petal width (cm),分别对应花萼长度、花萼宽度、花瓣长度、花瓣宽度4个特征
代码思路
特征相关性观察
通过散点矩阵图观察到,鸢尾花的花瓣长度和宽度对鸢尾花类型偏正相关一点
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import pandas as pd
iris = load_iris()
# 散点矩阵图,看各特征之间的相关性
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
scatter_corr = pd.plotting.scatter_matrix(iris_df, marker='o', c=iris.target, hist_kwds={'bins': 20})
# plt.show()
参考文章:pandas库scatter_matrix绘图可视化参数详解-优快云博客
可视化设置
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于显示中文
plt.rcParams['axes.unicode_minus'] = False # 用于解决保存图像是负号‘-’显示为方框的问题
plt.rcParams['font.size'] = '12' #用于设置中文大小
plt.rcParams['axes.labelsize'] = plt.rcParams['font.size'] # 设置坐标轴标签的字体大小
"""
figsize:画布大小
dpi:清晰度
edgecolor:画布边框颜色
frameon:是否绘制画布图框
"""
fig, axes = plt.subplots(num='可视化不同训练集比例',ncols=4,figsize=(25, 6), dpi=80,
edgecolor=None,frameon=False)
color_list = ['r','g','b','magenta'] # 颜色列表
模型导入
- 逻辑回归:是一种线性模型,常用于二元分类问题。
- 线性判别分析 (LDA):是一种统计模型,用于分类和判别分析。
- KNN :是一种基于实例的学习算法,在训练数据集中存储实例,并使用这些实例来进行分类。
- 决策树:是一种树形结构,使用训练数据集中的特征对实例进行分类。
- 朴素贝叶斯分类器:是一种基于贝叶斯定理的分类器,常用于文本分类。
- 支持向量机 (SVM):是一种二分类模型,通过创建一个超平面将数据划分为两个类别。
- 随机森林:是一种集成学习模型,通过构建多个决策树并取其输出的平均值来进行分类。
- 梯度提升决策树:也属于决策树的一种,通过迭代训练多个决策树并取其输出的平均值来进行分类。
import numpy as np
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.tree import DecisionTreeClassifier # 分类与回归树
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # 线性判别分析
from sklearn.neighbors import KNeighborsClassifier # KNN最近邻
from sklearn.naive_bayes import GaussianNB # 朴素贝叶斯
from sklearn.svm import SVC # 向量机
from sklearn.ensemble import RandomForestClassifier # 随机森林
from sklearn.ensemble import GradientBoostingClassifier # 梯度提升决策树
字典形式引用模型
以字典的形式存储模型后续通过循环迭代的方式,应用每个模型在数据集中
models = {
"LR" : LogisticRegression(max_iter=200),
"LDA" : LinearDiscriminantAnalysis(),
"KNN" : KNeighborsClassifier(),
"CART": DecisionTreeClassifier(),
"NB" : GaussianNB(),
"SVM" : SVC(),
"RF" : RandomForestClassifier(n_estimators=100),
"GBDT": GradientBoostingClassifier()
}
训练参数设置
建立空列表是为了后续可视化的时候使用(X轴为模型名称、Y轴为模型得分)
size = [0.6, 0.7, 0.8, 0.9] # 训练集比例
kf = KFold(n_splits=5, random_state=10, shuffle=True) # n_splite:K折交叉验证划分数量
通过循环遍历训练比例训练模型
先进行数据划分出训练集和测试集
先将数据集划分为四个部分,结合for循环多次划分训练集
因为数据量较少,但每次划分有需要保留部分数据,因此结合stratify、random_state、shuffle参数在每次划分前都打乱数据,且控制随机数量和按鸢尾花种类等比划分
"""
train_size:训练集占比
stratify:按鸢尾花种类进行分层采样
random_state:控制随机数生成器的种子数量
shuffle:先打乱数据再划分
"""
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,
train_size=size[index],
stratify=iris.target,
random_state=42,
shuffle=True)
K折交叉验证模型性能
用K折交叉验证法将训练集划分出来训练模型,并用测试集去评估模型的性能
model_scores = {}
for model_name, model in models.items():
cv_score = cross_val_score(model, x_train, y_train, cv=kf)
score = np.mean(cv_score).round(3)
model_scores[model_name] = score
再将各模型性能得分可视化
在各训练比例、模型性能评估下,得到的分数放在子图表里
for model_name,score in model_scores.items():
ax.bar(model_name,score,width=0.4,color=color_list[index],alpha=0.45)
ax.text(model_name,score,score,ha='center',va='bottom')
ax.set_title(f'训练集占比为{size[index]}的各模型得分')
ax.set_yticks([0.7, 0.8, 0.9, 1])
ax.set_ylim((0.8, 1.1))
参考文章:【matplotlib】浅谈python图形可视化练习经验分享_plt.xtick-优快云博客
完整代码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
# 散点矩阵图,看各特征之间的相关性
iris_df = pd.DataFrame(iris.data, columns=iris.feature_names)
scatter_corr = pd.plotting.scatter_matrix(iris_df, marker='o', c=iris.target, hist_kwds={'bins': 20})
# ---------------------------------------- 可视化设置 --------------------------------------------
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于显示中文
plt.rcParams['axes.unicode_minus'] = False # 用于解决保存图像是负号‘-’显示为方框的问题
plt.rcParams['font.size'] = '12' # 用于设置中文大小
plt.rcParams['axes.labelsize'] = plt.rcParams['font.size'] # 设置坐标轴标签的字体大小
"""
figsize:画布大小
dpi:清晰度
edgecolor:画布边框颜色
frameon:是否绘制画布图框
"""
fig, axes = plt.subplots(num='可视化不同训练集比例', ncols=4, figsize=(25, 6), dpi=80,
edgecolor=None, frameon=False)
color_list = ['r', 'g', 'b', 'magenta'] # 颜色列表
# --------------------------------------- 导入各模型 ------------------------------------------
import numpy as np
from sklearn.model_selection import train_test_split, KFold, cross_val_score
from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.tree import DecisionTreeClassifier # 分类与回归树
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # 线性判别分析
from sklearn.neighbors import KNeighborsClassifier # KNN最近邻
from sklearn.naive_bayes import GaussianNB # 朴素贝叶斯
from sklearn.svm import SVC # 向量机
from sklearn.ensemble import RandomForestClassifier # 随机森林
from sklearn.ensemble import GradientBoostingClassifier # 梯度提升决策树
models = {
"LR" : LogisticRegression(max_iter=200),
"LDA" : LinearDiscriminantAnalysis(),
"KNN" : KNeighborsClassifier(),
"CART": DecisionTreeClassifier(),
"NB" : GaussianNB(),
"SVM" : SVC(),
"RF" : RandomForestClassifier(n_estimators=100),
"GBDT": GradientBoostingClassifier()
}
# ---------------------------------------- 训练参数设置 --------------------------------------------
size = [0.6, 0.7, 0.8, 0.9] # 训练集比例
kf = KFold(n_splits=5, random_state=10, shuffle=True) # n_splite:K折交叉验证划分数量
# -------------------------- 使用不同训练比例遍历各模型并放入子图表中可视化 -----------------------------
for index, ax in enumerate(axes):
"""
train_size:训练集占比
stratify:按鸢尾花种类进行分层采样
random_state:控制随机数生成器的种子数量
shuffle:先打乱数据再划分
"""
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,
train_size=size[index],
stratify=iris.target,
random_state=42,
shuffle=True)
model_scores = {} # 每次遍历都会清空该字典
for model_name, model in models.items():
cv_score = cross_val_score(model, x_train, y_train, cv=kf)
score = np.mean(cv_score).round(3)
model_scores[model_name] = score # 模型评估得分装进该字典
for model_name, score in model_scores.items():
ax.bar(model_name, score, width=0.4, color=color_list[index], alpha=0.45)
# 数据标签
ax.text(model_name, score, score, ha='center', va='bottom')
# 子图表标题
ax.set_title(f'训练集占比为{size[index]}的各模型得分')
# Y轴刻度
ax.set_yticks([0.7, 0.8, 0.9, 1])
# Y轴范围
ax.set_ylim((0.8, 1.1))
plt.show()
参考文章: