Sklearn机器学习入门

Sklearn(全称 scikit-learn)是一个开源的机器学习库,是一个基于 Python 编程语言的开源机器学习库,致力于提供简单而高效的工具,其建立在 NumPy、SciPy 和 matplotlib 这些科学计算库之上,提供了简单而高效的数据挖掘和数据分析工具

Sklearn 是许多机器学习项目的核心工具之一,并且在学术界、工业界和个人项目中广泛应用,其适用于各类机器学习任务,如分类、回归、聚类、降维等

前言

必要知识

学习Sklearn之前,需要具备的技能和需要了解的知识:

  • Python
  • 数据分析
    • Pandas
    • Numpy
    • Matplotlib
  • 机器学习相关知识
    • 特征工程
    • 模型评估和验证
    • 监督学习
      • 回归
      • 分类
      • 决策树
    • 无监督学习
      • 聚类
      • PCA
      • ...
  • 优化相关知识

学习Sklearn需要掌握以上相关知识,以上知识之前的文章都有讲解,可以查看往期的文章

关于Sklearn的安装教程这里不做介绍,仅仅介绍常用的Sklearn操作

教程风格

本教程将会以机器学习的一般流程,一步一步介绍每一步可能会用到的函数和方法,相比于网上大多数的 “词典式” 的教程将会更加易学

且文章展示的代码均为 Jupyter Notebook 文件下编写的代码,可能与正常 .py 文件的代码不一致

机器学习一般流程

以下是机器学习的一般流程:

  • 场景解析
    • 算法选择
  • 数据相关操作
    • 导入数据
    • 了解数据
    • 数据清洗
    • 数据预处理
  • 特征工程
    • 特征缩放
    • 特征选择
    • 字符串数据处理
    • 处理不平均样本
  • 模型训练
    • 数据集分割
    • 优化策略
      • 交叉验证
      • 网格搜索
    • 模型训练(和优化策略并行)
  • 模型评估
    • 性能评估

我将从上到下一步一步进行介绍可能用到的操作

场景解析

算法选择

在做一个项目时,我们首先会了解项目背景,大致可以确定具体的算法

例如:一个房价预测...

这一类项目,从字面意思就能知道,他是预测房价的,房价是连续数据,自然而然就能想到需要使用回归相关算法

例如:判断是否XXX...

像这种就是分类,具体是二分类还是多分类还要具体分析

从这里起码就可以知道,到底是分类还是回归,监督学习还是无监督学习

再结合机器学习相关知识,以及相关模型,心里大概就有了对应的模型选择

数据相关操作

使用Sklearn的话,一般都是使用结构化数据

对于非结构化数据:图像、视频、文字、音频...我们一般会使用深度学习相关算法和框架:PyTorch和TensorFlow

导入数据

由于Sklearn常常都是处理结构化数据,而这些数据基本上都是以CSV格式存储

所以就直接使用Pandas相关方法进行导入

1
2
import pandas as pd
data = pd.read_csv('文件路径')

对于其他类型的数据存储方式,Pandas提供了很多方法,具体可以查看之前的文章

数据的结构

一般的监督学习的结构化数据的数据结构都是:

  • 特征矩阵
  • 目标向量

例如:

ID 特征1 特征2 特征3 ... 特征n 目标(标签)
1 ... ... ... ... ... ...
2 ... ... ... ... ... ...
3 ... ... ... ... ... ...
... ... ... ... ... ... ...

对于 ID 这一列,有些数据可能没有

但是对于Pandas读取的数据,他们都有隐式表示:index

对于监督学习来说,数据中都有一列作为我们需要预测的目标

而除了 ID 以为的其他数据都是特征

即:一列表示特征,一行表示一条数据

了解数据

对于这了解数据来说,这里很少用到Sklearn的方法,但是也是数据操作的一步

这里一般用到Pandas和Numpy相关操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看前5条数据,可以填入具体数字,表示查看前n条数据
data.head()

# 查看后5条数据
data.tail()

# 查看数据维度
data.shape

# 查看数据类型和数据量
data.info()

# 查看数据的统计学特征:max、min、mean、std、0.25、0.5、0.75、1.0 ...
data.describe()

# 一次性输出多个结果,可以将上述方法填入,一次性输出
display(..., ..., ...)

