Skip to content

机器学习基础

1. 什么是机器学习

机器学习(Machine Learning, ML)是人工智能的一个重要分支,它使计算机系统能够通过经验自动改进性能,而无需明确编程。机器学习的核心思想是让计算机从数据中学习模式和规律,并利用这些模式对新数据进行预测或决策。

1.1 机器学习的定义

"机器学习是一种让计算机在没有明确编程的情况下学习的能力。" —— Arthur Samuel (1959)

"如果一个计算机程序在某类任务T上的性能(用P衡量)随着经验E的增加而改善,那么我们说这个程序从经验E中学习了任务T。" —— Tom Mitchell (1997)

1.2 机器学习与传统编程的区别

传统编程

  • 输入:数据 + 程序
  • 输出:结果
  • 特点:人工编写规则和逻辑

机器学习

  • 输入:数据 + 结果
  • 输出:程序(模型)
  • 特点:自动发现规律和模式

1.3 机器学习的应用场景

  • 推荐系统:电商平台商品推荐、视频平台内容推荐
  • 图像识别:人脸识别、医学影像诊断、自动驾驶
  • 自然语言处理:机器翻译、情感分析、智能客服
  • 金融风控:信用评估、欺诈检测、量化交易
  • 医疗健康:疾病诊断、药物发现、个性化治疗
  • 工业制造:质量检测、预测性维护、供应链优化

2. 机器学习的分类

2.1 按学习方式分类

2.1.1 监督学习(Supervised Learning)

定义:使用带标签的训练数据来学习输入和输出之间的映射关系。

特点

  • 训练数据包含输入特征和对应的标签
  • 目标是学习一个函数,能够对新的输入预测正确的输出
  • 可以评估模型的准确性

主要任务类型

分类(Classification)

  • 目标:预测离散的类别标签
  • 示例:邮件垃圾分类、图像识别、疾病诊断
  • 常用算法:逻辑回归、决策树、随机森林、SVM、神经网络
python
# 分类示例:鸢尾花分类
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 加载数据
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)

# 训练模型
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)

# 预测和评估
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"分类准确率: {accuracy:.4f}")

回归(Regression)

  • 目标:预测连续的数值
  • 示例:房价预测、股票价格预测、销量预测
  • 常用算法:线性回归、多项式回归、岭回归、支持向量回归
python
# 回归示例:房价预测
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# 加载数据
boston = load_boston()
X, y = boston.data, boston.target

# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

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

# 预测和评估
y_pred = reg.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"均方误差: {mse:.4f}")
print(f"R²得分: {r2:.4f}")

2.1.2 无监督学习(Unsupervised Learning)

定义:从没有标签的数据中发现隐藏的模式和结构。

特点

  • 训练数据只有输入特征,没有标签
  • 目标是发现数据的内在结构
  • 难以直接评估模型性能

主要任务类型

聚类(Clustering)

  • 目标:将相似的数据点分组
  • 示例:客户细分、基因分析、图像分割
  • 常用算法:K-means、层次聚类、DBSCAN
python
# 聚类示例:客户细分
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

# 生成示例数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# K-means聚类
kmeans = KMeans(n_clusters=4, random_state=42)
y_pred = kmeans.fit_predict(X)

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], 
           c='red', marker='x', s=200, linewidths=3)
plt.title('K-means聚类结果')
plt.show()

降维(Dimensionality Reduction)

  • 目标:减少数据的维度,保留重要信息
  • 示例:数据可视化、特征选择、噪声去除
  • 常用算法:PCA、t-SNE、LDA
python
# 降维示例:PCA降维
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits

# 加载数据
digits = load_digits()
X = digits.data

# PCA降维
pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X)

# 可视化
plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=digits.target, cmap='tab10')
plt.colorbar(scatter)
plt.title('PCA降维可视化')
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')
plt.show()

关联规则挖掘

  • 目标:发现数据项之间的关联关系
  • 示例:购物篮分析、网页访问模式
  • 常用算法:Apriori、FP-Growth

