Supervised Learning 监督学习是机器学习最常用的范式之一

监督学习基础

学习目标

完成本模块学习后,你将能够:

  • 理解监督学习的基本概念和原理
  • 掌握常见的监督学习算法
  • 学会评估和优化模型性能
  • 解决实际的监督学习问题

先修知识

  • Python编程基础
  • 数学基础(线性代数、微积分、概率统计)
  • 数据分析基础

1. 监督学习概述

1.1 基本概念

监督学习是机器学习的主要范式之一,其核心思想是通过已标记的训练数据来学习输入到输出的映射关系。在这个过程中:

  • 算法通过观察训练样本(特征和标签)来学习模式
  • 学习到的模式用于预测新样本的标签
  • 预测结果与实际标签的差异用于指导模型改进

1.2 应用场景

# 示例:房价预测
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# 加载数据
df = pd.read_csv('house_prices.csv')
X = df[['size', 'bedrooms', 'location']]
y = df['price']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

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

# 预测和评估
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f'均方误差: {mse:.2f}')
print(f'R2分数: {r2:.2f}')

2. 经典监督学习算法

2.1 线性回归

线性回归是最基础的监督学习算法,用于建立特征和目标变量之间的线性关系。

from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

# 创建Pipeline
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('regressor', LinearRegression())
])

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

# 获取特征重要性
feature_importance = pd.DataFrame({
    'feature': X.columns,
    'importance': abs(pipeline.named_steps['regressor'].coef_)
})
print("特征重要性:")
print(feature_importance.sort_values('importance', ascending=False))

2.2 逻辑回归

逻辑回归是一种用于分类问题的监督学习算法。

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns

# 创建和训练模型
clf = LogisticRegression(random_state=42)
clf.fit(X_train, y_train)

# 预测和评估
y_pred = clf.predict(X_test)
print("分类报告:")
print(classification_report(y_test, y_pred))

# 绘制混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix(y_test, y_pred), 
            annot=True, 
            fmt='d',
            cmap='Blues')
plt.title('混淆矩阵')
plt.show()

2.3 决策树

决策树是一种直观且易于解释的监督学习算法。

from sklearn.tree import DecisionTreeClassifier, plot_tree

# 创建和训练模型
dt = DecisionTreeClassifier(max_depth=4, random_state=42)
dt.fit(X_train, y_train)

# 可视化决策树
plt.figure(figsize=(20,10))
plot_tree(dt, 
         feature_names=X.columns,
         class_names=['0', '1'],
         filled=True,
         rounded=True)
plt.title('决策树可视化')
plt.show()

# 特征重要性
feature_importance = pd.DataFrame({
    'feature': X.columns,
    'importance': dt.feature_importances_
})
print("\n特征重要性:")
print(feature_importance.sort_values('importance', ascending=False))

3. 模型评估与优化

3.1 评估指标

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import roc_curve, auc

def evaluate_model(y_true, y_pred, y_prob=None):
    """评估分类模型性能"""
    print("模型评估指标:")
    print(f"准确率: {accuracy_score(y_true, y_pred):.3f}")
    print(f"精确率: {precision_score(y_true, y_pred):.3f}")
    print(f"召回率: {recall_score(y_true, y_pred):.3f}")
    print(f"F1分数: {f1_score(y_true, y_pred):.3f}")
    
    if y_prob is not None:
        # 绘制ROC曲线
        fpr, tpr, _ = roc_curve(y_true, y_prob)
        roc_auc = auc(fpr, tpr)
        
        plt.figure(figsize=(8, 6))
        plt.plot(fpr, tpr, color='darkorange', lw=2,
                 label=f'ROC curve (AUC = {roc_auc:.2f})')
        plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
        plt.xlim([0.0, 1.0])
        plt.ylim([0.0, 1.05])
        plt.xlabel('假正率')
        plt.ylabel('真正率')
        plt.title('接收者操作特征(ROC)曲线')
        plt.legend(loc="lower right")
        plt.show()

3.2 交叉验证

from sklearn.model_selection import cross_val_score, KFold
from sklearn.model_selection import learning_curve

def plot_learning_curve(estimator, X, y, cv=5):
    """绘制学习曲线"""
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=-1,
        train_sizes=np.linspace(0.1, 1.0, 10))
    
    # 计算平均值和标准差
    train_mean = np.mean(train_scores, axis=1)
    train_std = np.std(train_scores, axis=1)
    test_mean = np.mean(test_scores, axis=1)
    test_std = np.std(test_scores, axis=1)
    
    # 绘制学习曲线
    plt.figure(figsize=(10, 6))
    plt.plot(train_sizes, train_mean, label='训练集得分')
    plt.plot(train_sizes, test_mean, label='验证集得分')
    plt.fill_between(train_sizes, train_mean - train_std,
                     train_mean + train_std, alpha=0.1)
    plt.fill_between(train_sizes, test_mean - test_std,
                     test_mean + test_std, alpha=0.1)
    plt.xlabel('训练样本数')
    plt.ylabel('得分')
    plt.title('学习曲线')
    plt.legend(loc='best')
    plt.grid(True)
    plt.show()

3.3 超参数调优

from sklearn.model_selection import GridSearchCV

def optimize_model(model, param_grid, X, y, cv=5):
    """使用网格搜索优化模型超参数"""
    grid_search = GridSearchCV(model, param_grid, cv=cv, 
                             scoring='accuracy', n_jobs=-1)
    grid_search.fit(X, y)
    
    print("最佳参数:", grid_search.best_params_)
    print("最佳得分:", grid_search.best_score_)
    
    # 参数重要性可视化
    results = pd.DataFrame(grid_search.cv_results_)
    plt.figure(figsize=(12, 6))
    sns.boxplot(x='param_max_depth', y='mean_test_score', data=results)
    plt.xlabel('最大深度')
    plt.ylabel('交叉验证得分')
    plt.title('不同最大深度的模型性能')
    plt.show()
    
    return grid_search.best_estimator_

4. 实战案例:信用卡欺诈检测

4.1 数据准备

# 加载数据
df = pd.read_csv('credit_card_fraud.csv')

# 处理类别不平衡
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)

# 特征工程
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_resampled)

4.2 模型训练与评估

# 创建模型
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(random_state=42)

# 定义参数网格
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [10, 20, 30],
    'min_samples_split': [2, 5, 10]
}

# 优化模型
best_model = optimize_model(rf, param_grid, X_scaled, y_resampled)

# 预测和评估
y_pred = best_model.predict(X_test)
y_prob = best_model.predict_proba(X_test)[:, 1]

# 评估模型性能
evaluate_model(y_test, y_pred, y_prob)

常见问题解答

Q: 如何处理类别不平衡问题? A: 可以使用过采样(SMOTE)、欠采样或调整类别权重等方法。选择方法时需要考虑数据规模和业务需求。

Q: 如何选择合适的评估指标? A: 根据问题类型和业务目标选择。比如在欺诈检测中,召回率可能比准确率更重要;在医疗诊断中,精确率可能更重要。

Q: 如何避免过拟合? A: 可以使用交叉验证、正则化、早停等技术。同时,确保训练数据的质量和代表性也很重要。

扩展阅读