Python 机器学习入门:scikit-learn 完整实战教程

小飞兽 Python 6 次阅读 2026-07-24

Introduction

scikit-learn 是 Python 机器学习的标配库。本文从数据预处理、模型训练、交叉验证、超参数调优讲起,用真实数据集完成分类、回归、聚类三大任务,附模型持久化(joblib)。

---

环境安装

pip install scikit-learn pandas matplotlib numpy

数据加载与预处理

import pandas as pd
import numpy as np
from sklearn.datasets import load_iris

# 加载内置数据集
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 划分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    df.drop('target', axis=1), df['target'],
    test_size=0.2, random_state=42, stratify=df['target']
)

# 数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

分类模型

from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report

# 逻辑回归
lr = LogisticRegression(max_iter=1000, random_state=42)
lr.fit(X_train_scaled, y_train)
y_pred_lr = lr.predict(X_test_scaled)
print(f'逻辑回归准确率: {accuracy_score(y_test, y_pred_lr):.3f}')

# 随机森林
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
y_pred_rf = rf.predict(X_test)
print(f'随机森林准确率: {accuracy_score(y_test, y_pred_rf):.3f}')

# 支持向量机
svm = SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42)
svm.fit(X_train_scaled, y_train)
y_pred_svm = svm.predict(X_test_scaled)
print(f'SVM准确率: {accuracy_score(y_test, y_pred_svm):.3f}')

print(classification_report(y_test, y_pred_rf, target_names=iris.target_names))

回归模型

from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score

# 线性回归
lr_reg = LinearRegression()
lr_reg.fit(X_train, y_train)
y_pred_reg = lr_reg.predict(X_test)
print(f'线性回归 R²: {r2_score(y_test, y_pred_reg):.3f}')
print(f'MSE: {mean_squared_error(y_test, y_pred_reg):.3f}')

# 梯度提升回归
gb = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3)
gb.fit(X_train, y_train)
y_pred_gb = gb.predict(X_test)
print(f'GB回归 R²: {r2_score(y_test, y_pred_gb):.3f}')

交叉验证与超参数调优

from sklearn.model_selection import cross_val_score, GridSearchCV

# 5折交叉验证
scores = cross_val_score(rf, X_train, y_train, cv=5, scoring='accuracy')
print(f'交叉验证准确率: {scores.mean():.3f} ± {scores.std():.3f}')

# GridSearchCV 超参数调优
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [3, 5, 7, None],
    'min_samples_split': [2, 5, 10]
}
grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid, cv=5, scoring='accuracy', n_jobs=-1
)
grid_search.fit(X_train, y_train)
print(f'最优参数: {grid_search.best_params_}')
print(f'最优分数: {grid_search.best_score_:.3f}')
best_model = grid_search.best_estimator_

聚类(K-Means)

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

# 找最优 K 值
inertias = []
silhouettes = []
K_range = range(2, 10)
for k in K_range:
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    km.fit(X_train_scaled)
    inertias.append(km.inertia_)
    silhouettes.append(silhouette_score(X_train_scaled, km.labels_))

# 手肘法可视化
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('K'); plt.ylabel('Inertia')

plt.subplot(1, 2, 2)
plt.plot(K_range, silhouettes, 'ro-')
plt.xlabel('K'); plt.ylabel('Silhouette')
plt.tight_layout()
plt.savefig('kmeans_evaluation.png')

# 最终聚类
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_train_scaled)

模型持久化

import joblib

# 保存模型
joblib.dump(rf, 'random_forest_model.pkl')
joblib.dump(scaler, 'scaler.pkl')

# 加载模型
loaded_model = joblib.load('random_forest_model.pkl')
loaded_scaler = joblib.load('scaler.pkl')

# 用加载的模型预测
X_new_scaled = loaded_scaler.transform([[5.1, 3.5, 1.4, 0.2]])
prediction = loaded_model.predict(X_new_scaled)
print(f'预测类别: {iris.target_names[prediction[0]]}')

常见问题

Q1: 过拟合怎么解决?增加训练数据、减少模型复杂度(max_depth/n_estimators)、使用正则化(L1/L2)、交叉验证评估。

Q2: 类别不平衡怎么处理?用 SMOTE 过采样、class_weight='balanced'、或选择对不平衡数据友好的模型(如 XGBoost)。

Q3: 特征重要性怎么分析?rf.feature_importances_ 返回各特征的重要程度排序。

延伸阅读

  • XGBoost / LightGBM 进阶算法
  • 深度学习入门(TensorFlow/PyTorch)
  • 模型部署(ONNX)

---

作者:小马 | 绍大技术网 shaoda.net