2.1.3 强化学习(Reinforcement Learning)

定义:通过与环境交互,学习在特定情况下采取何种行动以获得最大奖励。

特点

  • 没有直接的监督信号,只有奖励信号
  • 需要在探索和利用之间平衡
  • 适用于序列决策问题

应用示例

  • 游戏AI(AlphaGo、Dota2 AI)
  • 自动驾驶
  • 机器人控制
  • 推荐系统优化
python
# 强化学习示例:Q-learning解决迷宫问题
import numpy as np
import random

class QLearningAgent:
    def __init__(self, states, actions, learning_rate=0.1, discount_factor=0.9, epsilon=0.1):
        self.states = states
        self.actions = actions
        self.lr = learning_rate
        self.gamma = discount_factor
        self.epsilon = epsilon
        self.q_table = np.zeros((states, actions))
    
    def choose_action(self, state):
        if random.uniform(0, 1) < self.epsilon:
            return random.choice(range(self.actions))  # 探索
        else:
            return np.argmax(self.q_table[state])  # 利用
    
    def update_q_table(self, state, action, reward, next_state):
        current_q = self.q_table[state, action]
        max_next_q = np.max(self.q_table[next_state])
        new_q = current_q + self.lr * (reward + self.gamma * max_next_q - current_q)
        self.q_table[state, action] = new_q

# 使用示例
agent = QLearningAgent(states=16, actions=4)  # 4x4迷宫,4个动作
print("Q-learning智能体已创建")

2.2 按算法类型分类

2.2.1 参数化方法

  • 特点:假设数据符合特定的概率分布
  • 优点:计算效率高,理论基础扎实
  • 缺点:可能不适合复杂的非线性关系
  • 示例:线性回归、逻辑回归、朴素贝叶斯

2.2.2 非参数化方法

  • 特点:不对数据分布做强假设
  • 优点:灵活性高,适应性强
  • 缺点:计算复杂度较高
  • 示例:K近邻、决策树、核方法

2.2.3 集成方法

  • 特点:结合多个基础模型的预测结果
  • 优点:通常具有更好的泛化能力
  • 缺点:模型复杂度高,解释性差
  • 示例:随机森林、梯度提升、AdaBoost

3. 机器学习的核心概念

3.1 特征工程

特征工程是机器学习中最重要的环节之一,好的特征往往比复杂的算法更重要。

3.1.1 特征选择

目标:从原始特征中选择最相关的特征子集。

方法

  • 过滤法:基于统计指标选择特征
  • 包装法:基于模型性能选择特征
  • 嵌入法:在模型训练过程中选择特征
python
# 特征选择示例
from sklearn.feature_selection import SelectKBest, chi2, RFE
from sklearn.ensemble import RandomForestClassifier

# 过滤法:卡方检验
selector = SelectKBest(chi2, k=10)
X_selected = selector.fit_transform(X, y)

# 包装法:递归特征消除
estimator = RandomForestClassifier(n_estimators=100)
rfe = RFE(estimator, n_features_to_select=10)
X_rfe = rfe.fit_transform(X, y)

print(f"原始特征数: {X.shape[1]}")
print(f"选择后特征数: {X_selected.shape[1]}")

3.1.2 特征构造

数值特征处理

python
# 数值特征处理示例
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 归一化
normalizer = MinMaxScaler()
X_normalized = normalizer.fit_transform(X)

# 鲁棒缩放
robust_scaler = RobustScaler()
X_robust = robust_scaler.fit_transform(X)

类别特征处理

python
# 类别特征处理示例
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import pandas as pd

# 标签编码
le = LabelEncoder()
categorical_encoded = le.fit_transform(categorical_data)

# 独热编码
ohe = OneHotEncoder(sparse=False)
categorical_onehot = ohe.fit_transform(categorical_data.reshape(-1, 1))

