Bohrium
robot
新建

空间站广场

论文
Notebooks
比赛
课程
Apps
我的主页
我的Notebooks
我的论文库
我的足迹

我的工作空间

任务
节点
文件
数据集
镜像
项目
数据库
公开
快速开始 Scikit-Learn|使用 Scikit-Learn 建立机器学习模型
Scikit-Learn
ML-Tutorial
Scikit-LearnML-Tutorial
MileAway
发布于 2023-06-09
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
赞 7
4
20
快速开始 Scikit-Learn|使用 Scikit-Learn 建立机器学习模型
目标
目录
背景
实践
1 认识 Scikit-Learn
1.1 什么是 Scikit-Learn
1.2 安装 Scikit-Learn
1.3 验证 Scikit-Learn 安装并查看版本
2 Scikit-Learn 方法
1 提供数据集
1.1 自建数据集
1.2 使用 sklearn 提供的数据集(以鸢尾花数据集为例)
2 数据预处理(以标准化和归一化举例)
2.1 归一化
2.2 标准化
3 快速划分数据集
4 特征选择
4.1 Filter : 过滤法
4.2 Wrapper : 包装法
4.3 Embedded 嵌入法
5 建立机器学习模型
6 评价指标
6.1 平均绝对误差 MAE
6.2 均方误差 MSE
6.3 决定系数 R2
7 交叉验证
8 参数优化
总结
进一步阅读
参考

快速开始 Scikit-Learn|使用 Scikit-Learn 建立机器学习模型

代码
文本

Open In Bohrium

代码
文本

©️ Copyright 2023 @ Authors
作者:阙浩辉 📨
日期:2023-05-09
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

代码
文本

🎯 本教程旨在快速掌握使用 scikit-learn 建立机器学习模型的范式周期。

  • 一键运行,你可以快速在实践中检验你的想法。

  • 丰富完善的注释,对于入门者友好。

代码
文本

Bohrium Notebook 界面,你可以点击界面上方蓝色按钮 开始连接,选择 bohrium-notebook 镜像及任何一款节点配置,稍等片刻即可运行。

代码
文本

目标

了解 Scikit-Learn 在建立机器学习模型中的基础功能,并能够使用 Scikit-Learn 的范式快速建立机器学习模型。

在学习本教程后,你将能够:

  • 使用 Scikit-Learn 快速创建某一类型的数据或加载现有数据。
  • 对数据进行预处理,例如归一化与标准化,以及快速划分数据集。
  • 进行特征选择的一些方法,例如过滤法、包装法及嵌入法。
  • 使用 Scikit-Learn 的范式快速建立机器学习模型。
  • 使用 sklearn.metric 来评价模型质量。
  • 使用交叉验证以及自动查找最佳的评估器参数。

阅读该教程【最多】约需 30 分钟,让我们开始吧!

代码
文本

背景

本指南的目的是说明 scikit-learn 提供的一些主要功能。Scikit-learn是一个开源机器学习库,支持监督和无监督学习。它还为模型拟合、数据预处理、模型选择、模型评估和许多其他实用程序提供了各种工具。

你需要提前了解以下知识:

  • 非常基本的机器学习实践的工作知识(了解特征、标签、训练集、测试集等)
代码
文本

实践

代码
文本

1 认识 Scikit-Learn

在这一部分,你会了解什么是 Scikit-Learn,在 Bohrium Notebook 中 使用 Scikit-Learn,验证安装并查看版本。

代码
文本

1.1 什么是 Scikit-Learn

Scikit-learn(曾叫做scikits.learn还叫做sklearn)是基于 SciPy 构建的用于Python编程语言自由软件机器学习。并在 3-Clause BSD许可证下分发。它的特征是具有各种分类回归聚类算法,包括支持向量机随机森林梯度提升k-平均聚类DBSCAN,它被设计协同于Python数值和科学库NumPySciPy。[1,2]

它具有如下显著特点[3]:

  • 用于数据分析与预测的简单高效的工具
  • 每个人都可以访问,并且可以在各种环境中重复使用
  • 基于 NumPy、SciPy 和 matplotlib 构建
  • 开源,商业上可用 - BSD 许可证
代码
文本

1.2 安装 Scikit-Learn

本教程是一个 Bohrium Notebook。Python 程序可直接在浏览器中运行,Bohrium 已安装 Scikit-Learn。这是学习和使用 Scikit-Learn 的好方法。

