Scikit-learn 详解 [复制链接]

管理员组

Scikit-learn 详解

Scikit-learn 是 Python 最流行的机器学习库,提供简单高效的工具用于数据挖掘和数据分析。


📦 核心特点

特点

说明

简单易用

统一的 API 设计,学习曲线平缓

功能全面

分类、回归、聚类、降维、模型选择等

高效稳定

基于 NumPy/SciPy,性能优秀

文档完善

官方文档详尽,示例丰富

生态友好

与 Pandas、Matplotlib、XGBoost 等无缝集成


🗂️ 核心模块架构

scikit-learn/
├── preprocessing      # 数据预处理
├── model_selection    # 模型选择与评估
├── linear_model       # 线性模型
├── ensemble           # 集成学习
├── tree               # 决策树
├── svm                # 支持向量机
├── neural_network     # 神经网络
├── cluster            # 聚类
├── decomposition      # 降维
├── metrics            # 评估指标
├── pipeline           # 流水线
└── feature_selection  # 特征选择

🎯 统一 API 设计

三大核心接口

# 1. 拟合模型
model.fit(X_train, y_train)

# 2. 预测
y_pred = model.predict(X_test)

# 3. 评估(部分模型支持)
score = model.score(X_test, y_test)

所有估计器(Estimator)都遵循:

from sklearn.ensemble import RandomForestClassifier

# 创建模型
model = RandomForestClassifier(n_estimators=100)

# 训练
model.fit(X_train, y_train)

# 预测
predictions = model.predict(X_test)

# 获取参数
model.get_params()

# 设置参数
model.set_params(n_estimators=200)

📊 主要功能模块详解

1️⃣ 数据预处理 (preprocessing)

from sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder

# 标准化(均值=0, 方差=1)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 归一化(缩放到 [0,1])
minmax = MinMaxScaler()
X_norm = minmax.fit_transform(X)

# 类别特征编码
encoder = OneHotEncoder()
X_encoded = encoder.fit_transform(category_features)

# 缺失值填充
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean')  # mean/median/most_frequent
X_filled = imputer.fit_transform(X_with_missing)

2️⃣ 模型选择 (model_selection)

训练集/测试集划分

from sklearn.model_selection import train_test_split

# 基础划分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2,      # 测试集比例
    random_state=42,    # 随机种子
    stratify=y          # 分层抽样(分类问题)
)

交叉验证

from sklearn.model_selection import cross_val_score, KFold

# K 折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=kf, scoring='accuracy')

print(f"平均准确率:{scores.mean():.3f} (+/- {scores.std():.3f})")

网格搜索(超参数调优)

from sklearn.model_selection import GridSearchCV

param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, 15, None],
    'min_samples_split': [2, 5, 10]
}

grid_search = GridSearchCV(
    RandomForestClassifier(),
    param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1  # 使用所有 CPU
)

grid_search.fit(X_train, y_train)
print(f"最佳参数:{grid_search.best_params_}")
print(f"最佳得分:{grid_search.best_score_:.3f}")

随机搜索(大数据集更快)

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform

param_dist = {
    'n_estimators': randint(50, 300),
    'max_depth': randint(3, 20),
    'min_samples_split': randint(2, 20)
}

random_search = RandomizedSearchCV(
    RandomForestClassifier(),
    param_distributions=param_dist,
    n_iter=50,           # 尝试 50 组参数
    cv=5,
    n_jobs=-1
)

3️⃣ 回归模型 (linear_model & ensemble)

线性回归

from sklearn.linear_model import LinearRegression, Ridge, Lasso

# 普通线性回归
lr = LinearRegression()
lr.fit(X_train, y_train)
print(f"系数:{lr.coef_}")
print(f"截距:{lr.intercept_}")

# 岭回归(L2 正则化)
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)

# Lasso 回归(L1 正则化,可做特征选择)
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)

回归评估指标

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

y_pred = model.predict(X_test)

mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"MSE: {mse:.3f}, RMSE: {rmse:.3f}")
print(f"MAE: {mae:.3f}, R²: {r2:.3f}")

4️⃣ 分类模型

逻辑回归

from sklearn.linear_model import LogisticRegression