具体的数据查看方法Pandas和Numpy有很多,可以自己查询需要的

数据清洗

缺失值处理

缺失值是指在数据集中某些特征的值缺失

机器学习算法通常无法直接处理缺失值,因此我们需要对缺失值进行处理

检查缺失值

首先,检查数据集中是否有缺失值

通常可以使用 pandas 来查看数据集中的缺失值:

1
2
3
4
5
import pandas as pd

data.isnull().sum() # 查看每一列缺失值的数量

data.info() # 能够更直观的看到哪些列有缺失数据

填充缺失值

对于缺失值的处理,最常用的方法是填充

常见的填充策略包括:

  • 填充均值(Mean):适用于数值型数据
  • 填充中位数(Median):对于含有离群值的数据集,使用中位数可能更有效
  • 填充最频繁值(Mode):适用于类别型数据

除了上述三种,还有更多的方式,要根据实际情况操作,且填充的数据需要有填充的理由

且填充数据不可一次性填充全局的缺失值,一个特征一个特征的填充

SKlearn方法:

1
2
3
4
5
from sklearn.impute import SimpleImputer

# 对于数值型数据,使用均值填充
imputer = SimpleImputer(strategy='mean') # 可选:'mean', 'median', 'most_frequent'
data = imputer.fit_transform(data) # 填充缺失值

Pandas方法:

1
2
3
4
import Pandas as pd

# fill_data:需要填充到缺失处的数据
data = data['含缺失值的特征'].fillna(fill_data)

删除缺失值:

1
data = data.dropna()  # 删除包含缺失值的行

缺失值是常见的数据清洗操作,除此之外,还有很多需要清洗的情况:

  • 例如同一个特征内的数据类型不一致

  • 存在数据异常(有些值超出常识范围)

这些问题的处理具体可以学习数据分析,之前的文章讲过

数据预处理

数据预处理其实和特征工程的区分度不怎么大,因为本质都是为了模型更好的学习,而对数据进行加工,数据预处理这里一般都是对数据进行映射,或者数据衍生等等操作

具体还没有涉及需要 Sklearn 的方法

而对于数据缩放,我们将其放到特征工程这一类

特征工程

特征缩放

对于使用梯度下降算法的机器学习算法,其对数据的尺度很敏感,对于一些超出一般范围的数据,梯度将会消失或者爆炸,减缓收敛速度

以及某些数值很大的特征主导学习过程,这对模型的学习十分不利

其实不仅仅对于梯度下降算法,对于其他算法也一样有影响,例如太大的数据会增加模型的计算量,增加模型训练时间

所以说,对于一些数据,我们可以对其进行缩放

常见的缩放方法有:

  • 标准化(Standardization):将数据转换为均值为0、标准差为1的分布。适用于大多数机器学习算法
  • 归一化(Normalization):将数据缩放到指定范围(通常是 [0, 1])

标准化

标准化可以通过 StandardScaler 实现,它会将每个特征转换为零均值和单位方差:

1
2
3
4
5
6
7
8
9
10
from sklearn.preprocessing import StandardScaler

# 初始化 标准化对象
sc = StandardScaler()

# 全局标准化 data
data = sc.fit_transform(data)

# 对部分特征标准化
data['需要标准化的特征'] = sc.fit_transform(data['需要标准化的特征'])

归一化

归一化将每个特征缩放到一个指定的范围(通常是 [0, 1])

MinMaxScaler 用于将数据进行归一化:

1
2
3
4
5
6
7
8
9
10
from sklearn.preprocessing import MinMaxScaler

# 初始化 归一化对象
sc = MinMaxScaler()

# 全局归一化 data
data = sc.fit_transform(data)

# 对部分特征归一化
data['需要归一化的特征'] = sc.fit_transform(data['需要归一化的特征'])

特征选择

特征选择是通过选择最重要的特征来提高模型的性能,并减少计算成本

常见的特征选择方法包括:

基于模型的特征选择

使用一些机器学习模型(如 决策树随机森林 )来评估特征的重要性,从而进行特征选择

1
2
3
4
5
6
7
8
9
from sklearn.ensemble import RandomForestClassifier

# 训练一个随机森林模型
clf = RandomForestClassifier()
clf.fit(X_train, y_train)