# 使用pandas进行独热编码
df_encoded = pd.get_dummies(df, columns=['category_column'])

3.2 模型评估

3.2.1 分类问题评估指标

混淆矩阵

python
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns

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

# 可视化混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('混淆矩阵')
plt.ylabel('真实标签')
plt.xlabel('预测标签')
plt.show()

# 详细分类报告
print(classification_report(y_test, y_pred))

主要指标

  • 准确率(Accuracy):正确预测的比例
  • 精确率(Precision):预测为正例中实际为正例的比例
  • 召回率(Recall):实际正例中被正确预测的比例
  • F1分数:精确率和召回率的调和平均数
python
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average='weighted')
recall = recall_score(y_test, y_pred, average='weighted')
f1 = f1_score(y_test, y_pred, average='weighted')

print(f"准确率: {accuracy:.4f}")
print(f"精确率: {precision:.4f}")
print(f"召回率: {recall:.4f}")
print(f"F1分数: {f1:.4f}")

3.2.2 回归问题评估指标

python
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np

# 主要回归指标
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"平均绝对误差 (MAE): {mae:.4f}")
print(f"均方误差 (MSE): {mse:.4f}")
print(f"均方根误差 (RMSE): {rmse:.4f}")
print(f"决定系数 (R²): {r2:.4f}")

3.3 交叉验证

交叉验证是评估模型泛化能力的重要方法。

python
from sklearn.model_selection import cross_val_score, StratifiedKFold

# K折交叉验证
cv_scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print(f"交叉验证得分: {cv_scores}")
print(f"平均得分: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")

# 分层K折交叉验证(适用于不平衡数据)
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
stratified_scores = cross_val_score(clf, X, y, cv=skf, scoring='accuracy')
print(f"分层交叉验证得分: {stratified_scores.mean():.4f}")

3.4 过拟合与欠拟合

3.4.1 概念理解

过拟合(Overfitting)

  • 模型在训练数据上表现很好,但在测试数据上表现较差
  • 模型过于复杂,学习了训练数据中的噪声

欠拟合(Underfitting)

  • 模型在训练数据和测试数据上都表现较差
  • 模型过于简单,无法捕捉数据中的模式

3.4.2 诊断方法

python
# 学习曲线诊断
from sklearn.model_selection import learning_curve

def plot_learning_curve(estimator, X, y, title="学习曲线"):
    train_sizes, train_scores, val_scores = learning_curve(
        estimator, X, y, cv=5, 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)
    val_mean = np.mean(val_scores, axis=1)
    val_std = np.std(val_scores, axis=1)
    
    plt.figure(figsize=(10, 6))
    plt.plot(train_sizes, train_mean, 'o-', color='blue', label='训练得分')
    plt.fill_between(train_sizes, train_mean - train_std, train_mean + train_std, alpha=0.1, color='blue')
    plt.plot(train_sizes, val_mean, 'o-', color='red', label='验证得分')
    plt.fill_between(train_sizes, val_mean - val_std, val_mean + val_std, alpha=0.1, color='red')
    
    plt.xlabel('训练样本数')
    plt.ylabel('得分')
    plt.title(title)
    plt.legend()
    plt.grid(True)
    plt.show()

# 使用示例
plot_learning_curve(RandomForestClassifier(), X, y)

3.4.3 解决方法

解决过拟合

  • 增加训练数据
  • 特征选择
  • 正则化
  • 早停法
  • 集成方法
python
# 正则化示例:岭回归
from sklearn.linear_model import Ridge, RidgeCV

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

# 交叉验证选择最佳alpha
ridge_cv = RidgeCV(alphas=[0.1, 1.0, 10.0, 100.0], cv=5)
ridge_cv.fit(X_train, y_train)
print(f"最佳alpha: {ridge_cv.alpha_}")

解决欠拟合

  • 增加模型复杂度
  • 添加更多特征
  • 减少正则化强度
  • 使用更复杂的算法