log_reg = LogisticRegression(
    C=1.0,              # 正则化强度
    penalty='l2',       # l1/l2
    solver='lbfgs',     # 优化算法
    max_iter=1000
)
log_reg.fit(X_train, y_train)

# 概率预测
probabilities = log_reg.predict_proba(X_test)

支持向量机 (SVM)

from sklearn.svm import SVC, SVR

# 分类
svc = SVC(
    kernel='rbf',       # linear/poly/rbf/sigmoid
    C=1.0,              # 惩罚参数
    gamma='scale',      # 核系数
    class_weight='balanced'  # 处理类别不平衡
)
svc.fit(X_train, y_train)

# 回归
svr = SVR(kernel='rbf')
svr.fit(X_train, y_train)

决策树

from sklearn.tree import DecisionTreeClassifier, export_text

dt = DecisionTreeClassifier(
    max_depth=5,            # 最大深度
    min_samples_split=20,   # 最小分裂样本数
    min_samples_leaf=10,    # 最小叶节点样本数
    criterion='gini'        # gini/entropy
)
dt.fit(X_train, y_train)

# 查看规则
print(export_text(dt, feature_names=list(X.columns)))

随机森林

from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor

rf = RandomForestClassifier(
    n_estimators=100,       # 树的数量
    max_depth=None,         # 树的最大深度
    min_samples_split=2,
    min_samples_leaf=1,
    max_features='sqrt',    # 每次分裂考虑的特征数
    bootstrap=True,         # 是否自助采样
    oob_score=True,         # 袋外评分
    n_jobs=-1,
    random_state=42
)
rf.fit(X_train, y_train)

# 特征重要性
importances = rf.feature_importances_

梯度提升 (GBM/XGBoost/LightGBM 风格)

from sklearn.ensemble import GradientBoostingClassifier, AdaBoostClassifier

# 梯度提升
gb = GradientBoostingClassifier(
    n_estimators=100,
    learning_rate=0.1,
    max_depth=3,
    subsample=0.8,          # 样本采样比例
    random_state=42
)

# AdaBoost
ada = AdaBoostClassifier(
    n_estimators=50,
    learning_rate=1.0,
    random_state=42
)

5️⃣ 聚类 (cluster)

K-Means

from sklearn.cluster import KMeans

kmeans = KMeans(
    n_clusters=3,       # 聚类数量
    init='k-means++',   # 初始化方法
    n_init=10,          # 运行次数
    max_iter=300,
    random_state=42
)
labels = kmeans.fit_predict(X)
centroids = kmeans.cluster_centers_

# 肘部法则找最佳 K
inertias = []
for k in range(1, 11):
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans.fit(X)
    inertias.append(kmeans.inertia_)

DBSCAN(基于密度的聚类)

from sklearn.cluster import DBSCAN

dbscan = DBSCAN(
    eps=0.5,            # 邻域半径
    min_samples=5       # 核心点最小邻居数
)
labels = dbscan.fit_predict(X)
# -1 表示噪声点

层次聚类

from sklearn.cluster import AgglomerativeClustering

hierarchical = AgglomerativeClustering(
    n_clusters=3,
    linkage='ward'      # ward/complete/average/single
)
labels = hierarchical.fit_predict(X)

6️⃣ 降维 (decomposition)

PCA(主成分分析)

from sklearn.decomposition import PCA

# 保留 95% 方差
pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X)

# 指定主成分数
pca = PCA(n_components=3)
X_reduced = pca.fit_transform(X)

# 查看解释方差比
print(f"各主成分解释方差:{pca.explained_variance_ratio_}")
print(f"累计解释方差:{np.cumsum(pca.explained_variance_ratio_)}")

t-SNE(可视化高维数据)

from sklearn.manifold import TSNE

tsne = TSNE(
    n_components=2,     # 降维到 2D
    perplexity=30,      # 困惑度
    learning_rate=200,
    n_iter=1000
)
X_embedded = tsne.fit_transform(X)

LDA(线性判别分析)

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

lda = LinearDiscriminantAnalysis(n_components=2)
X_reduced = lda.fit_transform(X, y)  # 需要标签

7️⃣ 评估指标 (metrics)

分类指标

from sklearn.metrics import (
    accuracy_score, precision_score, recall_score, 
    f1_score, confusion_matrix, classification_report,
    roc_auc_score, roc_curve, precision_recall_curve
)