# 获取特征重要性
importances = clf.feature_importances_
print(importances)

递归特征消除(Recursive Feature Elimination,RFE)

RFE 是一种通过递归的方式,逐步删除最不重要的特征,从而选择最优特征的方法

RFE 可以帮助我们自动选择重要特征

1
2
3
4
5
from sklearn.feature_selection import RFE

# 使用线性模型进行递归特征消除
rfe = RFE(clf, n_features_to_select=3) # 保留 3 个最重要的特征
X_rfe = rfe.fit_transform(X_train, y_train)

除了上述方法,还可以调用数据的相关系数方法,查看特征之间的相关性系数进行选择

字符串数据处理

机器学习模型通常无法直接处理字符串类型的类别变量,因此需要将类别变量转化为数值型数据

常见的编码方法有:

标签编码

标签编码将每个类别映射到一个唯一的整数

适用于类别之间有顺序关系的情况(例如,低、中、高)

1
2
3
4
5
6
7
from sklearn.preprocessing import LabelEncoder

# 初始化操作对象
label_encoder = LabelEncoder()

# 将类别变量转换为整数
data['需要编码的特征'] = label_encoder.fit_transform(data['需要编码的特征'])

独热编码

独热编码将每个类别转换为一个二进制的向量,适用于类别之间没有顺序关系的情况(例如,颜色、国家等)

OneHotEncoder 可以将类别变量转化为独热编码

1
2
3
4
5
6
7
from sklearn.preprocessing import OneHotEncoder

# 初始化操作对象
encoder = OneHotEncoder(sparse=False) # sparse=False 返回一个密集矩阵

# 将类别变量转换为独热编码
data['需要编码的特征'] = encoder.fit_transform(data['需要编码的特征'])

在 pandas 中,也可以使用 get_dummies() 函数进行独热编码:

1
2
# 直接把所有数据丢入,自动识别字符串数据并进行转换
data = pd.get_dummies(data)

处理不平均样本

在分类问题中,如果数据集的各类别样本数量差异较大,可能会导致模型偏向预测多数类,从而影响模型的性能

常见的处理方法包括:

过采样(Over-sampling)

通过增加少数类样本的数量,使得数据集更加平衡

常见的方法是使用 SMOTE(Synthetic Minority Over-sampling Technique) 算法

1
2
3
4
5
6
7
from imblearn.over_sampling import SMOTE

# 初始化操作对象
smote = SMOTE()

# 传入特征矩阵和目标向量
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)

下采样(Under-sampling)

通过减少多数类样本的数量,使得数据集更加平衡

1
2
3
4
5
6
7
from imblearn.under_sampling import RandomUnderSampler

# 初始化操作对象
undersampler = RandomUnderSampler()

# 传入特征矩阵和目标向量
X_resampled, y_resampled = undersampler.fit_resample(X_train, y_train)

其他操作

特征提取

特征提取旨在从原始特征中提取出新的、更具表达力的特征

常见的特征提取方法包括: 主成分分析(PCA)线性判别分析(LDA)

主成分分析(PCA)

PCA 是一种常用的降维技术,它通过线性变换将数据从高维空间映射到低维空间,使得新特征(主成分)尽可能保留数据的方差

PCA 特别适用于特征数量过多的情况,可以有效降低计算复杂度

1
2
3
4
5
from sklearn.decomposition import PCA

# 假设 X 是特征矩阵
pca = PCA(n_components=2) # 降维到 2 个主成分
X_pca = pca.fit_transform(X)

PCA 主要用于两种场景:

  • 降维:当特征过多时,使用 PCA 降维可以减少计算成本,同时保留数据的主要信息
  • 可视化:将高维数据映射到 2D 或 3D 空间,帮助我们可视化数据结构

线性判别分析(LDA)

LDA 是一种监督学习的降维方法,它旨在找到一个线性组合,使得不同类别之间的距离最大化,类别内的距离最小化

LDA 通常用于分类任务中

1
2
3
4
5
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# 假设 X 是特征矩阵,y 是目标变量
lda = LinearDiscriminantAnalysis(n_components=2) # 降维到 2 个线性判别组件
X_lda = lda.fit_transform(X, y)

模型训练

数据集分割

在实际应用中,通常需要将数据集分割成训练集和测试集

