← 数据分析 AI 第三方库 →

📘 Scikit-learn 完整教程

Scikit-learn 是 Python 中最流行的机器学习库,提供了各种经典的机器学习算法和工具。本教程将从零开始,系统讲解 Scikit-learn 的核心概念、算法和实战应用。

Scikit-learn 核心特性:

  • 🔄 统一 API:所有模型遵循 fit/predict 模式
  • 📊 算法丰富:分类、回归、聚类、降维等
  • 🔧 工具完善:预处理、模型选择、评估指标
  • 🚀 高效性能:基于 NumPy 和 SciPy 优化
  • 📚 文档完善:详细文档和丰富示例

🌳 Scikit-learn 知识体系

Scikit-learn
监督学习
无监督学习
模型选择
数据预处理
分类
回归
聚类
降维
交叉验证
网格搜索
标准化
编码

一、机器学习工作流程

掌握标准的机器学习项目流程是成功的关键。

🔄 完整工作流程图

1. 数据收集
2. 数据探索与可视化
3. 数据预处理
4. 特征工程
5. 选择模型?
6. 训练模型
7. 性能达标?
8. 模型调优
9. 模型评估
10. 部署应用

📋 各阶段详细说明

阶段 主要任务 常用工具 输出
1. 数据收集 获取原始数据 Pandas, SQL, API 原始数据集
2. 数据探索 理解数据分布、相关性 Matplotlib, Seaborn EDA 报告
3. 数据预处理 清洗、填充、标准化 sklearn.preprocessing 干净数据
4. 特征工程 特征选择、构造、降维 sklearn.feature_selection 特征矩阵
5-6. 模型训练 选择算法、训练模型 sklearn.ensemble, svm 训练好的模型
7-9. 模型评估 交叉验证、调参、评估 sklearn.model_selection 最优模型
10. 部署 模型保存、API 服务 joblib, pickle, Flask 生产模型

二、Scikit-learn API 设计

理解 Scikit-learn 的统一 API 设计是高效使用的关键。

🔄 统一 API 序列图

用户代码
Estimator
Model
1. fit(X, y) ← 训练模型
2. predict(X) ← 预测
3. score(X, y) ← 评估

📋 核心 API 方法

方法 参数 返回值 说明
fit(X, y) X: 特征,y: 标签 self 训练模型,学习参数
predict(X) X: 新样本 预测值 预测新样本
predict_proba(X) X: 新样本 概率数组 预测类别概率
score(X, y) X: 特征,y: 标签 分数 模型评分
transform(X) X: 数据 转换后数据 数据转换
fit_transform(X) X: 数据 转换后数据 拟合并转换

💻 API 使用示例

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 1. 准备数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 2. 创建模型
model = RandomForestClassifier(n_estimators=100, random_state=42)

# 3. 训练模型 (fit)
model.fit(X_train, y_train)

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

# 5. 评估 (score)
accuracy = model.score(X_test, y_test)
print(f"准确率:{accuracy:.4f}")

# 6. 获取特征重要性
importances = model.feature_importances_

三、监督学习算法

监督学习使用标记数据训练模型,包括分类和回归两大任务。

🌳 监督学习算法分类

监督学习
分类算法
回归算法
逻辑回归
决策树
随机森林
SVM
KNN
朴素贝叶斯
线性回归
岭回归
Lasso
决策树回归
随机森林回归

📋 分类算法详细对比

算法 类名 优点 缺点 适用场景
逻辑回归 LogisticRegression 简单、可解释、输出概率 只能处理线性问题 二分类、基线模型
决策树 DecisionTreeClassifier 易理解、可可视化 易过拟合 小数据集、可解释性要求
随机森林 RandomForestClassifier 准确率高、不易过拟合 模型大、速度慢 通用、默认选择
SVM SVC 高维有效、核技巧 大数据慢、参数敏感 小样本、高维数据
KNN KNeighborsClassifier 简单、无需训练 预测慢、对异常值敏感 小数据集、基线
梯度提升 GradientBoostingClassifier 准确率高、灵活 参数多、需调优 竞赛、高精度要求