y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]

# 基础指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)

# 详细报告
report = classification_report(y_test, y_pred)

# ROC-AUC
auc = roc_auc_score(y_test, y_proba)
fpr, tpr, thresholds = roc_curve(y_test, y_proba)

回归指标

from sklearn.metrics import (
    mean_squared_error, mean_absolute_error, 
    r2_score, explained_variance_score
)

聚类指标

from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score

silhouette = silhouette_score(X, labels)

8️⃣ 流水线 (Pipeline)

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV

# 构建流水线
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('classifier', LogisticRegression())
])

# 网格搜索(参数名 = 步骤名 + '__' + 参数名)
param_grid = {
    'classifier__C': [0.1, 1, 10],
    'classifier__penalty': ['l1', 'l2'],
    'classifier__solver': ['liblinear', 'lbfgs']
}

grid_search = GridSearchCV(pipeline, param_grid, cv=5)
grid_search.fit(X_train, y_train)

print(f"最佳参数:{grid_search.best_params_}")

9️⃣ 特征选择 (feature_selection)

from sklearn.feature_selection import (
    SelectKBest, SelectFromModel, RFE, 
    f_classif, mutual_info_classin
)

# 选择前 K 个特征
selector = SelectKBest(score_func=f_classif, k=10)
X_selected = selector.fit_transform(X, y)

# 基于模型的特征选择
selector = SelectFromModel(
    RandomForestClassifier(n_estimators=100),
    threshold='mean'  # 选择重要性高于平均的特征
)
X_selected = selector.fit_transform(X, y)

# 递归特征消除
rfe = RFE(
    estimator=LogisticRegression(),
    n_features_to_select=10
)
X_selected = rfe.fit_transform(X, y)

🎯 完整工作流示例

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix

# 1. 加载数据
df = pd.read_csv('data.csv')
X = df.drop('target', axis=1)
y = df['target']

# 2. 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 3. 构建流水线
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('clf', RandomForestClassifier(random_state=42))
])

# 4. 超参数调优
param_grid = {
    'clf__n_estimators': [100, 200],
    'clf__max_depth': [5, 10, None],
    'clf__min_samples_split': [2, 5]
}

grid_search = GridSearchCV(pipeline, param_grid, cv=5, n_jobs=-1)
grid_search.fit(X_train, y_train)

# 5. 评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)

print("分类报告:")
print(classification_report(y_test, y_pred))

print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))

# 6. 交叉验证
cv_scores = cross_val_score(best_model, X, y, cv=5)
print(f"交叉验证准确率:{cv_scores.mean():.3f} (+/- {cv_scores.std():.3f})")

📚 常用超参数速查表

模型

关键参数

说明

RandomForest

n_estimators

树的数量(越多越稳定)

max_depth

树的最大深度(控制复杂度)

min_samples_split

分裂所需最小样本数

max_features

每次分裂考虑的特征数

SVM

C

惩罚参数(越大越严格)

gamma

核系数(越大越复杂)

kernel

核函数类型

LogisticRegression

C

正则化强度(越小正则化越强)

penalty

L1/L2正则化

solver

优化算法

GradientBoosting

learning_rate

学习率(越小越慢但可能更好)

n_estimators

基学习器数量

subsample

样本采样比例


🔧 实用技巧

1. 处理类别不平衡

# 方法 1: class_weight
model = RandomForestClassifier(class_weight='balanced')

# 方法 2: SMOTE 过采样
from imblearn.over_sampling import SMOTE
smote = SMOTE()
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)

2. 保存和加载模型

import joblib

# 保存
joblib.dump(model, 'model.pkl')

# 加载
model = joblib.load('model.pkl')

3. 学习曲线(诊断过拟合/欠拟合)

from sklearn.model_selection import learning_curve

train_sizes, train_scores, test_scores = learning_curve(
    model, X, y, cv=5, n_jobs=-1
)

# 绘制曲线判断模型状态

📖 学习资源

资源

链接

官方文档

https://scikit-learn.org

用户指南

非常详细,按主题组织

示例库

包含大量可运行的示例代码

API 参考

每个类/函数的完整说明

最新回复

请先登录后再回复 登录

uid:1 管理员组
关注
发帖 8
评论 0
粉丝 0
关注 0
发新帖
目录