scikit-learn 提供了一个方便的函数 train_test_split() 来实现这一点:

1
2
3
4
from sklearn.model_selection import train_test_split

# X为特征矩阵, y为目标向量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
  • 以上代码调用 train_test_split 函数,并将结果赋值给四个变量:X_trainX_testy_trainy_test
  • Xy 是传入 train_test_split 函数的参数,它们分别代表特征数据集和目标变量(标签)。通常 X 是一个二维数组,y 是一个一维数组
  • test_size=0.3 参数指定了测试集的大小应该是原始数据集的 30%。这意味着 70% 的数据将被用作训练集,剩下的 30% 将被用作测试集
  • random_state=42 参数是一个随机数种子,用于确保每次分割数据集时都能得到相同的结果。这在实验和模型验证中非常有用,因为它确保了结果的可重复性

X和y都需要在data数据中进行分割,具体操作很简单,使用Pandas就可以实现

当然,你也可以自己手动分割数据集

优化策略

交叉验证

交叉验证的概念

交叉验证(Cross-Validation)是一种用于评估模型性能的技术,它通过将数据集分成多个子集(折叠),并多次训练和测试模型来获得更稳定、可靠的评估结果

交叉验证有助于检测模型是否过拟合,并且能够更准确地评估模型的泛化能力

常见的交叉验证方法包括:

  • K-fold 交叉验证:将数据分成 K 个折叠,依次选择其中一个折叠作为测试集,其他 K-1 个折叠作为训练集,重复 K 次,最后计算 K 次的结果平均值
  • 留一法交叉验证(Leave-One-Out Cross-Validation, LOOCV):每次只保留一个数据点作为测试集,剩余的作为训练集。这种方法非常耗时,但可以用于小数据集
  • 分层 K-fold 交叉验证:在 K-fold 中,确保每个折叠中的类别分布与整个数据集相似,适用于类别不平衡的情况

scikit-learn 提供了多种交叉验证的方法,如 cross_val_score 和 cross_val_predict 等,可以帮助我们高效地进行交叉验证

使用 cross_val_score 进行 K-fold 交叉验证

cross_val_score 函数用于执行 K-fold 交叉验证,返回每个折叠的评分结果,帮助我们评估模型的稳定性和性能

使用 cross_val_score 执行 K-fold 交叉验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier

# 加载数据
data
# 对data进行分割产生的特征矩阵和目标向量
X, y

# 创建模型
model = RandomForestClassifier()

# 执行 K-fold 交叉验证
scores = cross_val_score(model, X, y, cv=5) # 5-fold 交叉验证
print(f"Cross-validation scores: {scores}")
print(f"Mean accuracy: {scores.mean()}")
  • cv=5:表示进行 5 折交叉验证
  • scores:返回每一折的评分,最终结果是这些评分的平均值,表示模型的性能

使用 StratifiedKFold 进行 K-fold 交叉验证

1
2
3
4
5
6
7
8
9
10
11
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.ensemble import RandomForestClassifier

# 设置K折交叉验证
kfold = StratifiedKFold(n_splits=10)

# 创建模型
model = RandomForestClassifier()

# 将kfold填入任何具有 cv 参数的模型中,例如:
cross_val_score(model, X, y, cv=kfold, scoring='accuracy')

超参数优化

网格搜索 GridSearchCV

GridSearchCV 是一种通过穷举搜索所有超参数组合来找到最佳超参数的技术

GridSearchCV 通过提供一组参数的候选值,计算每一种组合的性能,最终选择最佳的参数组合

GridSearchCV 的常见参数:

  • param_grid:待调优的超参数网格,通常是一个字典,键是参数名,值是参数的候选值
  • cv:交叉验证的折数,通常设置为 5 或 10

scikit-learn 使用 GridSearchCV 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC

# 加载数据
data
# 对data进行分割产生的特征矩阵和目标向量
X, y

# 创建模型
model = SVC()

# 定义超参数网格
param_grid = {'kernel': ['linear', 'rbf'], 'C': [1, 10, 100]}

# 执行网格搜索
grid_search = GridSearchCV(model, param_grid, cv=5)
grid_search.fit(X, y)