要按照本教程进行操作,请点击本页顶部的按钮,在 Bohrium Notebook 中运行本笔记本。

  1. 你可以点击界面上方蓝色按钮 开始连接,选择 bohrium-notebook:2023-02-28 镜像及任何一款计算机型,稍等片刻即可运行。

  2. 若要运行笔记本中的所有代码,请点击左上角“ 运行全部单元格 ”。若要一次运行一个代码单元,请选择需要运行的单元格,然后点击左上角 “运行选中的单元格” 图标。

如果你的 Bohrium 镜像尚未安装 Scikit-Learn, 最方便的方法是通过 pip 安装:

代码
文本
[39]
! pip install scikit-learn==1.2.0
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: scikit-learn==1.2.0 in /opt/conda/lib/python3.8/site-packages (1.2.0)
Requirement already satisfied: numpy>=1.17.3 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.22.4)
Requirement already satisfied: scipy>=1.3.2 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.7.3)
Requirement already satisfied: joblib>=1.1.1 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.2.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (3.1.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
代码
文本

如果你需要使用更特定于你的平台或包管理器的安装方法,你可以在这里查看更完整的安装说明。

代码
文本

1.3 验证 Scikit-Learn 安装并查看版本

安装 Scikit-Learn 后,确认库已成功安装并且你可以开始使用它。

不要跳过此步骤。

如果 Scikit-Learn 未正确安装或在此步骤中引发错误,则将无法运行之后的示例。

代码
文本
[40]
import sklearn
print(sklearn.__version__) # sklearn.__version__ 返回安装的 Scikit-Learn 的版本号
1.2.0
代码
文本

2 Scikit-Learn 方法

在这一节中,你会了解到一些 Scikit-Learn 的基础方法,包括:

  • 提供数据集
  • 数据预处理
  • 快速划分数据集
  • 特征选择
  • 建立机器学习模型
  • 评价指标
  • 模型选择之交叉验证
  • 参数优化
代码
文本

1 提供数据集

代码
文本
1.1 自建数据集

Scikit-Learn 提供了各类分布类型的数据集的建立方法,例如团簇形、环形和月亮形等。

点击这里查看参数的完整介绍

代码
文本
[41]
# 导入基础工具包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 消除警告
import warnings
warnings.filterwarnings('ignore')

# sklearn 数据库接口
from sklearn.datasets import make_blobs, make_circles, make_classification, make_moons

n_samples = 100 # 要创建的样本点
data_name = ['blobs', 'circles', 'moons', 'classification'] # 要创建的数据点分布类型

datasets = [
make_blobs(n_samples=n_samples, centers=3, random_state=0),
make_circles(n_samples=n_samples, noise=0.2, random_state=0),
make_moons(n_samples=n_samples, noise=0.2, random_state=0),
make_classification(n_samples=n_samples, n_features=20, n_informative=2, n_redundant=0, random_state=0),
# `n_features`:生成的特征总数。这些包括`n_informative`个信息特征,`n_redundant`个冗余特征,`n_repeated`个重复特征和 `n_features-n_informative-n_redundant-n_repeated`个随机无用特征。
# `n_informative`:信息特征的数量。`n_redundant`:冗余特征的数量。这些特征是信息特征的随机线性组合。
]

# 查看我们构建的数据集
fig, ax = plt.subplots(ncols=4, nrows=1, figsize=(12,3)) # 实例化一个 4 列 1 行的图片,尺寸为 长*宽=12*3
for i, (X,Y) in enumerate(datasets):
ax[i].scatter(X[:,0],X[:,1], c=Y, s=10, cmap="rainbow")
ax[i].set_title(data_name[i])
ax[i].set_xticks (())
ax[i].set_yticks (())
代码
文本
1.2 使用 sklearn 提供的数据集(以鸢尾花数据集为例)
代码
文本

sklearn.datasets 模块提供了一系列加载和获取著名数据集如鸢尾花、波士顿房价、Olivetti人脸、MNIST数据集等的工具。

鸢尾花识别是一个经典的机器学习分类问题,它的数据样本中包括了4个特征变量,1个类别变量,样本总数为150。

它的目标是为了根据花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)这四个特征来识别出鸢尾花属于山鸢尾(iris-setosa)、变色鸢尾(iris-versicolor)和维吉尼亚鸢尾(iris-virginica)中的哪一种。

