一、scikit-learn: Linear Models
1. 模块总览
linear_model 模块提供了一组线性算法用于回归(预测连续值)与线性分类(预测类别)。它假设模型输出为输入特征的线性组合:
y ^ = w 0 + w 1 x 1 + ⋯ + w p x p \hat{y} = w_0 + w_1 x_1 + \dots + w_p x_p y^=w0+w1x1+⋯+wpxp
其中系数 w = (w_1...w_p) 对应属性 coef_,截距 w_0 对应属性 intercept_。
2. 线性回归与普通最小二乘
2.1 Ordinary Least Squares (OLS)
目标: 最小化预测值与真实值之间的平方误差和:
min w ∣ ∣ X w − y ∣ ∣ 2 2 \min_w ||Xw - y||_2^2 wmin∣∣Xw−y∣∣22
模型类 :LinearRegression
特点
- 最基本的线性回归模型
- 使用*奇异值分解(SVD)*求解最优解
- 对共线性敏感(特征高度相关会导致不稳定系数估计)
核心参数
fit_intercept: 是否拟合截距(默认 True)positive: 是否约束系数为非负(默认 False)
示例代码
python
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X_train, y_train)
print(reg.coef_, reg.intercept_)
y_pred = reg.predict(X_test)
3. 正则化回归
当特征共线性或高维数据时,OLS 会表现不佳,需引入正则化。
3.1 Ridge Regression (L2 正则化)
目标:
min w ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 2 2 \min_w ||Xw - y||_2^2 + \alpha ||w||_2^2 wmin∣∣Xw−y∣∣22+α∣∣w∣∣22
这个损失会惩罚系数大小,使模型更稳定。
模型类
RidgeRidgeCV(含交叉验证选最优 α)
参数
alpha: 正则项强度(越大越显著)solver: 求解器,自动选择或指定
分类变体
RidgeClassifier:将分类标签映射到 {-1,1},用回归思想做分类RidgeClassifierCV:带 CV 自动调参
示例:
python
from sklearn.linear_model import Ridge
reg = Ridge(alpha=1.0)
reg.fit(X, y)
print(reg.coef_, reg.intercept_)
3.2 Lasso Regression (L1 正则化)
目标:
min w 1 2 n ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 1 \min_w \frac{1}{2n} ||Xw - y||_2^2 + \alpha ||w||_1 wmin2n1∣∣Xw−y∣∣22+α∣∣w∣∣1
- Lasso 会稀疏化系数(变成 0),因此具备特征选择作用。
模型类
LassoLassoCV: 自动交叉验证调参
优点
- 输出稀疏解 → 可用于特征选择
示例:
python
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=0.1)
lasso.fit(X, y)
4. 高级线性模型
4.1 Elastic Net(L1 + L2 混合)
目标:
min w 1 2 n ∣ ∣ X w − y ∣ ∣ 2 2 + α ( ρ ∣ ∣ w ∣ ∣ 1 + ( 1 − ρ ) ∣ ∣ w ∣ ∣ 2 2 ) \min_w \frac{1}{2n} ||Xw - y||_2^2 + \alpha (\rho ||w||_1 + (1-\rho) ||w||_2^2) wmin2n1∣∣Xw−y∣∣22+α(ρ∣∣w∣∣1+(1−ρ)∣∣w∣∣22)
- 同时结合 L1 与 L2 优点
l1_ratio = ρ控制 L1/L2 的比例。
模型类
ElasticNetElasticNetCV(带交叉验证)
示例:
python
from sklearn.linear_model import ElasticNet
enet = ElasticNet(alpha=0.1, l1_ratio=0.5)
enet.fit(X, y)
5. 高维与稀疏算法
5.1 Least Angle Regression (LARS)
- 适用于高维稀疏数据
- 类似前向逐步回归,可以高效生成整个系数路径。
Lars、lars_path可用于访问路径。
5.2 LassoLars
- 用 LARS 算法实现 Lasso 路径
- 与 coordinate descent 不同,能得到完整解路径。
5.3 Orthogonal Matching Pursuit
- 贪婪算法,逐步选特征逼近最优解
- 适合找到少量重要特征的线性拟合。
6. 广义线性模型 (GLM)
6.1 Logistic Regression(线性分类)
- 虽然名字含 Regression,在 scikit-learn 中是线性分类器。
- 模拟事件发生概率:
P ( y = 1 ∣ X ) = σ ( X w + b ) P(y=1|X) = \sigma(Xw + b) P(y=1∣X)=σ(Xw+b)
- 支持多类分类策略
one-vs-rest- multinomial
参数
penalty: 正则化类型(l1、l2、elasticnet)C: 正则化强度(C 越大,正则越弱)solver: 求解算法(liblinear、lbfgs等)
示例:
python
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(penalty='l2', C=1.0)
clf.fit(X_train, y_train)
print(clf.predict(X_test))
7. 其他实用线性模型
| 模型 | 用途 |
|---|---|
TweedieRegressor |
广义线性回归,可指定分布(正态、泊松、Gamma 等) |
PoissonRegressor |
泊松回归(计数数据) |
GammaRegressor |
Gamma 分布回归 |
BayesianRidge |
带贝叶斯先验的 Ridge 回归 |
不同分布预测任务、误差结构有不同适用性。
8. 模型通用实践建议
数据预处理
- 标准化每个特征(对于正则化模型很重要)
- 类别变量需 one-hot 编码
- 注意异常值对线性模型影响较大
交叉验证
CV(如RidgeCV,LassoCV,ElasticNetCV)自动选择超参- 也可结合
GridSearchCV
评估指标
- 回归:MSE、R²
- 分类:Accuracy、Precision、Recall、AUC
常见代码模板
线性回归基础
python
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit(X_train, y_train)
preds = model.predict(X_test)
使用 Lasso 选择特征
python
from sklearn.linear_model import LassoCV
model = LassoCV(cv=5).fit(X, y)
Logistic 回归分类
python
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(max_iter=200).fit(X_train, y_train)
二、Classifier Comparison
示例:
1、示例目的说明
这个示例展示了 scikit-learn 中多种分类器在不同合成数据集上的决策边界比较。不同分类器对数据分布的适应方式不同,本示例通过可视化展示它们的表现。示例强调:
- 直观展示不同分类方法的决策边界形状;
- 在低维数据上评估训练集与测试集划分后的分类表现;
- 不同分类器在不同数据结构(如线性可分、非线性)上的效果差异。
注意:这个示例侧重理解模型行为,不代表真实数据集上精确性能对比。
2、数据集构造与预处理
示例构造三个二分类合成数据集:
- make_moons:月亮形状噪声数据;
- make_circles:同心圆结构;
- Linearly separable:线性可分数据,由 make_classification 生成并加入噪声。
数据集划分为训练集与测试集,后续用于拟合与评估。
3、分类器列表
示例中主要比较 10 种不同的分类器,每个分类器代表一种常见的分类方法:
| 名称 | scikit-learn 类 |
|---|---|
| Nearest Neighbors | KNeighborsClassifier(n_neighbors=3) |
| Linear SVM | SVC(kernel="linear", C=0.025) |
| RBF SVM | SVC(gamma=2, C=1) |
| Gaussian Process | GaussianProcessClassifier(1.0 * RBF(1.0)) |
| Decision Tree | DecisionTreeClassifier(max_depth=5) |
| Random Forest | RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1) |
| Neural Net | MLPClassifier(alpha=1, max_iter=1000) |
| AdaBoost | AdaBoostClassifier() |
| Naive Bayes | GaussianNB() |
| Quadratic Discriminant Analysis | QuadraticDiscriminantAnalysis() |
这里涵盖了基于距离、支持向量、统计概率、集成树与神经网络等不同分类策略。
4、代码结构与核心流程
下面是示例的核心代码片段整理与说明。
1. 导入库与定义分类器
python
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.gaussian_process import GaussianProcessClassifier
from sklearn.gaussian_process.kernels import RBF
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
names = [
"Nearest Neighbors", "Linear SVM", "RBF SVM", "Gaussian Process",
"Decision Tree", "Random Forest", "Neural Net", "AdaBoost",
"Naive Bayes", "QDA"
]
classifiers = [
KNeighborsClassifier(3),
SVC(kernel="linear", C=0.025, random_state=42),
SVC(gamma=2, C=1, random_state=42),
GaussianProcessClassifier(1.0 * RBF(1.0), random_state=42),
DecisionTreeClassifier(max_depth=5, random_state=42),
RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1, random_state=42),
MLPClassifier(alpha=1, max_iter=1000, random_state=42),
AdaBoostClassifier(random_state=42),
GaussianNB(),
QuadraticDiscriminantAnalysis(),
]
这段代码初始化了所有需要展示的分类器,并按照名称一一列出,方便随后迭代。
2. 数据划分与训练
示例将每个数据集按照 60% 训练、40% 测试划分:
python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)
这样可以在同一随机划分下比较不同分类器的表现。
3. 可视化决策边界
示例针对每个分类器,在数据空间上生成一个细网格,根据分类器预测标签填色,用以展示决策面:
python
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
ax.contourf(xx, yy, Z, cmap=cm, alpha=0.8)
然后在图上叠加训练点与测试点,训练点颜色不透明、测试点透明度较低。
4. 测试准确率展示
在每个决策边界图右下角显示分类器在测试集上的准确率:
python
score = clf.score(X_test, y_test)
ax.text(x_max - 0.3, y_min + 0.3, ("%.2f" % score).lstrip("0"), size=15)
从图上即可直观对比不同分类器的表现。
三、Cross-validation
1. 什么是交叉验证
交叉验证(cross-validation, CV)是一种评估模型在未见过数据上泛化能力的技术,相比单次简单划分训练集和测试集,它通过多次重复训练-验证过程,使评估更加稳健,减少因特定划分带来的偏差。
2. 主要 API 与用途
2.1 cross_val_score
- 目的:对给定估计器(estimator)和数据进行交叉验证,并返回每折的评分数组。
- 基本用法:
python
from sklearn.model_selection import cross_val_score
scores = cross_val_score(estimator, X, y, cv=5)
默认使用 estimator.score() 计算评分,可通过 scoring 参数指定其他指标(例如 'f1_macro')。
2.2 cross_validate
-
与
cross_val_score不同:支持多个指标、返回训练时间、预测时间等信息。 -
返回一个 dict,可包含:
bashtest_<metric> train_<metric> (如果 return_train_score=True) fit_time score_time -
示例:
python
from sklearn.model_selection import cross_validate
scores = cross_validate(
clf, X, y, scoring=['precision_macro', 'recall_macro'], cv=5,
return_train_score=True
)
这样可同时获取多种评估指标。
2.3 cross_val_predict
- 返回每个样本在对应测试折上的预测值。
- 适合用于绘图或模型融合(例如 stacking / blending)。
- 注意:它不是评分方法,与
cross_val_score不同,它返回具体预测而非分数。
3. 常用交叉验证策略
交叉验证器负责生成训练集/验证集索引。常见的包括:
3.1 K-Fold
将数据分成 K 份,每次用 K-1 份训练,1 份验证。适用于数据 i.i.d(独立同分布)的情况。
python
from sklearn.model_selection import KFold
kf = KFold(n_splits=5)
3.2 Stratified K-Fold
在分类问题中,通过保留各类比例在每个折中的分布,从而使训练集与验证集类别比例更均衡。常用于类别不平衡数据。
python
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5)
3.3 ShuffleSplit
随机打乱数据并按指定比例划分训练和测试集,独立生成多次拆分。适合样本非顺序排列、希望更随机的验证。
python
from sklearn.model_selection import ShuffleSplit
ss = ShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
3.4 Group 相关的 CV
当数据中存在按组(group)相关的样本时,应确保同一组的样本不出现在训练集和验证集同时出现。常用策略包括:
GroupKFold:按组划分,不同组不交叉;LeaveOneGroupOut:每次留出一个组作为测试;GroupShuffleSplit:按组随机划分。
3.5 时间序列 CV(TimeSeriesSplit)
适用于时间序列数据,保持时间顺序,在每次划分中训练集包含前面时间点的数据,验证集为后面时间点的数据。避免未来信息泄漏。
python
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=3)
4. 交叉验证使用注意
4.1 数据顺序与 shuffle
如果数据按顺序排列(例如时间、批次标签),不随机打乱可能导致不合理的训练/验证划分;因此在某些折叠策略上需要手动设置 shuffle=True 和 random_state 控制随机性。
4.2 预处理与 pipeline
在交叉验证内部进行预处理(例如标准化、特征选择)时,应确保该预处理仅使用训练折上的信息,而不是整个数据集,否则会导致数据泄漏。Pipeline 可确保这些操作正确应用。
5. 高级功能与扩展
5.1 自定义划分
可以通过实现自己的划分函数(返回训练/测试索引)用于更具体的策略,例如按时间窗口、自定义分组等。
5.2 模型选择与调参结合
交叉验证可以与网格搜索 (GridSearchCV)、随机搜索 (RandomizedSearchCV) 或更复杂的嵌套交叉验证一起使用,以优化模型的超参数组合。
6. 典型示例代码
6.1 计算交叉验证得分
python
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
clf = SVC(kernel='linear', C=1)
scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print("Average accuracy:", scores.mean())
6.2 多指标评估
python
from sklearn.model_selection import cross_validate
scoring = ['precision_macro', 'recall_macro']
scores = cross_validate(clf, X, y, scoring=scoring, cv=5)
print(scores['test_precision_macro'])
6.3 结合 Pipeline 预处理
python
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
pipeline = make_pipeline(StandardScaler(), SVC(kernel='rbf'))
scores = cross_val_score(pipeline, X, y, cv=5)
四、模型评估:常见情形的预定义评分
在使用诸如 model_selection.cross_val_score、GridSearchCV、validation_curve 等工具时,可以通过参数 scoring 指定评估指标。scoring 支持:
- 字符串名称(常见指标的预定义值);
- 可调用对象(更复杂或自定义指标)。
下面列出 stable 版本文档 中支持的所有 预定义字符串评分值 及其对应的评估函数。
1、分类
scoring 字符串 |
对应函数 | 说明 |
|---|---|---|
accuracy |
metrics.accuracy_score |
分类准确率 |
balanced_accuracy |
metrics.balanced_accuracy_score |
平衡准确率(类别不平衡情况) |
top_k_accuracy |
metrics.top_k_accuracy_score |
Top-K 准确率 |
average_precision |
metrics.average_precision_score |
平均精度 |
neg_brier_score |
metrics.brier_score_loss |
布里尔评分,预测概率误差(需要 predict_proba) |
f1 |
metrics.f1_score |
F1 分数(二分类) |
f1_micro |
metrics.f1_score |
F1 微平均 |
f1_macro |
metrics.f1_score |
F1 宏平均 |
f1_weighted |
metrics.f1_score |
F1 加权平均 |
f1_samples |
metrics.f1_score |
多标签样本级 F1 |
neg_log_loss |
metrics.log_loss |
负对数损失(需要 predict_proba) |
precision, precision_macro, precision_micro, precision_weighted, precision_samples |
metrics.precision_score |
精确率及其不同平均方式 |
recall, recall_macro, recall_micro, recall_weighted, recall_samples |
metrics.recall_score |
召回率及其不同平均方式 |
jaccard, jaccard_macro, jaccard_micro, jaccard_weighted, jaccard_samples |
metrics.jaccard_score |
Jaccard 指数 |
roc_auc, roc_auc_ovr, roc_auc_ovo, roc_auc_ovr_weighted, roc_auc_ovo_weighted |
metrics.roc_auc_score |
ROC AUC 指标(多个多类策略) |
d2_log_loss_score |
metrics.d2_log_loss_score |
对数损失衍生评估 |
d2_brier_score |
metrics.d2_brier_score |
Brier 分数衍生评估 |
2、聚类
scoring 字符串 |
对应函数 |
|---|---|
adjusted_mutual_info_score |
metrics.adjusted_mutual_info_score |
adjusted_rand_score |
metrics.adjusted_rand_score |
completeness_score |
metrics.completeness_score |
fowlkes_mallows_score |
metrics.fowlkes_mallows_score |
homogeneity_score |
metrics.homogeneity_score |
mutual_info_score |
metrics.mutual_info_score |
normalized_mutual_info_score |
metrics.normalized_mutual_info_score |
rand_score |
metrics.rand_score |
v_measure_score |
metrics.v_measure_score |
这些指标常用于评估聚类标签与真实标签之间的一致性或结构质量。
3、回归
对于回归任务,预定义评分字符串通常返回更高代表更好(注意距离/误差类指标以负值呈现):
scoring 字符串 |
对应函数 |
|---|---|
explained_variance |
metrics.explained_variance_score |
neg_max_error |
metrics.max_error |
neg_mean_absolute_error |
metrics.mean_absolute_error |
neg_mean_squared_error |
metrics.mean_squared_error |
neg_root_mean_squared_error |
metrics.root_mean_squared_error |
neg_mean_squared_log_error |
metrics.mean_squared_log_error |
neg_root_mean_squared_log_error |
metrics.root_mean_squared_log_error |
neg_median_absolute_error |
metrics.median_absolute_error |
r2 |
metrics.r2_score |
neg_mean_poisson_deviance |
metrics.mean_poisson_deviance |
neg_mean_gamma_deviance |
metrics.mean_gamma_deviance |
neg_mean_absolute_percentage_error |
metrics.mean_absolute_percentage_error |
d2_absolute_error_score |
metrics.d2_absolute_error_score |
说明:
- 以
neg_前缀开头的指标表示原本的误差度量取了负值;这是为了符合 scikit-learn 的统一规则:在所有 scorer 中,分数越高表示模型越好。
4、使用提醒
- 如果传入了错误的
scoring名称(不存在于预定义表中),许多模型评估工具(例如cross_val_score)会抛出异常,并提示所有可用 scorer 名称列表。 - 所有这些预定义 scorer 都存储在字典
sklearn.metrics.SCORERS中,可以通过metrics.get_scorer_names()查看完整列表。
5、示例用法
下面示例中,在交叉验证中指定不同的预定义评分:
python
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
clf = SVC(probability=True) # 需要predict_proba才能用neg_log_loss
scores = cross_val_score(clf, X, y, cv=5, scoring='roc_auc')
print("ROC AUC:", scores)
scores_mse = cross_val_score(regressor, X_reg, y_reg, cv=5, scoring='neg_mean_squared_error')
print("MSE (negated):", scores_mse)
在这个例子中,第一个评分使用 ROC AUC;第二个评分使用负均方误差表征回归性能。
五、K-Means
1. 什么是 K-Means 聚类
K-Means 是一种常见的 无监督聚类算法 ,用于将数据划分为预指定数量 KKK 个簇,使得每个簇内部的样本彼此之间更相似,同时与其他簇的样本更不相似。算法通过最小化簇内平方和(within-cluster sum of squares,也称惯性 inertia)来衡量聚类质量:
i n e r t i a = ∑ i = 1 n min μ j ∈ C ∥ x i − μ j ∥ 2 \mathrm{inertia} = \sum_{i=1}^{n} \min_{\mu_j \in C} \|x_i - \mu_j\|^2 inertia=i=1∑nμj∈Cmin∥xi−μj∥2
其中:
- x i x_i xi 是一个样本;
- μ j \mu_j μj 是第 j j j 个簇的质心(centroid),即该簇样本的均值;
- C C C 是所有簇中心的集合。
算法目标是让簇内点尽可能接近其簇中心,从而形成紧凑的簇。
2. 算法基本步骤(Lloyd's 算法)
K-Means 聚类的执行可以理解为以下迭代过程:
- 初始化质心
随机选择 KKK 个质心(或者利用更好的初始化策略如 k-means++)。 - 分配样本到最近质心
对每个样本,计算它到每个质心的距离,并将该样本指派给最近的质心。 - 更新质心
对每个簇中的所有样本求平均值,得到新的簇中心。 - 检查收敛
如果质心变化小于给定阈值或达到最大迭代次数,则停止;否则返回步骤 2。
K-Means 会在有限次迭代后收敛,但可能收敛到局部最优解,而非全局最优。这就是为什么要运行多次不同初始质心并选择最佳结果的原因。
3. scikit-learn 中的 K-Means API
scikit-learn 提供如下两个相关的接口:
KMeans类:经典的 K-Means 聚类实现。MiniBatchKMeans类:K-Means 的小批量版本,用于大规模数据加速。
4. KMeans 类详解
4.1 调用方式
python
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=K, init='k-means++', n_init=10,
max_iter=300, tol=1e-4, random_state=42)
kmeans.fit(X)
4.2 重要参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
n_clusters |
int | 聚类数量 KKK。必须指定。 |
init |
{'k-means++', 'random' | array | callable} | 初始化质心的方式。默认 'k-means++' 会较好地选择初始中心加快收敛。 |
n_init |
int 或 'auto' |
运行算法的次数(随机初始化次数)。选择最优结果(最小 inertia)。 |
max_iter |
int | 每次运行的最大迭代次数。 |
tol |
float | 收敛容忍阈值,当质心移动小于该值时停止迭代。 |
random_state |
int 或 RandomState | 随机种子,控制初始化和算法行为的随机性。 |
algorithm |
{'lloyd', 'elkan'} | 算法实现版本,默认为 'lloyd'。 |
4.3 常用属性
kmeans.labels_:聚类后的标签数组。kmeans.cluster_centers_:质心坐标。kmeans.inertia_:最终簇内平方和(惯性指标)。
这些属性使得后续分析和可视化变得方便。
5. k-means++ 初始化
默认为 init='k-means++' 的初始化策略比完全随机选择更稳定,通过尽量让初始质心彼此远离来减少局部最优的风险。
可以传入一个数组指定初始中心,或者使用自定义函数生成初始点。
6. MiniBatchKMeans(小批量 K-Means)
MiniBatchKMeans 是标准 K-Means 的加速改进版本,采用每次处理数据的 小批次(mini-batch) 进行聚类迭代,加快收敛速度,适用于大规模数据集。
MiniBatch 版本每次随机从数据集中抽取一小批样本计算簇中心更新,大幅降低计算成本,但聚类质量通常略逊于标准 K-Means。
7. 使用建议和注意事项
7.1 聚类数目 K 的选择
- K 需要用户指定,当聚类数未知时可借助 轮廓系数(Silhouette) 、肘部方法(Elbow method) 等指标辅助判断。
- 不同的 K 会导致完全不同的聚类结构,需要根据业务场景选择。
7.2 输入数据预处理
- 缩放特征 :若不同特征量纲差异大,建议进行标准化(如
StandardScaler)。 - PCA 降维在高维数据上可减少噪声影响、加速计算。
7.3 局限性
K-Means 具有如下典型局限性:
- 依赖欧氏距离,因此对 非凸簇 或 长细形簇结构 不敏感。
- 对初始化敏感,可能陷入局部最优。
- 对离群点敏感,因为极端值会影响簇中心。
在这些情况下可能需要考虑更复杂的聚类算法(如 DBSCAN、谱聚类等)。
8. 简单示例代码
python
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# X 是形状为 (n_samples, n_features) 的数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
kmeans = KMeans(n_clusters=5, random_state=42)
kmeans.fit(X_scaled)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
inertia = kmeans.inertia_
六、主成分分析(PCA)学习笔记 --- scikit-learn
1. 什么是 PCA
主成分分析(Principal Component Analysis, PCA)是一种经典的 线性降维方法,用于将高维数据投影到低维空间,同时尽量保留原始数据的方差。PCA 的目标是寻找一组正交方向(主成分),使投影后的数据在这些方向上的方差最大。
PCA 同时用于:
- 可视化降维(例如将多维数据投影到 2D/3D 平面上);
- 预处理降噪;
- 降维后作为其他学习算法的输入。
2. PCA 的基本原理
PCA 主要基于 奇异值分解(SVD) 或等价的特征分解:
- 对输入数据
X(样本 × 特征)先 中心化(每个特征减去均值); - 计算协方差矩阵或直接对中心化数据做 SVD;
- 得到正交方向(主成分)并按解释方差大小排序;
- 选择前
n_components个主成分作为新的坐标基,将数据投影到低维空间。
默认情况下,PCA 不对各特征进行标准化缩放,因此常与特征标准化(如 StandardScaler)一起使用,使不同尺度的特征具有相似的影响力。
3. scikit-learn 中的 PCA 实现
在 scikit-learn 中,PCA 通过类 sklearn.decomposition.PCA 实现,它是一个转换器(transformer),支持以下常见方法:
.fit(X):学习数据的主成分;.transform(X):将数据投影到主成分空间;.fit_transform(X):等效于 fit + transform;.inverse_transform(Z):(可选)将降维数据重构回原始空间(近似)。
导入方式
python
from sklearn.decomposition import PCA
4. 构造函数与参数
python
PCA(
n_components=None,
*,
copy=True,
whiten=False,
svd_solver='auto',
tol=0.0,
iterated_power='auto',
n_oversamples=10,
power_iteration_normalizer='auto',
random_state=None
)
核心参数说明
| 参数 | 类型 | 含义 |
|---|---|---|
n_components |
int/float/str | 想要保留的主成分数量;整数表示降到多少维;浮点(0~1)表示保留该比例的总方差;'mle' 表示使用 Minka 的 MLE 自动估算。 |
copy |
bool | 是否复制数据,默认 True 不修改原始。 |
whiten |
bool | 是否白化,即让各主成分具有单位方差。对于某些算法(例如基于距离的算法)可能有用。 |
svd_solver |
{'auto','full','arpack','randomized'} | 指定 SVD 求解器。 |
random_state |
int/None | 指定随机种子(影响随机截断 SVD)。 |
详细参数说明,请参阅官方 API 文档。
5. 如何选择 n_components
- 整数:直接指定新空间维度数;
- 浮点数(0 < n_components < 1):保留解释总方差比大于该值的最少主成分;
'mle':Minka 的最大似然估计自动确定维度(仅在svd_solver='full'时有效)。
例如:
pca = PCA(n_components=0.95) # 保留至少 95% 方差
6. 主要属性(训练后)
调用 .fit() 或 .fit_transform() 后可以访问以下属性:
| 属性名 | 含义 |
|---|---|
components_ |
主成分坐标(每行是一个主成分方向) |
explained_variance_ |
每个主成分解释的方差 |
explained_variance_ratio_ |
每个主成分解释的方差比例 |
singular_values_ |
奇异值(与主成分方差相关) |
这些属性用于了解各主成分的重要性以及降维后信息保留情况。
7. 样例代码
下面示例演示如何使用 PCA 对数据降维:
python
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 假设 X 是 shape=(n_samples, n_features) 的原始数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
# 查看各主成分解释的方差比例
print(pca.explained_variance_ratio_)
此代码首先标准化特征,然后将数据降到 2 维并打印主成分解释的方差比例。
8. whiten 参数用途
当 whiten=True 时,算法不仅投影到主成分空间,还对每个主成分缩放成单位方差,这在某些基于距离的方法(如 K-Means)和某些机器学习算法中有用,但会破坏原始数值间的方差结构。
9. 大规模数据:Incremental PCA
标准 PCA 需要将所有数据一次性载入内存进行 SVD,因此对于大规模数据有内存限制。
scikit-learn 提供了 IncrementalPCA 类,它通过小批量数据(mini-batch)逐步更新 PCA,使得数据不必一次全部载入内存,适合流式或磁盘映射数据处理。
10. 使用时常见注意事项
- PCA 依赖于数据中心化和对特征方差的敏感性,因此通常建议先做特征标准化(例如
StandardScaler)。 - 稀疏数据可以考虑使用
TruncatedSVD,因为 PCA 默认不支持稀疏矩阵中心化。 - 若希望确保可重复结果,可通过
random_state控制随机性。
学习资料来源:
Scikit-Learn 线性回归文档
分类算法对比
训练集/测试集分割
过拟合解决方案
k-means 聚类文档
PCA 降维指南