📋 回归算法详细对比

算法 类名 正则化 适用场景
线性回归 LinearRegression 基线模型
岭回归 Ridge L2 多重共线性
Lasso Lasso L1 特征选择
弹性网络 ElasticNet L1+L2 相关特征多

💻 分类算法对比示例

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report

# 加载数据
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义多个分类器
classifiers = {
    '逻辑回归': LogisticRegression(max_iter=1000),
    '决策树': RandomForestClassifier(n_estimators=10, random_state=42),
    '随机森林': RandomForestClassifier(n_estimators=100, random_state=42),
    'SVM': SVC(kernel='rbf', probability=True),
    'KNN': KNeighborsClassifier(n_neighbors=5),
    '梯度提升': GradientBoostingClassifier(n_estimators=100, random_state=42)
}

# 训练和评估
results = {}
for name, clf in classifiers.items():
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    results[name] = accuracy
    print(f"{name}: {accuracy:.4f}")

# 找出最佳模型
best_model = max(results, key=results.get)
print(f"\n最佳模型:{best_model} (准确率:{results[best_model]:.4f})")

四、无监督学习算法

无监督学习处理未标记数据,包括聚类和降维等任务。

🌳 无监督学习算法分类

无监督学习
聚类算法
降维算法
K-Means
DBSCAN
层次聚类
高斯混合
PCA
t-SNE
UMAP
NMF

📋 聚类算法详细对比

算法 类名 需要 K 值 处理噪声 适用场景
K-Means KMeans 敏感 球形簇、大数据
DBSCAN DBSCAN 任意形状、有噪声
层次聚类 AgglomerativeClustering 一般 小数据、层次结构
高斯混合 GaussianMixture 一般 概率聚类

💻 聚类分析完整示例

from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

# 生成聚类数据
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# 1. K-Means 聚类
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
kmeans_labels = kmeans.fit_predict(X)
kmeans_score = silhouette_score(X, kmeans_labels)
print(f"K-Means 轮廓分数:{kmeans_score:.4f}")

# 2. DBSCAN 聚类
dbscan = DBSCAN(eps=0.3, min_samples=5)
dbscan_labels = dbscan.fit_predict(X)
# 去除噪声点计算轮廓分数
mask = dbscan_labels != -1
if mask.sum() > 1:
    dbscan_score = silhouette_score(X[mask], dbscan_labels[mask])
    print(f"DBSCAN 轮廓分数:{dbscan_score:.4f}")

# 3. 层次聚类
hierarchical = AgglomerativeClustering(n_clusters=4)
hierarchical_labels = hierarchical.fit_predict(X)
hierarchical_score = silhouette_score(X, hierarchical_labels)
print(f"层次聚类轮廓分数:{hierarchical_score:.4f}")

# 可视化比较
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].scatter(X[:, 0], X[:, 1], c=kmeans_labels, cmap='viridis')
axes[0].set_title(f'K-Means (score={kmeans_score:.3f})')
axes[1].scatter(X[:, 0], X[:, 1], c=dbscan_labels, cmap='viridis')
axes[1].set_title(f'DBSCAN')
axes[2].scatter(X[:, 0], X[:, 1], c=hierarchical_labels, cmap='viridis')
axes[2].set_title(f'层次聚类 (score={hierarchical_score:.3f})')
plt.tight_layout()
plt.show()

五、数据预处理

数据预处理是机器学习成功的关键步骤。

🔄 预处理流程图

原始数据
缺失值处理
特征缩放
类别编码
预处理完成

📋 预处理方法对比

方法 类名 公式 适用场景
标准化 StandardScaler (x - μ) / σ 特征服从正态分布
归一化 MinMaxScaler (x - min) / (max - min) 边界明确的数据
鲁棒标准化 RobustScaler (x - 中位数) / IQR 有异常值的数据
独热编码 OneHotEncoder 类别→二进制向量 名义类别变量
标签编码 LabelEncoder 类别→整数 有序类别变量

💻 完整预处理示例

from sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, LabelEncoder
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
import pandas as pd
import numpy as np

# 创建示例数据
data = pd.DataFrame({
    'age': [25, 30, np.nan, 45, 50],
    'salary': [50000, 60000, 75000, np.nan, 90000],
    'city': ['北京', '上海', '北京', '广州', '上海'],
    'department': ['技术', '销售', '技术', '技术', '销售'],
    'target': [1, 0, 1, 1, 0]
})

# 1. 分离特征和标签
X = data.drop('target', axis=1)
y = data['target']

# 2. 识别数值和类别特征
numeric_features = ['age', 'salary']
categorical_features = ['city', 'department']

# 3. 创建数值预处理管道
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),  # 填充缺失值
    ('scaler', StandardScaler())  # 标准化
])

# 4. 创建类别预处理管道
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))  # 独热编码
])

# 5. 创建预处理器
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ]
)

# 6. 应用预处理
X_processed = preprocessor.fit_transform(X)

print(f"原始形状:{X.shape}")
print(f"处理后形状:{X_processed.shape}")
print(f"特征名:{preprocessor.get_feature_names_out()}")

六、模型选择与调优

选择合适的模型和参数是提升性能的关键。

🔄 交叉验证流程图

完整数据集
K 折划分
训练 K-1 折
验证 1 折
重复 K 次
计算平均分数

📋 交叉验证方法对比

方法 类名 优点 缺点
K 折交叉验证 KFold 充分利用数据 计算成本高
分层 K 折 StratifiedKFold 保持类别比例 仅用于分类
留一法 LeaveOneOut 无偏估计 计算量极大
自助法 ShuffleSplit 灵活控制 可能有重复

💻 网格搜索与随机搜索

from sklearn.model_selection import GridSearchCV, RandomizedSearchCV, cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
import numpy as np

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

# 1. 交叉验证
rf = RandomForestClassifier(n_estimators=100, random_state=42)
cv_scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')
print(f"5 折交叉验证平均分:{cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")

# 2. 网格搜索(穷举)
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20, 30],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    verbose=1
)

grid_search.fit(X, y)

print(f"\n网格搜索最佳参数:{grid_search.best_params_}")
print(f"最佳交叉验证分数:{grid_search.best_score_:.4f}")

# 3. 随机搜索(更高效)
param_dist = {
    'n_estimators': np.random.randint(50, 300, 100),
    'max_depth': [None] + list(np.random.randint(10, 50, 50)),
    'min_samples_split': np.random.randint(2, 20, 50),
    'min_samples_leaf': np.random.randint(1, 10, 50)
}

random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_dist,
    n_iter=50,  # 随机搜索 50 次
    cv=5,
    scoring='accuracy',
    n_jobs=-1,
    random_state=42
)

random_search.fit(X, y)

print(f"\n随机搜索最佳参数:{random_search.best_params_}")
print(f"最佳交叉验证分数:{random_search.best_score_:.4f}")

七、实战案例

通过实际案例掌握 Scikit-learn 的完整应用。

📊 案例 1:鸢尾花分类 入门

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt

# 1. 加载数据
iris = load_iris()
X, y = iris.data, iris.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. 训练模型
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)

# 4. 评估
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred, target_names=iris.target_names))

# 5. 可视化
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('预测')
plt.ylabel('真实')
plt.title('混淆矩阵')
plt.show()

🏠 案例 2:房价预测 中级

from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# 1. 加载数据
housing = fetch_california_housing()
X, y = housing.data, housing.target

# 2. 划分数据
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)

# 3. 训练模型
reg = GradientBoostingRegressor(
    n_estimators=100,
    learning_rate=0.1,
    max_depth=3,
    random_state=42
)
reg.fit(X_train, y_train)

# 4. 评估
y_pred = reg.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"RMSE: ${rmse*100000:.2f}")
print(f"R²: {r2:.4f}")

# 5. 特征重要性
importances = reg.feature_importances_
for name, importance in zip(housing.feature_names, importances):
    print(f"{name}: {importance:.4f}")
← 数据分析 AI 第三方库 →