代码
文本
[42]
from sklearn.datasets import load_iris

iris = load_iris()
X_iris = pd.DataFrame(iris.data, columns=iris.feature_names) # iris.data 会返回 iris 数据的特征
X_iris
代码
文本
[43]
Y_iris = pd.DataFrame(iris.target, columns=['Kind']) # iris.target 会返回 iris 数据的标签
Y_iris
代码
文本
[44]
# ## 获取更多信息,可直接查看 iris
# iris
代码
文本
[45]
# 将特征与标签在同一个 Pandas DataFrame 中表示。
df_iris = pd.concat([X_iris, Y_iris], axis=1) # 合并特征表与标签表
df_iris
代码
文本

2 数据预处理(以标准化和归一化举例)

在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求,这种需求统称为将数据“无量纲化”。

  • 譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经网络,无量纲化可以加快求解速度;
  • 而在距离类模型,譬如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。
  • (一个特例是决策树和树的集成算法们,对决策树我们不需要无量纲化,决策树可以把任意数据都处理得很好。)

数据的无量纲化可以是线性的,也可以是非线性的。

线性的无量纲化包括中心化 (Zero-centered或者Mean-subtraction) 处理缩放处理 (Scale)

中心化的本质是让所有记录减去一个固定值,即让数据样本平移到某个位置。

缩放的本质是通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。

代码
文本
2.1 归一化
代码
文本

当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间。

这个过程,就叫做数据归一化(Normalization,又称 Min-Max Scaling)。

注意,Normalization 是归一化,不是正则化,真正的正则化是 regularization,不是数据预处理的一种手段。

归一化之后的数据服从正态分布,公式如下:

代码
文本

手动来实现一个归一化

代码
文本
[46]
import numpy as np

X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])

# 归一化
X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_nor
代码
文本
[47]
#逆转归一化
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
X_returned
代码
文本

使用 sklearn 来实现归一化

代码
文本
[48]
from sklearn.preprocessing import MinMaxScaler

data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]] # 手动生成一个数据

# 能够判断data的结构吗?
# 如果换成表是什么样子?
import pandas as pd
pd.DataFrame(data)
代码
文本
[49]
#实现归一化
scaler = MinMaxScaler(feature_range=(0,1)) # 实例化, feature_range 确定 MinMaxScaler 缩放的范围
scaler = scaler.fit(data) # fit,在这里本质是生成 min(x) 和 max(x),当X中的特征数量非常多的时候,fit 会报错并表示,此时使用 partial_fit 作为训练接口 scaler = scaler.partial_fit(data)
result = scaler.transform(data) # 通过接口导出结果
result
代码
文本
[50]
result_ = scaler.fit_transform(data) # 训练和导出结果一步达成
result_
代码
文本
[51]
scaler.inverse_transform(result) # 将归一化后的结果逆转
代码
文本
2.2 标准化
代码
文本

当数据 (x) 按均值 (μ) 中心化后,再按标准差 (σ) 缩放,数据就会服从为均值为 0,方差为 1 的正态分布(即标准正态分布)

这个过程,就叫做数据标准化 (Standardization,又称 Z-score normalization),

公式如下:

代码
文本
[52]
from sklearn.preprocessing import StandardScaler

data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

scaler = StandardScaler() # 实例化
scaler.fit(data) # fit的本质是生成均值和方差
print(scaler.mean_) # 查看均值的属性 mean_
print(scaler.var_) # 查看方差的属性 var_
[-0.125  9.   ]
[ 0.546875 35.      ]
代码
文本
[53]
x_std = scaler.transform(data) # 通过接口导出结果
print(x_std.mean()) # 导出的结果是一个数组,用 mean() 查看均值
print(x_std.std()) # 用 std() 查看方差
x_std

0.0
1.0
代码
文本
[54]
scaler.fit_transform(data) # 使用 fit_transform(data)一步达成结果
代码
文本
[55]
scaler.inverse_transform(x_std) # 使用 inverse_transform 逆转标准化
代码
文本

3 快速划分数据集

可以使用 sklearn.model_selection.train_test_split 方法快速划分训练集和测试集。

在本例中,我们使用生物炭吸附数据集作为演示。

该数据集根据生物炭的特性、金属来源和环境条件等预测生物炭系统的重金属吸附效率。