4. 常用机器学习算法

4.1 线性模型

4.1.1 线性回归

python
# 线性回归实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

class SimpleLinearRegression:
    def __init__(self):
        self.slope = None
        self.intercept = None
    
    def fit(self, X, y):
        # 计算斜率和截距
        n = len(X)
        self.slope = (n * np.sum(X * y) - np.sum(X) * np.sum(y)) / (n * np.sum(X**2) - (np.sum(X))**2)
        self.intercept = (np.sum(y) - self.slope * np.sum(X)) / n
    
    def predict(self, X):
        return self.slope * X + self.intercept

# 使用示例
X = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])

model = SimpleLinearRegression()
model.fit(X, y)
predictions = model.predict(X)

plt.scatter(X, y, color='blue', label='实际值')
plt.plot(X, predictions, color='red', label='预测值')
plt.legend()
plt.title('简单线性回归')
plt.show()

4.1.2 逻辑回归

python
# 逻辑回归示例
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# 生成二分类数据
X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0, 
                          n_informative=2, n_clusters_per_class=1, random_state=42)

# 训练逻辑回归模型
log_reg = LogisticRegression()
log_reg.fit(X, y)

# 可视化决策边界
def plot_decision_boundary(X, y, model, title="决策边界"):
    plt.figure(figsize=(10, 8))
    
    # 创建网格
    h = 0.02
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                        np.arange(y_min, y_max, h))
    
    # 预测网格点
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    # 绘制决策边界
    plt.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.RdYlBu)
    scatter = plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.RdYlBu, edgecolors='black')
    plt.colorbar(scatter)
    plt.title(title)
    plt.show()

plot_decision_boundary(X, y, log_reg, "逻辑回归决策边界")

4.2 树模型

4.2.1 决策树

python
# 决策树示例
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris

# 加载数据
iris = load_iris()
X, y = iris.data[:, [2, 3]], iris.target  # 只使用两个特征便于可视化

# 训练决策树
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(X, y)

# 可视化决策树
plt.figure(figsize=(15, 10))
plot_tree(dt, feature_names=['花瓣长度', '花瓣宽度'], 
         class_names=iris.target_names, filled=True, rounded=True)
plt.title('鸢尾花分类决策树')
plt.show()

# 特征重要性
feature_importance = dt.feature_importances_
print("特征重要性:")
for i, importance in enumerate(feature_importance):
    print(f"特征 {i}: {importance:.4f}")

4.2.2 随机森林

python
# 随机森林示例
from sklearn.ensemble import RandomForestClassifier

# 训练随机森林
rf = RandomForestClassifier(n_estimators=100, max_depth=3, random_state=42)
rf.fit(X_train, y_train)

# 预测和评估
y_pred_rf = rf.predict(X_test)
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print(f"随机森林准确率: {accuracy_rf:.4f}")

# 特征重要性
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]

plt.figure(figsize=(10, 6))
plt.title("特征重要性排序")
plt.bar(range(len(importances)), importances[indices])
plt.xticks(range(len(importances)), [f"特征 {i}" for i in indices])
plt.show()

4.3 支持向量机

python
# SVM示例
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler

# 数据标准化(SVM对特征尺度敏感)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 训练SVM模型
svm_linear = SVC(kernel='linear', random_state=42)
svm_rbf = SVC(kernel='rbf', random_state=42)

svm_linear.fit(X_train_scaled, y_train)
svm_rbf.fit(X_train_scaled, y_train)

# 比较不同核函数的性能
y_pred_linear = svm_linear.predict(X_test_scaled)
y_pred_rbf = svm_rbf.predict(X_test_scaled)

print(f"线性核SVM准确率: {accuracy_score(y_test, y_pred_linear):.4f}")
print(f"RBF核SVM准确率: {accuracy_score(y_test, y_pred_rbf):.4f}")

4.4 K近邻算法

python
# KNN示例
from sklearn.neighbors import KNeighborsClassifier