# 输出最佳参数和最佳得分
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best score: {grid_search.best_score_}")
  • grid_search.best_params_:返回网格搜索中表现最好的超参数组合
  • grid_search.best_score_:返回最佳参数组合下的交叉验证得分

随机搜索 RandomizedSearchCV

RandomizedSearchCV 是一种更高效的超参数调优方法,它通过从超参数空间中随机选择一定数量的组合进行评估,从而加速调优过程

RandomizedSearchCV 适用于超参数空间较大时,可以节省计算时间

RandomizedSearchCV 的常见参数:

  • param_distributions:待调优的超参数分布,通常是一个字典,值可以是分布对象(如 scipy.stats 中的分布)或者离散的值列表
  • n_iter:随机搜索的迭代次数,即随机选择的超参数组合数量

scikit-learn 使用 RandomizedSearchCV 实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from sklearn.model_selection import RandomizedSearchCV
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from scipy.stats import uniform

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 创建模型
model = SVC()

# 定义超参数分布
param_distributions = {'C': uniform(0, 10), 'kernel': ['linear', 'rbf']}

# 执行随机搜索
random_search = RandomizedSearchCV(model, param_distributions, n_iter=10, cv=5)
random_search.fit(X, y)

# 输出最佳参数和最佳得分
print(f"Best parameters: {random_search.best_params_}")
print(f"Best score: {random_search.best_score_}")
  • random_search.best_params_:返回随机搜索中表现最好的超参数组合
  • random_search.best_score_:返回最佳参数组合下的交叉验证得分

模型训练

分类模型

分类问题是机器学习中最常见的问题之一,其目的是将输入数据映射到离散的类别标签

常见的分类模型有逻辑回归、K-近邻、支持向量机、决策树和随机森林等

逻辑回归(Logistic Regression)

逻辑回归是一种经典的线性分类模型,虽然名字中有"回归",但它实际上用于二分类问题。它通过将线性回归的输出通过逻辑函数(sigmoid)映射到 0 和 1 之间,从而预测事件的概率

scikit-learn 实现:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

# 假设 X 是特征矩阵,y 是标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = LogisticRegression()
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

K-近邻(K-Nearest Neighbors, KNN)

K-近邻(KNN)是一种基于实例的学习方法,预测时通过计算待预测样本与训练集中所有样本的距离,选取距离最近的 K 个邻居,并根据邻居的标签进行预测

主要参数:

  • K:选择的邻居数量
  • 距离度量:常用欧氏距离,也可以使用曼哈顿距离、闵可夫斯基距离等

scikit-learn 实现:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split

# 假设 X 是特征矩阵,y 是标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = KNeighborsClassifier(n_neighbors=3)
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

支持向量机(Support Vector Machine, SVM)

支持向量机是一种强大的分类模型,尤其适用于高维数据

SVM 的基本思想是找到一个超平面,使得不同类别的样本点之间的间隔最大化。对于非线性可分的数据,SVM 通过核技巧将数据映射到高维空间,找到一个分隔超平面

核函数:

  • 线性核:适用于线性可分的数据
  • 高斯径向基核(RBF):适用于非线性数据
  • 多项式核:适用于具有多项式关系的数据

scikit-learn 实现:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

# 假设 X 是特征矩阵,y 是标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = SVC(kernel='linear') # 使用线性核
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

决策树与随机森林(Decision Tree & Random Forest)

决策树是一种树形结构的分类模型,通过对数据进行分裂,最终将数据划分到不同的类别。随机森林则是通过构建多棵决策树,并通过投票或平均来决定最终的预测结果

决策树通过选择最优的特征进行数据划分,选择准则通常是 信息增益基尼系数

随机森林通过多棵决策树的集成来减少过拟合,并提高模型的准确性。它通过引入随机性(如随机选择特征、随机选择数据子集)来增加模型的多样性

scikit-learn 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

# 假设 X 是特征矩阵,y 是标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 决策树
dt_model = DecisionTreeClassifier()
dt_model.fit(X_train, y_train)

# 随机森林
rf_model = RandomForestClassifier(n_estimators=100)
rf_model.fit(X_train, y_train)

# 预测
dt_pred = dt_model.predict(X_test)
rf_pred = rf_model.predict(X_test)

回归模型

回归问题的目标是预测一个连续的输出变量。常见的回归模型包括线性回归、岭回归和 Lasso 回归