数据将通过 Pandas 自动下载,如果你想了解更多内容,请参阅:

代码
文本
[56]
from sklearn.model_selection import train_test_split, cross_val_score

# 导入数据集
df_bio = pd.read_csv('https://dp-public.oss-cn-beijing.aliyuncs.com/community/AI4EC/biochar_sorption(Original).csv')
df_bio.head()
代码
文本
[57]
# 划分特征与标签
X_mat = df_bio.iloc[:, :13].values
Y_mat = df_bio.iloc[:, -1].values.reshape(-1, 1)
# 对数据集标准化
X = StandardScaler().fit_transform(X_mat)
Y = StandardScaler().fit_transform(Y_mat)
# 划分训练集和测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.3, random_state=0) # random_state 参数规定每次以相同的方式进行数据划分
代码
文本

4 特征选择

当数据预处理完成后,我们需要选择有意义的特征输入机械学习的算法和模型中进行训练。通常来说,从两个方面考虑来选择特征:

  1. 特征是否发散:如果一个特征不发散,例如方差接近于0或者基本上都是重复数据,也就是说样本在这个特征上基本上没有差异,这个特征对于样本区分并没有什么用。
  2. 特征与目标的相关性:这点比较显而易见,与目标相关性高的特征,应当优选选择。

最近邻算法 KNN,单棵决策树,支持向量机SVM,神经网络,回归算法,都需要遍历特征或升维来进行运算,所以他们本身的运算量就很大,需要的时间就很长,因此方差过滤这样的特征选择对他们来说就尤为重要。

但对于不需要遍历特征的算法,比如随机森林,它随机选取特征进行分枝,本身运算就非常快速,因此特征选择对它来说效果平平。

因此,过滤法的主要对象是:需要遍历特征或升维的算法们,而过滤法的主要目的是:在维持算法表现的前提下,帮助算法降低计算成本。

根据特征选择的形式又可以将特征选择的方法分为3种:

代码
文本
4.1 Filter : 过滤法

按照发散性或者相关性对各个特征进行评分,设定阀值或者待选阀值的个数,选择特征。

代码
文本

4.1.1 方差法

计算各个特征的方差,根据阀值,选择方差大于阀值的特征

代码
文本
[58]
from sklearn.feature_selection import VarianceThreshold # 方差选择法,返回值为特征选择后的数据

X_var = VarianceThreshold(threshold = 2).fit_transform(X_mat) # 参数threshold为方差的阀值
X_var.shape
代码
文本

4.1.2 卡方过滤 (分类算法相关性检验)

卡方过滤是专门针对离散型标签(即分类问题)的相关性过滤。

卡方检验类 featureselection.chi2 计算每个非负特征和标签之间的卡方统计量,并依照卡方统计量由高到低为特征排名。

再结合 featureselection.SelectkBest 这个可以输入“评分标准"来选出前 K 个分数最高的特征的类,我们可以借此除去最可能独立于标签,与我们分类目的无关的特征。

卡方检验要求特征中均为非负值。

代码
文本
[59]
from sklearn.feature_selection import SelectKBest # 选择K个最好的特征,返回选择特征后的数据
from sklearn.feature_selection import chi2 # 卡方检验

X_fschi = SelectKBest(chi2, k = 2).fit_transform(X_iris, Y_iris)
# 第一个参数为计算评估特征依赖的统计量
# 第二个参数指定选择前 k 个特征

X_fschi.T # .T 将矩阵转置(便于阅读)
代码
文本

从特征工程的角度,我们希望选取卡方值很大,p 值小于 0.05 的特征,即和标签是相关联的特征。

而调用 SelectkBest 之前,我们可以直接从 chi2 实例化后的模型中获得各个特征所对应的卡方值和 P 值。

代码
文本
[60]
chivalue, pvalues_chi = chi2(X_iris, Y_iris) # 使用卡方系数查看相关性, chivalue 是卡方值,pvalues_chi 是 P值
pvalues_chi

代码
文本

4.1.3 F 检验 (线性相关性)

F检验,又称ANOVA,方差齐性检验,是用来捕捉每个特征与标签之间的 线性关系 的过滤方法。

F检验的本质是寻找两组数据之间的线性关系,其原假设是'数据不存在显著的线性关系”。

它返回 F 值和 P 值两个统计量。