# 不同k值的性能比较
k_values = range(1, 21)
accuracies = []

for k in k_values:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, y_train)
    y_pred = knn.predict(X_test)
    accuracies.append(accuracy_score(y_test, y_pred))

# 可视化k值对性能的影响
plt.figure(figsize=(10, 6))
plt.plot(k_values, accuracies, 'bo-')
plt.xlabel('k值')
plt.ylabel('准确率')
plt.title('KNN算法中k值对性能的影响')
plt.grid(True)
plt.show()

# 选择最佳k值
best_k = k_values[np.argmax(accuracies)]
print(f"最佳k值: {best_k}, 对应准确率: {max(accuracies):.4f}")

5. 机器学习项目流程

5.1 问题定义

  1. 明确业务目标:确定要解决的具体问题
  2. 确定问题类型:分类、回归、聚类等
  3. 定义成功指标:准确率、召回率、业务指标等
  4. 评估可行性:数据可用性、技术难度、资源需求

5.2 数据收集与探索

python
# 数据探索示例
import pandas as pd
import seaborn as sns

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

# 基本信息
print("数据基本信息:")
print(df.info())
print("\n数据描述统计:")
print(df.describe())

# 缺失值检查
print("\n缺失值统计:")
print(df.isnull().sum())

# 数据分布可视化
plt.figure(figsize=(15, 10))
for i, column in enumerate(df.select_dtypes(include=[np.number]).columns):
    plt.subplot(2, 3, i+1)
    plt.hist(df[column], bins=30, alpha=0.7)
    plt.title(f'{column} 分布')
    plt.xlabel(column)
    plt.ylabel('频次')
plt.tight_layout()
plt.show()

# 相关性分析
plt.figure(figsize=(10, 8))
correlation_matrix = df.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('特征相关性热力图')
plt.show()

5.3 数据预处理

python
# 完整的数据预处理流程
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.impute import SimpleImputer

class DataPreprocessor:
    def __init__(self):
        self.scalers = {}
        self.encoders = {}
        self.imputers = {}
    
    def fit_transform(self, df):
        df_processed = df.copy()
        
        # 处理数值特征
        numeric_columns = df.select_dtypes(include=[np.number]).columns
        for col in numeric_columns:
            # 处理缺失值
            imputer = SimpleImputer(strategy='median')
            df_processed[col] = imputer.fit_transform(df_processed[[col]]).ravel()
            self.imputers[col] = imputer
            
            # 标准化
            scaler = StandardScaler()
            df_processed[col] = scaler.fit_transform(df_processed[[col]]).ravel()
            self.scalers[col] = scaler
        
        # 处理类别特征
        categorical_columns = df.select_dtypes(include=['object']).columns
        for col in categorical_columns:
            # 处理缺失值
            df_processed[col].fillna(df_processed[col].mode()[0], inplace=True)
            
            # 标签编码
            encoder = LabelEncoder()
            df_processed[col] = encoder.fit_transform(df_processed[col])
            self.encoders[col] = encoder
        
        return df_processed
    
    def transform(self, df):
        df_processed = df.copy()
        
        # 应用已训练的预处理器
        for col in df.select_dtypes(include=[np.number]).columns:
            if col in self.imputers:
                df_processed[col] = self.imputers[col].transform(df_processed[[col]]).ravel()
            if col in self.scalers:
                df_processed[col] = self.scalers[col].transform(df_processed[[col]]).ravel()
        
        for col in df.select_dtypes(include=['object']).columns:
            if col in self.encoders:
                df_processed[col].fillna(df_processed[col].mode()[0], inplace=True)
                df_processed[col] = self.encoders[col].transform(df_processed[col])
        
        return df_processed

# 使用示例
preprocessor = DataPreprocessor()
df_processed = preprocessor.fit_transform(df)

5.4 模型选择与训练

python
# 多模型比较
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