线性回归(Linear Regression)

线性回归通过拟合一条直线来预测目标变量。其核心假设是特征与目标变量之间存在线性关系

scikit-learn 实现:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

# 假设 X 是特征矩阵,y 是目标变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

model = LinearRegression()
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

岭回归(Ridge Regression)

岭回归是线性回归的一个变种,使用 L2 正则化 来约束模型的复杂度,避免过拟合。通过惩罚回归系数的大小,岭回归能更好地处理多重共线性问题

scikit-learn 实现:

1
2
3
4
5
6
7
from sklearn.linear_model import Ridge

model = Ridge(alpha=1.0) # alpha 是正则化参数
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

Lasso 回归(Lasso Regression)

Lasso 回归也是线性回归的一种形式,它使用 L1 正则化 来对回归系数进行惩罚。与岭回归不同,Lasso 会将一些回归系数压缩到零,从而实现特征选择

scikit-learn 实现:

1
2
3
4
5
6
7
from sklearn.linear_model import Lasso

model = Lasso(alpha=0.1) # alpha 是正则化参数
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

聚类模型

聚类是一种无监督学习方法,其目标是将数据集中的对象分为不同的组(或簇),使得同一簇中的对象尽可能相似,而不同簇之间的对象尽可能不同

K-均值(K-Means)

K-均值是一种常见的聚类算法,目标是将数据分为 K 个簇,通过最小化每个数据点与其簇中心的距离来优化簇划分

scikit-learn 实现:

1
2
3
4
5
6
7
8
from sklearn.cluster import KMeans

# 假设 X 是特征矩阵
model = KMeans(n_clusters=3)
model.fit(X)

# 获取聚类标签
labels = model.predict(X)

DBSCAN(密度聚类)

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它通过寻找密度相对较高的区域来进行聚类,不需要事先指定簇的数量

scikit-learn 实现:

1
2
3
4
5
6
7
8
from sklearn.cluster import DBSCAN

# 假设 X 是特征矩阵
model = DBSCAN(eps=0.5, min_samples=5)
model.fit(X)

# 获取聚类标签
labels = model.labels_

层次聚类(Hierarchical Clustering)

层次聚类是一种通过递归地合并或分割簇的方式进行聚类的方法。常用的层次聚类方法有 凝聚型聚类(Agglomerative)和 分裂型聚类(Divisive)

scikit-learn 实现:

1
2
3
4
5
from sklearn.cluster import AgglomerativeClustering

# 假设 X 是特征矩阵
model = AgglomerativeClustering(n_clusters=3)
labels = model.fit_predict(X)

模型评估

分类模型评估

使用 classification_report, confusion_matrix, roc_auc_score

对于分类模型,我们通常使用精度、召回率、F1 分数等指标来评估模型性能

scikit-learn 提供了许多评估工具,帮助我们深入了解模型的表现

classification_report - 提供了精度、召回率、F1 分数和支持度(每个类别的样本数)等信息

1
2
3
4
from sklearn.metrics import classification_report

# 假设 y_test 是真实标签,y_pred 是模型预测结果
print(classification_report(y_test, y_pred))

confusion_matrix - 混淆矩阵用于显示分类模型在各个类别上的表现,特别是如何将正类预测为负类,反之亦然

1
2
3
4
from sklearn.metrics import confusion_matrix

# 假设 y_test 是真实标签,y_pred 是模型预测结果
print(confusion_matrix(y_test, y_pred))

roc_auc_score - ROC AUC(接收者操作特征曲线下面积)是评估分类模型性能的指标,尤其适用于不平衡数据集。AUC 值越高,模型性能越好

1
2
3
4
from sklearn.metrics import roc_auc_score

# 假设 y_test 是真实标签,y_pred_proba 是模型预测的概率值
print(f"ROC AUC Score: {roc_auc_score(y_test, y_pred_proba)}")

回归模型评估

使用 mean_squared_error, r2_score

对于回归问题,常用的评估指标包括 均方误差(MSE) 和 决定系数(R²)

mean_squared_error - 均方误差是回归模型的常见评估标准,计算预测值与真实值之间的平方误差的均值

1
2
3
4
from sklearn.metrics import mean_squared_error