和卡方过滤一样,我们希望选取 p 值小于 0.05 或 0.01 的特征,这些特征与标签是显著线性相关的,

而 P 值大于 0.05 或 0.01 的特征则被我们认为是和标签没有显著线性关系的特征,应该被删除。

代码
文本
[61]
from sklearn.feature_selection import SelectKBest # 选择K个最好的特征,返回选择特征后的数据
from sklearn.feature_selection import f_classif # F检验

F, pvalues_F = f_classif(X_iris, Y_iris)
print(pvalues_F)

x_F = SelectKBest(chi2, k = 2).fit_transform(X_iris, Y_iris)
x_F.T

# cross_val_score(RFR(n_estimators=10, random_state=0), X_F, Y, cv=5).mean()
[1.66966919e-31 4.49201713e-17 2.85677661e-91 4.16944584e-85]
代码
文本

4.1.4 互信息法

互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。

和F检验相似,它既可以做回归也可以做分类,并且包含两个类featureselection.mutualinfoclassif(互信息分类)和 featureselection.mutualinforegression(互信息回归)。

这两个类的用法和参数都和F检验一模一样,不过互信息法比F检验更加强大,F检验只能够找出线性关系,而互信息法可以找出任意关系。

互信息法不返回 p 值或 F 值类似的统计量,它返口"每个特征与目标之间的互信息量的估计”,

这个估计量在 [0,1] 之间取值,为 0 则表示两个变量独立,为 1 则表示两个变量完全相关。以互信息分类为例的代码如下:

代码
文本
[62]
from sklearn.feature_selection import mutual_info_classif as MIC

MIC(X_iris, Y_iris)
代码
文本
4.2 Wrapper : 包装法

根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。

代码
文本

4.2.1 递归特征消除法

递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。

代码
文本
[63]
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# 参数 estimator 为基模型,参数 n_features_to_select 为选择的特征个数
RFE(estimator = LogisticRegression(), n_features_to_select = 2).fit_transform(iris.data, iris.target).T
# 递归特征消除法,返回特征选择后的数据
代码
文本
4.3 Embedded 嵌入法

嵌入法是一种让算法自己決定使用哪些特征的方法,即特征选择和算法训练同时进行。

在使用嵌入法时,我们先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数.

根据权值系数从大到小选择权值系数大的特征,权值系数往往代表了特征对于模型的某种贡献或重要性。

selectFromModel 是一个元变换器,可以与任何在拟合后具有 coef_,feature_importances_ 属性或具有惩罚项的评估器一起使用

(比如随机森林和树模型就具有属性 featureimportances_,逻辑回归就带有l1和l2惩罚项,线性支持向量机也支持l2惩罚项)。

参数 说明
estimator 使用的模型评估器, 只要是带 coef_,feature_importances_ 属性或具有惩罚项的评估器都可以使用。
threshold 特征重要性的阈值,重要性低于这个阈值的特征都将被删除。
prefit 默认False,判断是否将实例化后的模型直接传递给构造函数。如果为True,则必须直接调用 fit 和 transform,不能使用 fit_transform,并且 SelectFromModel 不能与 cross_val_score, GridSearchCV和克隆估计器的类似程序一起使用。
norm_order k可输入非零整数,正无穷,负无穷,默认值为1在评估器的 coef_ 属性高于一维的情况下,用于过滤低于阈值的系数的向量的范数的阶数。
max_features 在阈值设定下,要选择的最大特征数。要禁用阈值并仅根据 max_features 选择,设 置threshold = -np.inf
代码
文本
[64]
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestRegressor

rfr = RandomForestRegressor(n_estimators=10, random_state=0)
print(rfr.fit(X,Y).feature_importances_) # 打印各特征的重要性参数
X_embedded = SelectFromModel(estimator=rfr, threshold=0.005).fit_transform(X, Y)
X_embedded.shape
[3.60360035e-03 5.84203561e-02 6.43556008e-03 1.21898803e-02
 1.13200898e-02 3.30934631e-03 9.24397894e-03 5.79670705e-04
 4.02999953e-03 9.70090553e-02 1.23106767e-03 1.08092186e-01
 6.84535209e-01]
代码
文本
[65]
# ## ######### TIME WARNING: 30 seconds ###########
threshold = np.linspace(0, rfr.fit(X, Y).feature_importances_.max(), 50)
scores = []