# 定义多个模型
models = {
    'Logistic Regression': LogisticRegression(random_state=42),
    'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
    'SVM': SVC(random_state=42),
    'Gradient Boosting': GradientBoostingClassifier(random_state=42)
}

# 比较模型性能
results = {}
for name, model in models.items():
    cv_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')
    results[name] = {
        'mean': cv_scores.mean(),
        'std': cv_scores.std()
    }
    print(f"{name}: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")

# 选择最佳模型
best_model_name = max(results, key=lambda x: results[x]['mean'])
best_model = models[best_model_name]
print(f"\n最佳模型: {best_model_name}")

5.5 超参数调优

python
# 网格搜索调优
from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [3, 5, 7, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# 网格搜索
rf = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(rf, 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_:.4f}")

# 使用最佳模型
best_rf = grid_search.best_estimator_

5.6 模型评估与部署

python
# 最终模型评估
final_predictions = best_rf.predict(X_test)
final_accuracy = accuracy_score(y_test, final_predictions)

print(f"最终测试准确率: {final_accuracy:.4f}")
print("\n详细分类报告:")
print(classification_report(y_test, final_predictions))

# 模型保存
import joblib

# 保存模型
joblib.dump(best_rf, 'best_model.pkl')
joblib.dump(preprocessor, 'preprocessor.pkl')

# 加载模型
loaded_model = joblib.load('best_model.pkl')
loaded_preprocessor = joblib.load('preprocessor.pkl')

print("模型已保存并可以重新加载使用")

6. 实际应用案例

6.1 客户流失预测

python
# 客户流失预测完整案例
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, roc_auc_score, roc_curve

# 模拟客户数据
np.random.seed(42)
n_customers = 1000

data = {
    'age': np.random.randint(18, 80, n_customers),
    'tenure': np.random.randint(1, 60, n_customers),
    'monthly_charges': np.random.uniform(20, 120, n_customers),
    'total_charges': np.random.uniform(100, 8000, n_customers),
    'contract_type': np.random.choice(['Month-to-month', 'One year', 'Two year'], n_customers),
    'payment_method': np.random.choice(['Electronic check', 'Mailed check', 'Bank transfer', 'Credit card'], n_customers),
    'internet_service': np.random.choice(['DSL', 'Fiber optic', 'No'], n_customers),
}

# 创建目标变量(流失标签)
churn_probability = (
    0.1 + 
    0.3 * (data['contract_type'] == 'Month-to-month') +
    0.2 * (data['monthly_charges'] > 80) +
    0.1 * (data['tenure'] < 12) +
    0.1 * (data['payment_method'] == 'Electronic check')
)

data['churn'] = np.random.binomial(1, churn_probability, n_customers)

df = pd.DataFrame(data)

# 数据预处理
df_encoded = pd.get_dummies(df, columns=['contract_type', 'payment_method', 'internet_service'])

# 分离特征和目标
X = df_encoded.drop('churn', axis=1)
y = df_encoded['churn']

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

# 训练模型
rf_churn = RandomForestClassifier(n_estimators=100, random_state=42)
rf_churn.fit(X_train, y_train)

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

print("客户流失预测结果:")
print(classification_report(y_test, y_pred))
print(f"AUC得分: {roc_auc_score(y_test, y_pred_proba):.4f}")

# ROC曲线
fpr, tpr, _ = roc_curve(y_test, y_pred_proba)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'ROC曲线 (AUC = {roc_auc_score(y_test, y_pred_proba):.4f})')
plt.plot([0, 1], [0, 1], 'k--', label='随机分类器')
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.title('ROC曲线 - 客户流失预测')
plt.legend()
plt.show()

# 特征重要性分析
feature_importance = pd.DataFrame({
    'feature': X.columns,
    'importance': rf_churn.feature_importances_
}).sort_values('importance', ascending=False)