# 假设 y_test 是真实值,y_pred 是预测值
print(f"Mean Squared Error: {mean_squared_error(y_test, y_pred)}")

r2_score - 决定系数 R² 用于衡量模型对数据的拟合程度,值越接近 1,表示模型拟合得越好

1
2
3
4
from sklearn.metrics import r2_score

# 假设 y_test 是真实值,y_pred 是预测值
print(f"R² Score: {r2_score(y_test, y_pred)}")

结果保存

在预测之后,可以将预测结果保存为CSV文件:

1
2
3
4
5
6
7
8
9
# 将预测结果与其唯一标签组成数据集
y_pred = model.predict(test_X)
result = pd.DataFrame()

result['唯一标识列'] = test_X['唯一标识列'][test_X['目标列'].isnull()]
result['目标列'] = y_pred

# 保存模型
result.to_csv('.../result.csv', index=False)

模型保存

在机器学习中,模型的训练过程通常是耗时的,为了避免每次重新训练模型,我们可以将训练好的模型保存下来,便于以后进行加载和预测

scikit-learn 提供了两种常用的方式来保存和加载模型:joblibpickle

使用 joblib 保存与加载模型

joblib 是一个高效的 Python 序列化工具,特别适合用于保存包含大量数值数组(如 numpy 数组、scikit-learn 模型等)的对象。相较于 picklejoblib 在处理大规模数据时更高效

joblib 是 Python 的一个外部库,可以通过以下命令安装:

1
pip install joblib

保存模型

joblib 提供了一个简单的 API 来保存和加载对象

我们可以使用 joblib.dump() 方法将模型保存到文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import joblib
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建并训练模型
model = SVC(kernel='linear')
model.fit(X_train, y_train)

# 保存模型到文件
joblib.dump(model, 'svm_model.joblib')

加载模型

使用 joblib.load() 方法加载保存的模型对象

1
2
3
4
5
6
7
8
# 加载保存的模型
loaded_model = joblib.load('svm_model.joblib')

# 使用加载的模型进行预测
y_pred = loaded_model.predict(X_test)

# 打印预测结果
print("Predictions:", y_pred)

使用 pickle 保存与加载模型

pickle 是 Python 内置的模块,允许将 Python 对象序列化和反序列化

虽然 joblib 更适用于处理大量数据,但 pickle 也是常用的保存和加载模型的工具,适用于一般情况

保存模型

与 joblib 类似,pickle 也有简单的 API 来保存和加载对象

保存模型的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pickle
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建并训练模型
model = SVC(kernel='linear')
model.fit(X_train, y_train)

# 使用 pickle 保存模型
with open('svm_model.pkl', 'wb') as f:
pickle.dump(model, f)

加载模型

使用 pickle.load() 加载模型:

1
2
3
4
5
6
7
8
9
# 使用 pickle 加载保存的模型
with open('svm_model.pkl', 'rb') as f:
loaded_model = pickle.load(f)

# 使用加载的模型进行预测
y_pred = loaded_model.predict(X_test)

# 打印预测结果
print("Predictions:", y_pred)

joblib vs pickle

joblib 和 pickle 是保存和加载模型的两种常用方法

joblib 更适合保存大型数据对象,而 pickle 是 Python 的标准序列化工具,适用于一般情况

  • joblib:通常适用于保存包含大量数值数据(如 numpy 数组)的对象。joblib 在处理大规模数据时比 pickle 更高效
  • pickle:适用于保存较小的对象或常规的 Python 对象。它是 Python 的内置库,使用时无需额外安装

如果模型中包含大量数值数组或矩阵(如支持向量机、随机森林等),推荐使用 joblib,它比 pickle 更高效。对于较小的模型或不包含大量数值数据的模型,pickle 足够使用

其他

Sklearn 还有其他操作,例如:管道(Pipeline)

Sklearn 中的管道和 PyTorch 和 TensorFlow 中的顺序容器差不多,在里面放入对应操作,使用其对象即可顺序执行里面的操作,十分方便。 Sklearn管道参考教程

本教程适合Sklearn入门学习,如要使用高阶操作,请移步至官方文档

如有任何问题可以留言或者点击左侧邮箱联系...

作者

heimaolala

发布于

2025-06-20

更新于

2025-06-20

许可协议

评论