for i in threshold:
X_embedded = SelectFromModel(rfr, threshold=i).fit_transform(X, Y)
cv_score = cross_val_score(rfr, X_embedded,Y, cv=5).mean()
scores.append(cv_score)

plt.plot(threshold, scores)
plt.show()
代码
文本

5 建立机器学习模型

代码
文本

线性回归模型展示

代码
文本
[66]
from sklearn.linear_model import LinearRegression # 导入线性回归模块

lr = LinearRegression() # 实例化一个模型, 参数都为默认值
lr.fit(Xtrain, Ytrain) # 用训练集数据进行训练
Ypred = lr.predict(Xtest) # 对测试结果进行预测
lr.score(Xtest, Ytest) # 查看预测分数
print(f'The predict score is {lr.score(Xtest, Ytest)}')

# 绘制预测结果图
plt.plot([-0.8,3.5], [-0.8,3.5], "--k")
plt.scatter(x=Ytest, y=Ypred, c='orange')
plt.show()
The predict score is 0.7951077576074727
代码
文本

决策树模型展示

代码
文本
[76]
from sklearn.tree import DecisionTreeRegressor # 导入线性回归模块

dtr = DecisionTreeRegressor(random_state=0) # 实例化一个模型, 参数都为默认值
dtr.fit(Xtrain, Ytrain) # 用训练集数据进行训练
Ypred = dtr.predict(Xtest) # 对测试结果进行预测
dtr.score(Xtest, Ytest) # 查看预测分数
print(f'The predict score is {dtr.score(Xtest, Ytest)}')

# 绘制预测结果图
plt.plot([-0.8,3.5], [-0.8,3.5], "--k")
plt.scatter(x=Ytest, y=Ypred, c='orange')
plt.show()
The predict score is 0.968738980776025
代码
文本

KMeans 模型展示

代码
文本
[75]
from sklearn.cluster import KMeans # 导入KMeans模块

kmeans = KMeans(n_clusters=3, random_state=0) # 实例化一个模型, 设置聚类中心为3
kmeans.fit(Xtrain) # 用训练集数据进行训练
Ypred = kmeans.predict(Xtest) # 对测试结果进行预测

# 不能直接使用score方法,因为KMeans是无监督学习,没有Ytest可以用来计算分数
# 若要评估模型,可以使用轮廓系数等方法,这里仅展示预测结果
print(f'The predict result is {Ypred}')

# 绘制预测结果图
plt.scatter(Xtest[:, 0], Xtest[:, 1], c=Ypred, cmap='viridis') # 根据预测结果绘制散点图
plt.show()
The predict result is [0 0 0 0 0 2 0 0 2 0 0 1 0 0 2 0 0 2 0 0 2 2 0 0 0 1 0 0 1 1 1 1 2 2 0 1 0
 0 0 2 2 0 1 1 1 2 0 0 0 2 1 0 1 0 0 2 0 1 1 0 0 1 1 0 0 2 2 0 0 0 0 1 0 0
 2 2 1 0 0 0 0 2 0 0 1 1 1 0 2 0 0 0 1 1 0 2 2 0 1 0 0 0 2 2 0 0]
代码
文本

可以看到,选择错误的模型会导致完全错误的结果。 🙅

代码
文本

支持向量机 SVM 模型展示

代码
文本
[77]
from sklearn.svm import SVR # 导入支持向量机回归模块

svr = SVR() # 实例化一个模型, 参数都为默认值
svr.fit(Xtrain, Ytrain) # 用训练集数据进行训练
Ypred = svr.predict(Xtest) # 对测试结果进行预测
svr.score(Xtest, Ytest) # 查看预测分数
print(f'The predict score is {svr.score(Xtest, Ytest)}')

# 绘制预测结果图
plt.plot([-0.8,3.5], [-0.8,3.5], "--k")
plt.scatter(x=Ytest, y=Ypred, c='orange')
plt.show()
The predict score is 0.9301744087982504
代码
文本

随机森林模型展示

代码
文本
[68]
from sklearn.ensemble import RandomForestRegressor # 导入随机森林模块

rfr = RandomForestRegressor() # 实例化一个模型, 参数都为默认值
rfr.fit(Xtrain, Ytrain) # 用训练集数据进行训练
Ypred = rfr.predict(Xtest) # 对测试结果进行预测
rfr.score(Xtest, Ytest) # 查看预测分数
print(f'The predict score is {rfr.score(Xtest, Ytest)}')