plt.figure(figsize=(10, 6))
plt.barh(feature_importance['feature'][:10], feature_importance['importance'][:10])
plt.xlabel('重要性')
plt.title('客户流失预测 - 前10个重要特征')
plt.gca().invert_yaxis()
plt.show()

6.2 房价预测

python
# 房价预测案例
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error

# 模拟房价数据
np.random.seed(42)
n_houses = 1000

house_data = {
    'area': np.random.uniform(50, 300, n_houses),
    'bedrooms': np.random.randint(1, 6, n_houses),
    'bathrooms': np.random.randint(1, 4, n_houses),
    'age': np.random.randint(0, 50, n_houses),
    'location_score': np.random.uniform(1, 10, n_houses),
    'garage': np.random.choice([0, 1], n_houses),
}

# 创建房价(基于特征的线性组合加噪声)
price = (
    house_data['area'] * 1000 +
    house_data['bedrooms'] * 5000 +
    house_data['bathrooms'] * 8000 +
    (50 - house_data['age']) * 500 +
    house_data['location_score'] * 10000 +
    house_data['garage'] * 15000 +
    np.random.normal(0, 20000, n_houses)
)

house_data['price'] = np.maximum(price, 50000)  # 确保价格为正

df_house = pd.DataFrame(house_data)

# 数据分割
X_house = df_house.drop('price', axis=1)
y_house = df_house['price']

X_train_house, X_test_house, y_train_house, y_test_house = train_test_split(
    X_house, y_house, test_size=0.2, random_state=42
)

# 训练梯度提升回归模型
gbr = GradientBoostingRegressor(n_estimators=100, random_state=42)
gbr.fit(X_train_house, y_train_house)

# 预测和评估
y_pred_house = gbr.predict(X_test_house)

mae = mean_absolute_error(y_test_house, y_pred_house)
mse = mean_squared_error(y_test_house, y_pred_house)
rmse = np.sqrt(mse)

print("房价预测结果:")
print(f"平均绝对误差: ${mae:,.2f}")
print(f"均方根误差: ${rmse:,.2f}")

# 预测vs实际值散点图
plt.figure(figsize=(10, 8))
plt.scatter(y_test_house, y_pred_house, alpha=0.6)
plt.plot([y_test_house.min(), y_test_house.max()], 
         [y_test_house.min(), y_test_house.max()], 'r--', lw=2)
plt.xlabel('实际房价')
plt.ylabel('预测房价')
plt.title('房价预测:实际值 vs 预测值')
plt.show()

# 残差分析
residuals = y_test_house - y_pred_house
plt.figure(figsize=(10, 6))
plt.scatter(y_pred_house, residuals, alpha=0.6)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('预测房价')
plt.ylabel('残差')
plt.title('残差分析')
plt.show()

7. 最佳实践与建议

7.1 数据质量

  1. 数据收集:确保数据的代表性和完整性
  2. 数据清洗:处理缺失值、异常值和重复数据
  3. 数据验证:检查数据的一致性和合理性
  4. 数据更新:建立数据更新机制,保持数据的时效性

7.2 特征工程

  1. 领域知识:结合业务理解创建有意义的特征
  2. 特征选择:去除冗余和无关特征
  3. 特征变换:标准化、归一化、对数变换等
  4. 特征组合:创建交互特征和多项式特征

7.3 模型选择

  1. 简单优先:从简单模型开始,逐步增加复杂度
  2. 多模型比较:尝试不同类型的算法
  3. 集成方法:结合多个模型的优势
  4. 领域适配:选择适合特定领域的算法

7.4 模型评估

  1. 多指标评估:不要只关注单一指标
  2. 交叉验证:使用适当的验证策略
  3. 业务指标:关注对业务有意义的指标
  4. 模型解释:理解模型的决策过程

7.5 部署与监控

  1. 模型版本管理:跟踪模型的版本和变更
  2. 性能监控:持续监控模型在生产环境中的表现
  3. 数据漂移检测:监控输入数据的分布变化
  4. 模型更新:建立模型重训练和更新机制