机器学习常见模型的sklearn实践详解
目录
各大模型详解
K_means
K-Means是一种基于距离的划分聚类算法,通过迭代将数据点分配到K个簇中,使得每个点与其所属簇中心(质心)的距离平方和最小。(即最小化 惯性(Inertia),簇内误差平方和(Within-cluster Sum-of-Squares, WCSS))

核心参数
| 参数 | 默认值 | 详细说明 |
|---|---|---|
n_clusters | 8 | 最重要的参数。即 $K$ 值,决定生成的簇数量。 |
init | 'k-means++' | 初始化中心点策略。'k-means++' 比 'random' 更智能,能加速收敛并避免陷入局部最优。 |
n_init | 'auto' | 算法运行次数。由于初始点随机,运行多次并选 Inertia 最小的那次作为最终结果。 |
max_iter | 300 | 单次运行的最大迭代次数。 |
tol | 1e-4 | 收敛阈值。如果中心点移动距离小于此值,算法提前停止。 |
algorithm | 'lloyd' | 计算算法。'lloyd' 是标准算法,'elkan' 在某些平衡数据集上效率更高。 |
重要属性 (Attributes)
训练完成后(fit 之后),通过以下属性获取结果:
-
cluster_centers_: 返回坐标阵,形状为[n_clusters, n_features],即每个簇的中心点。 -
labels_: 每个样本对应的簇标签。 -
inertia_: 最终的 WCSS 值。用于“手肘法”判定 K 值。 -
n_iter_: 实际迭代次数。 -
cluster_centers_: 簇中心, 形状: (n_clusters, n_features) -
.n_features_in_: 特征数
关键流程与细节
A. 数据预处理
KMeans 基于欧氏距离,因此:
-
标准化:必须进行
StandardScaler或MinMaxScaler。如果特征 A 范围是 0-1,特征 B 是 0-10000, B 会主导距离计算。 -
降维:高维数据(如文本向量)会导致距离失效,建议先用
PCA或TruncatedSVD。
B. k-means++ 初始化逻辑
-
随机选第一个中心点。
-
计算其余点到已有中心点的距离。
-
概率选择:离现有中心越远的点,被选为下一个中心的概率越大。这有效解决了初始点靠太近的问题。
效果评估工具
内部评价指标(无标签)
-
Inertia (手肘法): 找下降速度剧减的拐点。
-
Silhouette Score (轮廓系数): 接近 1 最好。使用
sklearn.metrics.silhouette_score。 -
Calinski-Harabasz Index: 簇间离散度与簇内离散度的比值,越大越好。
外部评价指标(有标签)
-
Adjusted Rand Index (ARI): 衡量两个聚类结果的相似度,接近 1 最好。
-
Normalized Mutual Information (NMI): 归一化互信息。
变体与进阶模型
如果数据量巨大或形状奇特,KMeans 并非唯一选择:
-
MiniBatchKMeans:
-
特点:使用小批量数据更新中心点。
-
场景:样本量 > 10 万时使用,速度极快,精度损失微小。
-
-
BisectingKMeans (二分K均值):
-
特点:从一个大簇开始,不断二分,直到达到 $K$ 个。
-
场景:结果更稳定,对初始化不敏感。
-
注:KMeans只接受二维数据,所以处理图片时要先转成二维
绘制样本函数
make_blobs函数
门用于生成聚类(Clustering)数据集。它产生的点服从正态分布(高斯分布)。
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0, random_state=42)
# 2. 绘制散点图
# X[:, 0] 是横轴,X[:, 1] 是纵轴,c=y 根据类别上色
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap='viridis')
plt.title("make_blobs Clustering Data")
plt.show()
核心参数
| 参数 | 含义 | 说明 |
|---|---|---|
n_samples | 样本总数 | 如果是整数,则是总数;如果是数组,可指定每个簇的数量。 |
n_features | 特征数 | 也就是数据的维度。默认是 2(方便画 2D 图)。 |
centers | 簇的数量 | 决定生成几个“团”。也可以直接传入坐标点。 |
cluster_std | 标准差 | 决定簇的松散程度。值越大,点越分散,簇之间重叠越多。 |
random_state | 随机种子 | 保证每次运行生成的图形一模一样。 |
make_circles函数
生成两层嵌套的圆环,用来测试线性不可分问题。
from sklearn.datasets import make_circles X, y = make_circles(n_samples=100, shuffle=True, noise=None, random_state=None, factor=0.8)
核心参数
| 参数 | 含义 | 说明 |
|---|---|---|
n_samples | 总样本数 | 默认是一半样本在外圈,一半在内圈。 |
noise | 噪声(抖动) | 类似于给圆环加“毛刺”。值越大,圆环越模糊,分类越难。 |
factor | 内外圆比例 | 内圆半径与外圆半径的比值。范围在 $(0, 1)$。值越小,两圆分得越开。 |
shuffle | 打乱顺序 | 是否将数据点的生成顺序打乱。 |
make_classification函数
可以模拟出特征之间的相关性、冗余特征、甚至带有错误标签的“脏数据”。
from sklearn.datasets import make_classification X, y = make_classification(n_samples=100, n_features=20, n_informative=2, n_redundant=2, n_classes=2, flip_y=0.01, random_state=42)
核心参数
| 参数 | 类别 | 含义 | 说明 |
|---|---|---|---|
n_features | 特征数量 | 样本的特征数量 | 默认 n_features=20,如果画图要手动设为2. |
n_informative | 有用特征 | 真正对分类有贡献的特征。 | 模型应该学习的特征。 |
n_redundant | 冗余特征 | 由有用特征线性组合生成的。 | 增加特征间的共线性。 |
n_repeated | 重复特征 | 随机从有用和冗余特征里复制出来的。 | 测试模型过滤重复信息的能力。 |
flip_y | 噪声标签 | 随机翻转标签的比例(默认 0.01)。 | 模拟数据录入错误。 |
class_sep | 类别分离度 | 越大,类别之间分得越开(越容易)。 | 默认 1.0。 |
weights | 样本比例 | 传入列表,如 [0.1, 0.9]。 | 模拟样本不均衡(如信贷违约)。 |
PCA
PCA 是一种线性无监督降维算法。
-
核心目标:通过线性旋转,找到数据方差最大的方向(主成分),在保留绝大部分信息的同时减少特征维度。
-
数学底蕴:
sklearn的 PCA 默认使用 SVD(奇异值分解) 来寻找主成分,而不是直接计算协方差矩阵的特征值分解,这使得它在处理高维数据时更加稳定。
基本语法
from sklearn.decomposition import PCA X_dr = PCA(n_components=2). fit_transform(X)
核心参数
| 参数 | 默认值 | 详细说明 |
|---|---|---|
n_components | None | 最关键参数。可以传整数(降到几维),也可以传 0~1 之间的浮点数(如 0.95,表示保留 95% 的方差/信息量)。 |
whiten | False | 白化。设为 True 会使每个特征的方差变为 1。常用于下游模型是 SVM 或神经网络的场景。 |
svd_solver | 'auto' | SVD 解算器。包括 'full'(精确)、'arpack'、'randomized'(大数据集效率高)。 |
random_state | None | 当使用随机解算器时,设置此项可保证结果可复现。 |
重要属性 (Attributes)
训练完成后(fit 之后),这些属性是分析数据的关键:
-
components_: 主成分的方向(特征空间的轴)。形状为[n_components, n_features]。 -
explained_variance_: 每个主成分所解释的方差绝对值。 -
explained_variance_ratio_: 极其重要。每个主成分解释方差的百分比。用于判断信息丢失程度。 -
n_components_: 实际保留的主成分数量(尤其是当你传浮点数作为参数时,可以用这个查看降到了几维)。
关键操作流程
A. 必须先标准化
PCA 对数据的量纲非常敏感。
注意:必须使用 StandardScaler(均值为 0,方差为 1),而不仅仅是缩放到 0-1。因为 PCA 是寻找方差最大的方向,如果某个特征数值极大,它会被误认为是一个主要成分。
B. 决定降到几维?(碎石图法)
通过观察 explained_variance_ratio_ 的累积和来决定:
import numpy as np pca = PCA().fit(X_scaled) cumulative_variance = np.cumsum(pca.explained_variance_ratio_) k = np.argmax(cumulative_variance >= 0.90) + 1 # 找到覆盖 90% 方差所需的维数 # 可以画累计可解释方差贡献率曲线 # 注,原本有n个特征,pca降维时最多保留min(n_samples - 1, n_features)个特征,生成的会是新的特征空间,降维过程中pca先找到数据中方差最大的方向(第一主成分),把能抓取的信息全部抓走;剩下的“残差”里再找方差最大的(第二主成分),以此类推(即在多维空间里先找能看到最多信息的观测视角,第二次找垂直于第一次方向的观测视角)。所以不管主成分设为几个,PC1 包含的信息量(方差)是固定的,选 K=2 还是 K=3,只是决定了从这个排好序的“信息池”里取前几个而已,已经生成的 PC1 不会因为多要了一个 PC3 而改变。
未完成练习:手写数字识别的PCA和随机森林结合
决策树
决策树(Decision Trees)是属于 sklearn.tree 模块的核心算法。它既能做分类(DecisionTreeClassifier),也能做回归(DecisionTreeRegressor)。
核心工作原理
决策树通过一系列“if-then-else”的逻辑判断,将特征空间切分为一个个矩形区域。
-
分类标准:默认使用 Gini 系数(基尼指数),也可以选择 Entropy(信息熵)。
-
回归标准:默认使用 Squared Error(均方误差 MSE)。
-
算法实现:
sklearn使用的是 CART(Classification and Regression Trees)算法的优化版本,它生成的始终是二叉树。
核心参数详解 (Parameters)
决策树极易过拟合,因此理解这些“剪枝”参数至关重要:
| 参数 | 默认值 | 作用与建议 |
|---|---|---|
criterion | 'gini'(基尼系数) | 衡量分裂质量的指标。分类可选 'entropy'(信息增益);回归可选 'squared_error'。 |
max_depth | None | 预剪枝核心。限制树的最大深度。如果不设置,树会一直生长直到叶子纯净。 |
min_samples_split | 2 | 拆分内部节点所需的最小样本数。增加此值可防止模型学习过于细碎的规则。 |
min_samples_leaf | 1 | 叶子节点必须包含的最小样本数。非常有效的平滑模型手段。 |
max_features | None | 寻找最佳分裂点时考虑的特征数量。设为 'sqrt' 常用于降低方差。 |
ccp_alpha | 0.0 | 后剪枝参数。通过代价复杂度剪枝,值越大,剪枝越厉害。 |
splitter | best | 模型在每个节点如何寻找划分点。best遍历所有可能的切分点,选择能够最大程度降低不纯度的那个;random随机抽取一部分切分点,并从中选出最好的一个。 |
min_impurity_decrease | 0.0 | 关注划分的质量,设定一个阈值,只有当分裂产生的不纯度(Impurity,如 Gini 或 Entropy)下降值大于或等于这个值时,节点才会进行分裂。 |
best结果相对稳定,生成的树通常比较精简,预测精度高。但计算慢且容易过拟合。
random速度快,抗过拟合,但单棵树的效果通常不如 "best"且因为切分不是最优的,可能需要更多层才能达到相同的纯度。
重要属性与方法
训练完成后,可以通过这些“探针”查看模型学到了什么:
-
feature_importances_: 极其重要。返回每个特征对减小不纯度的贡献(特征重要性)。 -
tree_: 底层树对象,可以访问节点的阈值、左孩子、右孩子等详细信息。 -
apply(X): 返回每个样本最终落在了哪个叶子节点的索引。 -
predict: 返回每个样本的分类/回归结果 -
cost_complexity_pruning_path: 返回剪枝路径,帮助你寻找最佳的ccp_alpha。
可视化
这是决策树最强大的地方——白盒模型,可解释性极强。
from sklearn.tree import plot_tree import matplotlib.pyplot as plt plt.figure(figsize=(12, 8)) plot_tree(clf, #训练好的模型 feature_names=iris.feature_names, #节点特征 class_names=iris.target_names, #节点类别 filled=True, # 给节点上色(颜色深浅代表纯度) rounded=True #每个节点框的棱角 ) plt.show()
优缺点
优点:
-
直观易懂:模型可以被画出来,非专业人士也能理解逻辑。
-
数据适应性强:不需要标准化/归一化(因为它是基于阈值切分的,与量纲无关)。
-
处理缺失值:能处理各种类型的数据。
缺点:
-
极易过拟合:如果不限制深度,它能记住所有训练数据的噪声。
-
不稳定:数据的一丁点变动可能导致整棵树结构完全改变(建议用随机森林解决)。
-
局部最优:它采用贪心算法分裂,不保证找到全局最优树。
实战避坑指南
-
类别不平衡:如果你的数据中 A 类占 99%,B 类占 1%,树会严重倾向于 A。请设置
class_weight='balanced'。 -
维度灾难:特征太多时,树会变得非常复杂。建议先用 PCA 降维或利用
feature_importances_剔除无用特征。 -
防止过拟合:
-
限制
max_depth(通常 3-5 层起步)。 -
增大
min_samples_leaf(防止出现只有一个样本的孤立叶子)。
-
随机森林
随机森林属于集成学习(Ensemble Learning)中的 Bagging(套袋法)。
-
核心逻辑:构建多棵独立的决策树,通过“投票”(分类)或“平均”(回归)来得出最终结果。
-
随机性的来源(双重随机):
-
样本随机:通过 Bootstrap(自助采样法),每棵树使用的样本集是从原始数据中有放回抽样得到的。
-
特征随机:在每个节点分裂时,只从随机选出的
max_features个特征中寻找最优切分点。
-
核心参数
随机森林的参数由 “树的参数” 和 “集成的参数” 两部分组成:
A. 集成专用参数(控制森林规模)
| 参数 | 默认值 | 详细说明 | 建议值 |
|---|---|---|---|
n_estimators | 100 | 核心参数。森林中树的数量。通常越多越好,但达到一定数量后精度会趋于平稳,且增加计算开销。 | 起点:100-500大数据集:200-1000 |
bootstrap | True | 是否使用有放回抽样。设为 False 则每棵树都使用全部样本。 | 保持True,核心特性 |
oob_score | False | 袋外分数。是否使用未参与训练的样本(袋外样本)来评估模型。开启后无需交叉验证即可估算泛化能力。 | 设为True获取免费验证 |
n_jobs | None | 并行计算。设为 -1 使用所有 CPU 核心。随机森林各棵树独立,并行效率极高。 | -1最快 |
B. 树的控制参数(防止过拟合)
这些参数与 DecisionTreeClassifier 完全一致:
| 参数 | 默认值 | 推荐范围 | 说明 | 调优建议 |
|---|---|---|---|---|
| max_depth | None | 分类:5-30 回归:10-50 | 树的最大深度限制 | 过拟合时减小,欠拟合时增大或设None |
| max_features | 分类:'sqrt' 回归:'n_features' | 特征数 < 10:用所有 特征数 10-100:'sqrt' 特征数 > 100:'log2' | 每次分裂考虑的特征数 | 随机森林随机性的核心,值越小抗过拟合越强 |
| min_samples_leaf | 1 | 分类:1, 2, 5 回归:5, 10, 20 | 叶节点最小样本数 | 防止生成只含少数样本的叶子,回归问题需要更大值 |
| min_samples_split | 2 | 分类:2, 5, 10, 20 回归:5, 10, 20 | 节点分枝所需最小样本数 | 可用浮点数百分比(如0.01=1%) |
| criterion | 分类:'gini' ;回归:'squared_error' | 略 | 分裂质量衡量标准 | 分类通常用gini(计算快),回归用squared_error |
调参顺序

重要属性与方法
-
estimators_: 列表,存储了森林中所有训练好的DecisionTreeClassifier对象。 -
feature_importances_: 特征重要性。随机森林给出的特征重要性通常比单棵树更鲁棒、更可靠。 -
oob_score_: 如果开启了oob_score=True,训练后可直接查看此分数。oob指袋外数据,即随机森林训练过程中的抽样没有抽到过这些数据,那这些数据也可以视作测试集评分一下。 -
predict_proba(): 返回样本属于各个类别的概率(分类专用)。
其他
为什么随机森林比单棵树好?
-
降低方差(Variance):单棵树极易过拟合。随机森林通过平均多棵树的结果,抵消了单棵树的随机误差,模型更稳健。
-
抗噪能力强:由于引入了样本和特征的随机性,模型不容易被个别异常值带偏。
-
处理高维数据:不需要降维也可以处理成千上万个特征,并能自动评估特征重要性。
性能调优建议
-
第一步:
n_estimators。先调大树的数量,直到计算成本可接受且分数不再显著上升。 -
第二步:
max_features。这是最重要的随机性参数。减小它能增加树之间的差异性,降低过拟合。 -
第三步:
max_depth或min_samples_leaf。如果模型依然过拟合,再考虑限制树的生长。
特殊情况处理
1. 处理不平衡数据
-
min_samples_leaf:设置较大值防止小类别被忽略
-
class_weight:设置为'balanced'自动调整权重
-
max_depth:适当限制深度防止对小类别过拟合
2. 处理过拟合
-
减小 max_depth
-
增大 min_samples_split 和 min_samples_leaf
-
减小 max_features(如从'sqrt'改为'log2')
-
增加 n_estimators
3. 处理欠拟合
-
增大 max_depth 或设为 None
-
减小 min_samples_split 和 min_samples_leaf
-
增大 max_features
常见陷阱与注意点
-
训练慢,预测快:虽然有并行加速,但树多了之后内存开销会很大。
-
类别不平衡:如果数据极度不平衡,记得设置
class_weight='balanced'或'balanced_subsample'。 -
无法处理序列/外推:和所有基于树的模型一样,随机森林不能很好地预测超出训练集数值范围的数据(外推性差)。
逻辑回归
经典的线性分类模型,在线性回归公式 $z = w^Tx + b$ 的基础上,套入 Sigmoid 函数,将输出映射到 (0, 1) 之间,代表属于某个类别的概率。默认以 0.5 为阈值。P > 0.5 判定为 1,否则为 0。
相关类
-
LogisticRegression(标准类)核心功能:支持 L1、L2、ElasticNet 正则化,支持二分类和多分类(OvR 或 Multinomial)。
适用场景:常规建模、手动调参。
-
LogisticRegressionCV(带交叉验证的类)内置了交叉验证功能,专门用于自动寻找最优的正则化强度参数
C。 -
SGDClassifier(随机梯度下降分类器)当它的损失函数设置为
'log_loss'(旧版本为'log')时,它就是一个使用随机梯度下降实现的逻辑回归。适合处理超大规模数据:它不是一次性把数据读入内存,而是通过迭代更新,非常省内存。支持
partial_fit,可以边读数据边训练。
核心参数
A. 正则化与惩罚
| 参数 | 默认值 | 详细说明 |
|---|---|---|
penalty | 'l2' | 惩罚项类型。可选 'l1', 'l2', 'elasticnet', None。用于防止过拟合。 |
C | 1.0 | 核心参数。正则化强度的倒数。C 越小,正则化越强,模型越简单。 |
l1_ratio | None | 仅在 penalty='elasticnet' 时使用,控制 L1 和 L2 的比例。 |
L1正则化会将参数压缩为0,L2正则化只会让参数尽量小,不会取到0
B. 求解器 (Solver) - 决定计算效率
| 选项 | 适用场景 | 特点 |
|---|---|---|
liblinear | 小数据集 | 坐标下降法。支持 L1 和 L2,但不支持多分类(需 OvR)。 |
lbfgs | 中等/大数据集 | 默认值。拟牛顿法的一种。性能稳定,仅支持 L2。 |
sag / saga | 超大数据集 | 随机平均梯度下降。saga 是唯一支持 L1、L2 和 ElasticNet 的全能选手。 |

C.重要参数
| 参数 | 默认值 | 详细说明与建议 |
|---|---|---|
max_iter | 100 | 最大迭代次数。如果模型报错 "Failed to converge",请将其调大(如 1000 或 5000)。这代表求解器在停止前最多走多少步。 |
tol | 1e-4 | 容忍度(停止准则)。当两次迭代之间的损失函数改进小于这个值时,训练提前停止。 |
random_state | None | 随机种子。虽然逻辑回归是凸优化,但在使用 sag, saga, liblinear 求解器时,初始状态会影响结果,固定它可保证实验可复现。 |
class_weight | None | 类别权重。处理不平衡数据神器。设为 'balanced' 会根据类别频率自动调整权重,让少数类受到更多关注。 |
verbose | 0 | 日志详细程度。在训练大数据集时,设为 1 或更高可以实时看到求解器的进度(这对缓解“程序是否卡死”的焦虑很有用)。 |
warm_start | False | 热启动。设为 True 时,调用 fit 会重用上一次调用的初始化结果,适合在同一数据集上微调参数。 |
fit_intercept | True | 是否拟合截距(即常数项 $b$)。如果你的数据已经预处理过且中心化了,可以设为 False。 |
除了class_weight,我们有其他处理样本不均衡的方法:采样法(上采样,通过重复来增加少数类的样本;下采样,减少多数类的样本)
D.多分类策略
-
multi_class:-
'ovr'(One-vs-Rest): 为每个类别建一个二分类器,处理二分类问题,或多分类中的一对多 -
'multinomial': 直接最小化多项式损失(Softmax),通常比 OvR 更精确。 -
auto: 自动根据数据分类情况或其他参数选择
-
重要属性
n_iter: 模型的实际迭代次数
coef_: 回归系数(权重 w)。
intercept_: 截距(偏置 b)。
predict_proba(X): 极常用。返回每个样本属于各类别的概率。
decision_function(X): 返回样本到决策边界的置信距离(z 值)。
其他
必须进行数据标准化:
逻辑回归对特征量纲非常敏感(尤其是开启正则化时)。在使用前务必进行 StandardScaler。
样本不均衡:
如果数据中 0 多 1 少,设置 class_weight='balanced',sklearn 会自动根据频率调整权重。逻辑回归使用上采样也可以很好解决样本不均衡
Solver 与 Penalty 匹配表:
-
L1 正则 $\rightarrow$ 必须用
liblinear或saga。 -
L2 正则 $\rightarrow$ 所有 solver 都支持。
-
ElasticNet $\rightarrow$ 必须用
saga。
支持向量机(SVM)
SVM 的目标是找到一个超平面,不仅能正确分隔不同类别,还要让距离该平面最近的点(即支持向量)到平面的距离最大化。
常用类
| 类名 | 用途 | 特点 |
|---|---|---|
SVC | 分类 | 最常用。基于 libsvm 实现。支持多种核函数,功能最全。 |
SVR | 回归 | 用于连续值预测。目标是让尽可能多的点落在“管道”内。 |
LinearSVC | 线性分类 | 基于 liblinear 实现。不支持核函数,但在大数据集上速度极快。 |
核心参数
调优 SVM 主要是调 C 和 Kernel 相关参数:
A. 惩罚参数
-
C(默认=1.0):-
C 越大:对错误的容忍度越低,模型试图精确分类,容易过拟合。
-
C 越小:允许更多错误以换取更宽的间隔,模型更简单,容易欠拟合。
-
如果数据的噪音比较多那最好把c调小点,比如0.02
-
B. 核函数 (kernel)
-
'linear': 线性核。适用于特征非常多(如文本分类)的情况。 -
'poly': 多项式核。阶数为1的多项核函数效果跟线性核函数差不多且运行速度更快 -
'rbf'(默认): 径向基函数(高斯核)。最强大的非线性核,能处理绝大多数复杂边界,很牛,什么类型的数据都处理的不错。 -
'sigmoid': 类似逻辑回归。凑数的吗,感觉什么数据都不擅长,笑死我了。
C. 核函数专用参数
-
gamma(仅对 rbf, poly, sigmoid 有效):-
控制单个样本影响的范围。
-
gamma 越大:模型只关注支持向量附近的点,决策边界非常复杂(容易过拟合)。
-
gamma 越小:模型关注更远的点,决策边界平滑(容易欠拟合)。
-
默认
'auto',自动使用1/(n_features)作为gamma的取值 -
输入"
scale",则使用1/(n_features * X.std())作为gamma的取值 -
输入"
auto_deprecated",则表示没有传递明确的gamma值(不推荐使用)
-
-
degree(仅对 poly 有效): 多项式的阶数,默认为3. -
coef0: 浮点数,可不填,默认=0.0,是核函数中的常数项,kernel为'poly'和'sigmoid'时有效。
D. 工程控制参数
-
probability(默认=False): 设为True后才能调用predict_proba(),表示启用概率估计,注意这会显著减慢训练速度。 -
cache_size: 训练时允许使用的内存(MB)。大数据集建议设为 500 或 1000。
重要属性
-
support_vectors_: 返回所有的支持向量。 -
n_support_: 每个类别下支持向量的数量。 -
.coef_: 每个特征的重要性,这个系数仅仅适合于线性核 -
decision_function(X): 返回样本到超平面的置信距离(对于 SVM 分类非常重要)。
其他
-
必须要进行数据标准化! SVM 是基于距离计算的。
-
SVC的计算复杂度在样本量 $N > 50,000$ 时会变得非常恐怖。如果数据量巨大,请换用LinearSVC或SGDClassifier。 -
类别不平衡: 支持向量机不推荐使用上采样,推荐设置
class_weight='balanced'来处理不平衡样本,可以手动用字典设置每个标签的权重。另外,SVC的接口fit的参数smaple_weight也可以调,输入数组,每个样本在fit时的权重。支持向量机实际是通过C来影响的,标签1的C为:权重1*C,标签2的C为:权重2 * C
支持向量机的
class_weight很好用,通过字典手动调整权重比
线性回归
模块路径:from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LinearRegression # 1. 实例化模型 reg = LinearRegression(fit_intercept=True, copy_X=True, n_jobs=None) # 2. 训练模型 reg.fit(X_train, y_train) # 3. 预测 y_pred = reg.predict(X_test)
关键参数
| 参数 | 说明 | 默认值 | 备注 |
|---|---|---|---|
fit_intercept | 是否计算截距 $w_0$。 | True | 如果数据已经中心化,可设为 False。 |
normalize | 是否进行归一化(已弃用)。 | False | 建议使用 StandardScaler 进行预处理。 |
copy_X | 是否在内存中复制 $X$。 | True | 设为 False 会覆盖原数据以节省内存。 |
n_jobs | 用于计算的 CPU 核心数。 | None | -1 表示使用全部核心。 |
重要属性
reg.coef_:返回特征的系数 w_1, w_2...(NumPy 数组)。
reg.intercept_:返回截距 w_0(标量)。
注意:在 sklearn 中,后缀带下划线 _ 的变量表示这是模型训练(fit)后才生成的。
评估指标
score(X, y):默认返回 R^2 (决定系数)。越接近 1 模型拟合越好。
(R^2的计算:均方误差除以方差)
(R^2可以使用三种方式来调用,一种是直接从metrics中导入r2_score,输入预测值和真实值后打分。第二种是直接从 线性回归LinearRegression的接口score来进行调用。第三种是在交叉验证中,输入"r2"来调用。)
(如果R^2为负,说明数据的拟合超级差,甚至不如均值)
mean_squared_error (MSE):均方误差,计算预测值与真实值差的平方。只能判断预测的数值是否正确或大部分接近,不能判断是否成功拟合了数据的变化规律和捕捉的信息量,而方差就是衡量信息量的,所以会用R^2评估。
(在交叉验证中只能调用负的均方误差。)
mean_absolute_error (MAE):平均绝对误差。
进阶变体:解决过拟合
基础线性回归(OLS)在特征过多或存在多重共线性时容易过拟合。sklearn 提供了带正则化的变体:
| 模型类 | 正则化类型 | 特点 |
|---|---|---|
Ridge (岭回归) | L2 正则化 | 压缩系数,使其接近 0 但不为 0。适合处理多重共线性。 |
Lasso | L1 正则化 | 能够将不重要的特征系数压缩为 0,对α值更加敏感。适合特征选择。不能解决多重共线性问题,只能抑制。 |
ElasticNet | L1 + L2 | 两者的折中,适合特征关联性强且特征量大的情况。 |
岭回归
岭回归在损失函数中加入的是系数的平方和(L2 惩罚项)。
其目标函数为:![]()
它会将系数向 0 压缩,但永远不会让系数真正等于 0。这意味着它保留了所有特征,只是减小了它们的权重。
#岭回归,如果一般线性模型的结果很差,就用岭回归试试,若有提升,说明特征间有多重共线性问题
from sklearn.linear_model import RidgeCV #交叉验证选最优α
from sklearn.linear_model import Ridge #一般使用
reg_cv = RidgeCV(alphas=[0.1, 1.0, 10.0]) # 自动测试,选出最好的,一般情况下α加大会削弱原本的信息
reg_cv.fit(X_train, y_train)
print(f"最佳 alpha 值: {reg_cv.alpha_}")
reg_ridge = Ridge(alpha=1.0).fit(X_train, y_train) #训练
print(reg_ridge.coef_) #查看系数
#使用岭回归后,我们期望的是R^2更大(即偏差更小,降低欠拟合),方差更小(降低过拟合),这样模型的整体性能就会很好,同时这也能说明数据确实存在多重共线性,所以岭回归的结果会有明显优势
Lasso
在普通最小二乘法(OLS)的基础上,Lasso 增加了所有回归系数绝对值的和作为惩罚项。
其目标函数为:![]()
α:正则化强度。α越大,惩罚越重,更多的系数会变成 0。
-
Alpha 最大值 ($\alpha_{max}$):这是让所有回归系数都刚好被压缩到 0 的那个临界值。如果 $\alpha$ 大于这个值,模型就是一个只剩截距的空壳。
-
Alpha 最小值 ($\alpha_{min}$):我们通常希望测试到一个足够小的 $\alpha$,使其接近普通线性回归的结果。
eps 的公式定义为:![]()
,eps用来尝试一系列alpha值,从eps*α(min)到α(max).
| 参数名称 | 默认值 | 作用 |
|---|---|---|
| eps | 1e-3 (即 0.001) | 决定了 alpha 序列中最小值与最大值的比例。 |
n_alphas | 100 | 正则化路径中alpha的个数 |
from sklearn.linear_model import Lasso
# 创建并训练模型,alpha 选得好,特征选得早
lasso = Lasso(alpha=0.1) #和岭回归的用法很类似,可以用LassoCV选择合适的alpha
lasso.fit(X_train_scaled, y_train)
print(f"回归系数: {lasso.coef_}") # 查看系数,会发现很多系数变成了 0
from sklearn.linear_model import LassoCV
# 创建模型:搜索 100 个 alpha 值,最小值是最大值的 0.01 倍
model = LassoCV(eps=0.01, n_alphas=100, cv=5)
model.fit(X_scaled, y)
print(f"Alpha 的搜索范围是从 {model.alphas_.max()} 到 {model.alphas_.min()}")
# Lasso默认评估指标是均方误差,而岭回归是R^2
| 属性 | 含义 |
|---|---|
| alpha_ | 调用交叉验证选出来的最佳正则化参数 |
| alphas_ | 使用正则化路径的长度和路径中 的个数来自动生成的,用来进行交叉验证的正则化参数 |
| mse_path | 返回所以交叉验证的结果细节 |
| coef_ | 调用最佳正则化参数下建立的模型的系数 |
分箱线性回归
通过分箱帮助线性回归解决非线性问题,将连续变量 x 划分为若干个区间,将每个区间转换为 One-Hot 编码(或普通编码),每个区间现在拥有了独立的权重(系数)。
能够拟合阶梯状或非线性的趋势;对异常值(Outliers)不敏感,一个极端的离群点只会落在最后一个箱子里,不会拉偏整个回归线;可以把“缺失”单独作为一个箱子处理,不需要删除数据。
分箱过多会导致特征空间变大,样本量不足时容易过拟合。
from sklearn.preprocessing import KBinsDiscretizer from sklearn.linear_model import LinearRegression # 1. 准备分箱工具 # encode='onehot' 会生成哑变量,让线性回归能处理 est = KBinsDiscretizer(n_bins=10, encode='onehot', strategy='quantile') #支持三种策略:uniform(等宽)、quantile(等频)和 kmeans(聚类) # 2. 转换数据 X_binned = est.fit_transform(X) # 3. 训练线性回归 reg = LinearRegression().fit(X_binned, y)
多项式回归
通过增加特征的高次幂,将非线性问题转化为线性回归问题来求解。
特征空间的升维:手动创造出 x^2, x^3, ……, x^n 作为新的特征。
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
# 1. 定义多项式阶数(Degree)
degree = 2
# 2. 使用管道(Pipeline)封装:先升维,再回归
model = Pipeline([
("poly", PolynomialFeatures(degree=degree)),
("regression", LinearRegression())
])
model.fit(X, y)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| degree | int | 2 | 最关键参数。多项式的阶数。如果是 3,则会生成 $x^3, x^2, x$ 等特征。 |
| interaction_only | bool | False | 如果设为 True,则只生成交互项(如 $x_1x_2$),而不生成特征的自乘项(如 $x_1^2$)。 |
| include_bias | bool | True | 是否包含偏差列(即截距项,特征全为 1 的那一列)。如果后续线性回归模型里设了 fit_intercept=True,这里可以设为 False。 |
| order | str | 'C' | 输出数组的内存布局(C 风格或 Fortran 风格),通常不需改动。 |
核心接口 (API)
-
get_feature_names_out(input_features=None): 强烈推荐使用。它能返回每一列新特征的名称(如x0^2,x0 x1),让你知道增加的特征到底代表什么。
欠拟合 (Underfitting):阶数太低(如 1 阶),模型太简单,无法捕捉曲线趋势。
过拟合 (Overfitting):阶数太高(如 10 阶),模型太复杂,试图穿过每一个噪声点。
最佳实践方案:
-
先用
PolynomialFeatures生成高阶特征(比如 3 阶或 5 阶)。 -
接着使用 Lasso 或 Ridge 进行正则化。
-
正则化会把那些不重要的高次幂系数压缩到趋近 0,从而在保留非线性拟合能力的同时,防止曲线过度抖动。
其他
数据缩放 (Scaling)
虽然线性回归对缩放不敏感,但带有正则化的模型(Ridge/Lasso)对缩放极其敏感。
-
在使用 Ridge/Lasso 前,必须先用
StandardScaler标准化。
线性回归的假设
(面试常考)
虽然 sklearn 能直接跑,但线性回归的有效性基于以下假设:
-
线性相关:自变量和因变量之间确实存在线性趋势。
-
误差项独立:样本之间互不影响。
-
同方差性:误差项的方差不随自变量改变。
-
正态性:误差项服从正态分布。
多重共线性
求解系数w需要用到X的逆矩阵,所以逆矩阵必须存在,而逆矩阵存在的充要条件是矩阵的行列式不能为0,求解行列式可以通过把矩阵化为上三角求解(那么最后就行列式等于对角线的乘积),因此化为上三角后对角线上不能有0,那么化之前的原矩阵就不能存在完全线性关系(精确相关关系,如第一行是三行的2倍这种)的两行。另外,如果两行不是精确相关,但是高度相关,那矩阵的行列式不为0,但很接近0,那逆矩阵就会接近无限大,直接影响w的求解。精确相关关系和高度相关关系并称为"多重共线性",在多重共线性下,模型无法建立,或者模型不可用。
注意区分多重共线性和相关性,多重共线性指的是两个之间有倍数关系,有共线性,画到坐标轴里基本重合,使用指标方差膨胀因子来进行衡量。而相关性是衡量两个或多个变量一起波动的程度的指标,它可以是正的,负的或者0,是线性相关性,比如A升B也升,它俩就正相关,A升B降了,它俩就负相关。线性相关一般由皮尔逊相关系数进行衡量,非线性相关可以使用斯皮尔曼相关系数或者互信息法进行衡量。
上述说的那些关系都是指特征之间的。岭回归是用来解决这个的,但不一定好用,毕竟也会损失一部分信息量
朴素贝叶斯
可以得到![]()
其中P(Y|X)是在特征X的前提下标签为Y的概率,为Y的后验概率;P(Y)表示没有条件的情况下标签为Y的概率,为Y的先验概率;P(X|Y)表示在标签为Y的前提下特征是X的概率,这被称为类的条件概率。
在机器学习中,P(Y)一般表示Y为正样本/少数类的概率,而P(Y|X) 是对于任意一个样本而言,具体是什么由该样本的特征是什么决定。
假设特征之间是有条件独立的,则![]()
假设特征之间是有条件独立的,可以解决众多问题,也简化了很多计算过程,这是朴素贝叶斯被称为”朴素“的理由。
求P(X)可以用全概率公式,
不过分类时有时可以不用求P(X),

在这种情况下,我们需要的是比较二者哪个大,所以可以不计算分母只考虑分子的大小。
朴素贝叶斯中连续型变量的概率估计
求解连续型变量下某个点取值的概率问题,可以转化成求解一个函数 在点 上的取值的问题。那接下来只要找到我们的 f(x),就可以求解出不同的条件概率了。fit就是在找这个 f(x)。具体为什么这么化,去看菜菜课件。
高斯朴素贝叶斯
通过假设P(xi|Y)服从高斯分布(也就是正态分布),来估计每个特征下每个类别上的条件概率。
| 参数 | 含义 |
|---|---|
| prior | 可输入任何类数组结构,形状为(n_classes,) 表示类的先验概率。如果指定,则不根据数据调整先验,如果不指定,则自行根据数据计算先验概率 。二分类这种的就让算法自己看。 |
| var_smoothing | 浮点数,可不填(默认值= 1e-9) 在估计方差时,为了追求估计的稳定性,将所有特征的方差中最大的方差以某个比例添加 到估计的方差中。这个比例,由var_smoothing参数控制。 |
用的时候让这俩都保持默认就行。
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB().fit(X,y)
print(f"各类的均值: {gnb.theta_}")
print(f"各类的方差: {gnb.var_}")
多项式朴素贝叶斯
在sklearn中,用来执行多项式朴素贝叶斯的类MultinomialNB包含如下的参数和属性:
| 参数 | 说明 |
|---|---|
| alpha | 浮点数, 可不填 (默认为1.0)。设置为0则表示完全没有平滑选项,平滑相当于人为给概率加上一些噪音,因此设置得越大,多项式朴素贝叶斯的精确性会越低(虽然影响不是非常大),布里 尔分数也会逐渐升高。 |
| fit_prior | 布尔值, 可不填 (默认为True)。是否学习先验概率 。 |
| class_prior | 形似数组的结构,结构为(n_classes, ),可不填(默认为None) 类的先验概率 。如果没有给出具体的先验概率则自动根据数据来进行计算。 |
伯努利贝叶斯
多项式朴素贝叶斯可同时处理二项分布(抛硬币)和多项分布(掷骰子),其中二项分布又叫做伯努利分布。
伯努利朴素贝叶斯与多项式朴素贝叶斯非常相似,都常用于处理文本分类数据。但由于伯努利朴素贝叶斯是处理二项 分布,所以它更加在意的是“存在与否”,而不是“出现多少次”这样的次数或频率。
参数在多项式贝叶斯的基础上多了一个,binarize : 浮点数或None,可不填,默认为0 将特征二值化的阈值,如果设定为None,则会假定说特征已经被二值化完毕。
补集朴素贝叶斯
标准多项式朴素贝叶斯算法的改进,能够解决样本不平 衡问题,并且能够一定程度上忽略朴素假设。
CNB使用来自每个标签类别的补集的概率,并以此来计算每个特征的权重。
概率类模型评估指标
概率类模型包括朴素贝叶斯,逻辑回归,SVC等
1.布里尔分数 (Brier Score)
布里尔分数衡量的是预测概率与实际结果(0 或 1)之间的均方误差。
数学公式:
![]()
-
f_t:模型给出的预测概率(例如 0.8)。
-
o_t:实际结果(1 代表发生,0 代表未发生)。
-
取值范围:[0, 1]。分数越低,模型性能越好(0 代表完美的预测,1 代表完全错误的预测)。
-
同时考察了模型的准确性和置信度。如果模型以 0.99 的概率预测正类却错了,BS 会给予极大的惩罚;而如果以 0.51 的概率预测错,惩罚则较小。
-
概率可以取到0或1时,优先使用布里尔分数。比如树,随机森林
from sklearn.metrics import brier_score_loss brier_score_loss(Ytest, prob[:,1], pos_label=1) #pos_label与prob中的索引一致,就可以查看这个类别下的布里尔分数是多少 #新版本布里尔分数只能衡量二分类,不能衡量多分类
2.对数似然函数(Log Loss/Cross-Entropy)
对数损失是逻辑回归等模型最常用的损失函数,也常用于模型评估。
-
特点:它比布里尔分数更“严厉”。
-
逻辑:它对预测错误的概率施加对数惩罚。如果实际标签为 1,而模型预测概率趋近于 0,Log Loss 会趋向于无穷大。
-
概率只能无限接近于0或1,无法取到0或1 。
-
用途:常用于衡量概率分布的差异,反映了模型包含的信息量。现实中对数损失用的比较多。
from sklearn.metrics import log_loss log_loss(Ytest,prob) log_loss(Ytest,logi.predict_proba(Xtest)) log_loss(Ytest,svc_prob)
3.校准度评估:可靠性曲线 (Reliability Curve)
又叫做概率校准曲线(probability calibration curve),可靠性图(reliability diagrams)。一条以预测概率为横坐标,真实标签为纵坐标的曲线,一个模型/算法的概率校准曲线越靠近对角线越好。
画成散点图易发现,由于真实标签是0和1,所以所有的点都在y=1和y=0这两条直线上分布,这样画成折线图后图像没有意义,所以需要把纵坐标也变成概率。将数据进行分箱,然后规定每个箱子中真实的少数类所占的 比例为这个箱上的真实概率trueproba,以此为纵坐标绘制曲线。这种分箱操作本质相当于是一种平滑。sklearn提供了相关的类calibration_curve.

校准可靠性曲线如果曲线偏离严重,我们通常使用 sklearn.calibration.CalibratedClassifierCV 进行修正,主要有两种方式:1)Platt Scaling 1)(Sigmoid 拟合)在模型输出之后加一个逻辑回归。适用样本量较少,或者模型误差分布符合 Sigmoid 形状(如 SVM)。
2) Isotonic Regression (等序回归)
一种非参数方法,试图找一个保序的分段线性函数来拟合曲线。适用样本量充足时效果极佳。它非常灵活,可以纠正任何单调的偏差。
from sklearn.calibration import CalibratedClassifierCV base_model = GaussianNB() #初始化原始模型 #校准器的初始化和训练 calibrated_model = CalibratedClassifierCV(base_model, method='sigmoid', cv=5).fit(X_train, y_train) #预测概率 prob_raw = base_model.fit(X_train, y_train).predict_proba(X_test)[:, 1] prob_calibrated = calibrated_model.predict_proba(X_test)[:, 1]
4.预测概率的直方图
区分:
概率密度曲线,横坐标是样本的取值,纵坐标是落在这个样本取值区间中的样本个数,衡量的是每个X的取值区间之内有多少样本。服从高斯分布。
概率分布直方图,横坐标是概率的取值[0,1],纵坐标是落在这个概率取值范围中的样本的个数,衡量的是每个概率取值区间之内有多少样本。分布无假设。
以样本的预测概率分箱后的结果为横坐标,每个箱中的样本数量为纵坐标的一个图像。
更多推荐
所有评论(0)