# 绘制预测结果图
plt.plot([-0.8,3.5], [-0.8,3.5], "--k")
plt.scatter(x=Ytest, y=Ypred, c='orange')
plt.show()
The predict score is 0.9699573420845312
代码
文本

神经网络模型(多层感知机)效果展示

代码
文本
[78]
from sklearn.neural_network import MLPRegressor # 导入多层感知机回归模块

mlp = MLPRegressor(random_state=0) # 实例化一个模型, 参数都为默认值
mlp.fit(Xtrain, Ytrain) # 用训练集数据进行训练
Ypred = mlp.predict(Xtest) # 对测试结果进行预测
mlp.score(Xtest, Ytest) # 查看预测分数
print(f'The predict score is {mlp.score(Xtest, Ytest)}')

# 绘制预测结果图
plt.plot([-0.8,3.5], [-0.8,3.5], "--k")
plt.scatter(x=Ytest, y=Ypred, c='orange')
plt.show()
The predict score is 0.8914636746919842
代码
文本

可以看到,选择不同的机器学习模型,对预测效果存在重要影响。

代码
文本

6 评价指标

模型效果如何需要有效的评估方法。在分类算法中,我们可以很明确的使用准确率指标,而在回归类算法中,我们需要一些指标来评估是否预测到了正确的数值。

代码
文本
[69]
! pip install scikit-learn==1.2.0
from sklearn.metrics import get_scorer_names
print(get_scorer_names())
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: scikit-learn==1.2.0 in /opt/conda/lib/python3.8/site-packages (1.2.0)
Requirement already satisfied: numpy>=1.17.3 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.22.4)
Requirement already satisfied: scipy>=1.3.2 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.7.3)
Requirement already satisfied: joblib>=1.1.1 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (1.2.0)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/lib/python3.8/site-packages (from scikit-learn==1.2.0) (3.1.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
['accuracy', 'adjusted_mutual_info_score', 'adjusted_rand_score', 'average_precision', 'balanced_accuracy', 'completeness_score', 'explained_variance', 'f1', 'f1_macro', 'f1_micro', 'f1_samples', 'f1_weighted', 'fowlkes_mallows_score', 'homogeneity_score', 'jaccard', 'jaccard_macro', 'jaccard_micro', 'jaccard_samples', 'jaccard_weighted', 'matthews_corrcoef', 'max_error', 'mutual_info_score', 'neg_brier_score', 'neg_log_loss', 'neg_mean_absolute_error', 'neg_mean_absolute_percentage_error', 'neg_mean_gamma_deviance', 'neg_mean_poisson_deviance', 'neg_mean_squared_error', 'neg_mean_squared_log_error', 'neg_median_absolute_error', 'neg_negative_likelihood_ratio', 'neg_root_mean_squared_error', 'normalized_mutual_info_score', 'positive_likelihood_ratio', 'precision', 'precision_macro', 'precision_micro', 'precision_samples', 'precision_weighted', 'r2', 'rand_score', 'recall', 'recall_macro', 'recall_micro', 'recall_samples', 'recall_weighted', 'roc_auc', 'roc_auc_ovo', 'roc_auc_ovo_weighted', 'roc_auc_ovr', 'roc_auc_ovr_weighted', 'top_k_accuracy', 'v_measure_score']
代码
文本
6.1 平均绝对误差 MAE

代码
文本
[70]
from sklearn.metrics import mean_absolute_error as MAE

MAE(Ypred, Ytest)
代码
文本
6.2 均方误差 MSE

代码
文本
[71]
from sklearn.metrics import mean_squared_error as MSE

MSE(Ypred, Ytest)
代码
文本
6.3 决定系数

代码
文本
[72]
from sklearn.metrics import r2_score as R2

R2(Ypred, Ytest)

代码
文本

7 交叉验证

学习预测函数的参数并在相同的数据上对其进行测试是一个方法上的错误:一个只重复它刚刚看到的样本标签的模型将获得满分,但无法预测任何有用的数据。

这种情况称为过拟合。

为了避免这种情况,在执行(监督)机器学习 “实验” 时,通常的做法是将部分可用数据保留为测试集 X_test,y_test。

下面是模型训练中典型交叉验证工作流的示意图。最佳参数可以通过网格搜索确定。

CV-sklearn

由 k 折交叉验证报告的评估指标是循环后得到的平均值。

这种方法的计算成本可能很高,但不会浪费太多数据,这在诸如样本数量非常少的问题中仍能较好的反应模型效果,是交叉验证的一个主要优势。

代码
文本
[73]
from sklearn.model_selection import cross_val_score, cross_validate

cross_val_score(rfr, X, Y, cv=5, scoring='neg_mean_squared_error')
代码
文本

8 参数优化

所有估计器都有可以调整的参数(在文献中通常称为超参数)。

估计器的泛化功效通常主要取决于几个参数。

例如,RandomForestRegressor 具有一个确定林中树数的 n_estimators 参数,以及一个确定每棵树最大深度的 max_depth 参数。

通常,不清楚这些参数的确切值应该是多少,因为它们取决于手头的数据。

Scikit-Learn提供了自动查找最佳参数组合的工具。在下面的示例中,我们使用 RandomizedSearchCV 方法随机搜索随机森林回归的参数空间。

搜索结束后,RandomizedSearchCV 就像一个 RandomForestRegressor,它已经拟合了最佳参数集。

你可在用户指南中了解更多内容:

代码
文本
[74]
# ## ################ Time Warning: 5 seconds ###################
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint

# 还记得 Part 2.3 我们创建和划分的生物炭数据集吗?让我们在这里再回顾一下
# 导入数据集
df_bio = pd.read_csv('https://dp-public.oss-cn-beijing.aliyuncs.com/community/AI4EC/biochar_sorption(Original).csv')
# 划分特征与标签
X_mat = df_bio.iloc[:, :13].values
Y_mat = df_bio.iloc[:, -1].values.reshape(-1, 1)
# 对数据集标准化
X = StandardScaler().fit_transform(X_mat)
Y = StandardScaler().fit_transform(Y_mat)

# 设置网格搜索的超参数空间
n_estimators = randint(1, 5)
max_depth = randint(5, 10)
param_distributions = dict(n_estimators=n_estimators, max_depth=max_depth)

# 实例化一个随机搜索寻找最优参数
search = RandomizedSearchCV(RandomForestRegressor(random_state=0),
n_iter=5,
param_distributions=param_distributions,
random_state=0)
# 使用随机搜索训练模型
search.fit(X, Y) # 还记得吗?使用交叉验证不需要手动划分训练集和数据集,scikit-learn 会帮我们自动划分。

# 得到最优参数及最优模型预测分数
print(f"最优的参数是: {search.best_params_} ,其得分为 {search.best_score_}")
最优的参数是: {'max_depth': 7, 'n_estimators': 1} ,其得分为 0.7601224720158413
代码
文本

总结

在本教程中,您学习了在 Scikit-Learn 的一些基础方法。

具体而言,您了解到:

  • 使用 Scikit-Learn 快速创建某一类型的数据或加载现有数据。
  • 对数据进行预处理,例如归一化于标准化,以及快速划分数据集。
  • 进行特征选择的一些方法,例如过滤法、包装法及嵌入法。
  • 使用 Scikit-Learn 的范式快速建立机器学习模型。
  • 使用 sklearn.metric 来评价模型质量。
  • 使用交叉验证以及自动查找最佳的评估器参数。

你有什么问题吗? 欢迎与我们联系 bohrium@dp.tech

代码
文本

进一步阅读

如果您希望更深入学习 Scikit-Learn 及机器学习,本节提供有关该主题的更多资源。

书籍

Scikit-Learn 项目

代码
文本
Scikit-Learn
ML-Tutorial
Scikit-LearnML-Tutorial
已赞7
本文被以下合集收录
2023机器学习及其在化学中的应用
昌珺涵
更新于 2024-09-12
22 篇158 人关注
使用 Python 快速开始机器学习
MileAway
更新于 2024-07-25
7 篇25 人关注
推荐阅读
公开
快速开始 TensorFlow2|面向初学者的快速入门
TutorialTensorFlow
TutorialTensorFlow
MileAway
发布于 2023-06-10
3 转存文件
公开
快速开始 ABACUS|自洽 能带 态密度 结构优化
ABACUSDFTChinesesTutorial
ABACUSDFTChinesesTutorial
MileAway
发布于 2023-06-12
19 赞27 转存文件3 评论