本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:机器学习是人工智能的重要分支,Python凭借其简洁高效的语法和丰富的库(如Scikit-Learn)成为实现机器学习任务的首选语言。本资料包“machinelearninginaction”包含大量Python代码实例,覆盖监督学习、无监督学习及半监督学习的核心算法,帮助学习者通过实践掌握数据预处理、模型构建、评估优化和部署全流程。适合初学者入门及开发者进阶,理论结合实践,提升机器学习编程与数据分析能力。
机器学习例子(Python代码)

1. 机器学习基础概念

机器学习是人工智能的核心分支,旨在通过数据驱动的方式,使计算机系统具备从经验中学习并改进自身性能的能力。其核心思想是通过构建模型,从数据中自动学习规律,并用于预测或决策。

根据学习方式的不同,机器学习主要分为三大类: 监督学习 (如线性回归、逻辑回归)、 无监督学习 (如聚类、降维)和 强化学习 (如Q-learning、策略优化)。每种类型适用于不同的问题场景,理解它们的差异是构建有效模型的前提。

此外,机器学习系统由四个核心要素构成: 数据 (输入)、 模型 (学习机制)、 算法 (训练过程)以及 评估 (性能度量)。这些要素相互依赖,缺一不可,构成了完整的机器学习闭环。

2. Python在机器学习中的应用

Python 已经成为机器学习领域中最主流的编程语言之一,其优势不仅体现在语言本身的简洁与可读性上,更在于它拥有一个庞大且活跃的生态系统,能够支持从数据处理、模型构建到可视化、部署等各个阶段的工作。本章将从 Python 语言的优势出发,逐步介绍其在机器学习中的具体应用场景,并通过开发环境的搭建、核心数据结构的操作,以及可视化工具的使用,为后续章节中模型构建和训练打下坚实的基础。

2.1 Python语言的优势与机器学习生态

Python 在机器学习领域的广泛应用,离不开其语言特性和丰富的第三方库生态。Python 的设计哲学强调代码的可读性和简洁性,这使得即使是非专业程序员也能快速上手并进行开发。同时,Python 社区活跃,各类库和工具持续更新,尤其在机器学习、数据科学和人工智能领域,Python 已成为首选语言。

2.1.1 Python语言的简洁性与可读性

Python 语言的设计理念强调“代码即文档”,其语法简洁明了,避免了冗余的符号和复杂的结构。例如,Python 使用缩进来表示代码块,而不是像 C 或 Java 那样使用花括号。这种设计使得代码结构更加清晰,提高了可读性和可维护性。

def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

代码解释:

  • def greet(name): 定义了一个名为 greet 的函数,参数为 name
  • print(f"Hello, {name}!") 使用 f-string(格式化字符串字面量)将变量 name 插入到字符串中。
  • greet("Alice") 调用函数并传入参数 "Alice"

这种简洁的语法结构,使得开发者能够将注意力集中在算法逻辑和数据处理上,而不是语法细节上。

2.1.2 常用机器学习库概览(NumPy、Pandas、Matplotlib、Scikit-Learn)

Python 的强大之处在于其丰富的库支持。以下是一些在机器学习中最常用的库:

库名 主要功能说明
NumPy 提供高性能的多维数组对象,支持数学运算
Pandas 提供灵活的数据结构(DataFrame、Series),用于数据清洗和处理
Matplotlib 提供2D绘图功能,用于数据可视化
Scikit-Learn 提供经典的机器学习算法和模型评估工具
Seaborn 基于 Matplotlib 的高级可视化库,简化图表绘制
TensorFlow / PyTorch 深度学习框架,支持复杂模型构建与训练
示例:使用 Pandas 读取 CSV 数据并展示前5行
import pandas as pd

# 读取CSV文件
df = pd.read_csv('data.csv')

# 展示前5行数据
print(df.head())

代码解释:

  • import pandas as pd 导入 Pandas 模块并设置别名为 pd
  • pd.read_csv('data.csv') 读取名为 data.csv 的 CSV 文件,返回一个 DataFrame 对象。
  • df.head() 展示 DataFrame 的前五行数据。
示例:使用 Matplotlib 绘制散点图
import matplotlib.pyplot as plt

# 示例数据
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

# 绘制散点图
plt.scatter(x, y)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.title("Scatter Plot")
plt.show()

代码解释:

  • plt.scatter(x, y) 绘制散点图。
  • plt.xlabel plt.ylabel 设置坐标轴标签。
  • plt.title 设置图表标题。
  • plt.show() 显示图表。
Mermaid 流程图:Python 在机器学习项目中的流程
graph TD
    A[数据加载] --> B[数据清洗]
    B --> C[特征工程]
    C --> D[模型训练]
    D --> E[模型评估]
    E --> F[模型部署]

该流程图展示了一个典型的机器学习项目流程,从数据加载到最终部署的完整路径。Python 的生态系统几乎覆盖了整个流程,每个环节都有对应的库支持。

2.2 Python开发环境搭建

为了高效地进行机器学习项目的开发,搭建一个合适的开发环境至关重要。Python 提供了多种方式来管理开发环境,其中 Anaconda 和 Jupyter Notebook 是最常用的工具之一。

2.2.1 Anaconda与Jupyter Notebook配置

Anaconda 是一个开源的 Python 和 R 的发行版,专为数据科学和机器学习而设计。它集成了 Python 解释器、Conda 包管理器以及大量的科学计算和机器学习库。

安装 Anaconda
  1. 下载 Anaconda 安装包: https://www.anaconda.com/products/distribution
  2. 根据操作系统选择对应版本进行安装。
  3. 安装完成后,打开终端或命令行,输入 conda --version 检查是否安装成功。
使用 Jupyter Notebook

Jupyter Notebook 是一个基于 Web 的交互式开发环境,非常适合用于数据分析和机器学习原型开发。

启动 Jupyter Notebook:

jupyter notebook

该命令将在浏览器中打开 Jupyter Notebook 的界面,用户可以在其中创建新的 Python Notebook 并开始编写代码。

示例:在 Jupyter Notebook 中运行代码
import numpy as np

# 创建一个 3x3 的随机数组
random_array = np.random.rand(3, 3)

# 打印数组
print(random_array)

代码解释:

  • np.random.rand(3, 3) 生成一个 3 行 3 列的随机数组,数值范围在 [0, 1) 之间。
  • print(random_array) 打印数组内容。

2.2.2 虚拟环境管理与依赖安装

在项目开发中,使用虚拟环境可以有效隔离不同项目的依赖库,避免版本冲突。

创建 Conda 虚拟环境:
conda create -n ml_env python=3.9

该命令创建了一个名为 ml_env 的虚拟环境,并指定 Python 版本为 3.9。

激活虚拟环境:
conda activate ml_env
安装依赖库:
conda install numpy pandas scikit-learn matplotlib

或使用 pip:

pip install numpy pandas scikit-learn matplotlib
示例:在虚拟环境中安装并使用 scikit-learn
conda activate ml_env
pip install scikit-learn
from sklearn.linear_model import LinearRegression

# 示例数据
X = [[1], [2], [3]]
y = [2, 4, 6]

# 创建模型
model = LinearRegression()

# 训练模型
model.fit(X, y)

# 预测
print(model.predict([[4]]))

代码解释:

  • LinearRegression() 创建一个线性回归模型。
  • model.fit(X, y) 使用训练数据拟合模型。
  • model.predict([[4]]) 对输入值 4 进行预测。

2.3 Python数据结构与机器学习适配

Python 提供了多种数据结构,如列表、元组、字典、集合等,而 NumPy 和 Pandas 则提供了更适合机器学习任务的高性能数据结构。

2.3.1 NumPy数组操作与数学运算

NumPy 是 Python 中用于科学计算的核心库,提供了高性能的多维数组对象 ndarray ,并支持向量化操作。

示例:创建和操作 NumPy 数组
import numpy as np

# 创建一维数组
a = np.array([1, 2, 3])

# 创建二维数组
b = np.array([[1, 2], [3, 4]])

# 数组形状
print("Shape of b:", b.shape)

# 数组维度
print("Number of dimensions:", b.ndim)

# 数组元素类型
print("Data type:", b.dtype)

# 数组运算
c = a + 2
print("a + 2 =", c)

代码解释:

  • np.array() 创建 NumPy 数组。
  • shape 返回数组的维度信息。
  • ndim 返回数组的维度数量。
  • dtype 返回数组元素的数据类型。
  • 支持向量化运算,如 a + 2

2.3.2 Pandas数据框的构建与处理

Pandas 是 Python 中用于数据处理的强大库,主要提供了 DataFrame Series 两种数据结构。

示例:创建并操作 DataFrame
import pandas as pd

# 创建 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'London', 'Paris']
}

df = pd.DataFrame(data)

# 查看数据
print(df)

# 筛选数据
print("\nAge > 30:")
print(df[df['Age'] > 30])

# 添加新列
df['Salary'] = [50000, 60000, 70000]

# 保存为 CSV
df.to_csv('output.csv', index=False)

代码解释:

  • pd.DataFrame(data) 创建一个 DataFrame。
  • df[df['Age'] > 30] 筛选出年龄大于 30 的行。
  • df['Salary'] = [...] 添加新列。
  • to_csv() 将数据保存为 CSV 文件。

2.3.3 数据可视化基础(Matplotlib与Seaborn)

数据可视化是机器学习中不可或缺的一环。Matplotlib 是 Python 中最基础的绘图库,而 Seaborn 则在其基础上进行了封装,提供了更高层次的接口。

示例:使用 Seaborn 绘制柱状图
import seaborn as sns
import matplotlib.pyplot as plt

# 示例数据
tips = sns.load_dataset("tips")

# 绘制柱状图
sns.barplot(x="day", y="total_bill", data=tips)
plt.title("Average Total Bill by Day")
plt.show()

代码解释:

  • sns.load_dataset("tips") 加载内置的 tips 数据集。
  • sns.barplot() 绘制柱状图,显示每天的平均账单。
  • plt.title() 设置图表标题。
  • plt.show() 显示图表。

本章通过介绍 Python 语言的简洁性、丰富的库生态、开发环境的搭建以及数据结构的使用,为后续的机器学习建模打下了坚实的基础。下一章将深入探讨 Scikit-Learn 库的核心模块及其在数据预处理中的应用。

3. Scikit-Learn库核心模块与数据预处理

在机器学习的实际应用中,数据预处理是一个不可或缺的环节。Scikit-Learn(简称sklearn)作为Python中最为流行和广泛使用的机器学习库之一,提供了丰富的工具和模块,用于数据清洗、特征工程、标准化处理以及模型构建。本章将深入探讨Scikit-Learn库的核心模块,特别是Estimator与Transformer接口、Pipeline机制,并重点讲解如何使用这些工具进行数据预处理,包括缺失值处理、异常值检测、标准化与归一化、类别特征编码等关键步骤。

3.1 Scikit-Learn基础模块介绍

Scikit-Learn 的设计高度模块化,其核心理念是面向对象编程,主要通过 Estimator Transformer 接口来构建机器学习流程。此外, Pipeline 提供了将多个处理步骤串联起来的能力,从而实现高效、可复用的代码结构。

3.1.1 Estimator与Transformer接口

Estimator接口

在 Scikit-Learn 中,所有的模型(如线性回归、决策树、随机森林等)都实现了 Estimator 接口。这个接口定义了两个核心方法:

  • fit(X, y) :用于训练模型,其中 X 是特征矩阵, y 是目标变量。
  • predict(X) :用于对新的数据进行预测。

示例代码如下:

from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression

# 生成一个简单的回归数据集
X, y = make_regression(n_samples=100, n_features=1, noise=0.1)

# 创建线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X, y)

# 进行预测
predictions = model.predict(X)

代码逐行解读:

  1. make_regression :生成用于回归任务的合成数据。
  2. LinearRegression() :创建一个线性回归模型实例。
  3. fit() :模型根据输入数据进行训练,学习参数。
  4. predict() :使用训练好的模型进行预测。
Transformer接口

Transformer 是用于数据预处理和特征工程的核心接口。它定义了两个方法:

  • fit(X, y) :学习数据的转换规则(例如标准化的均值和标准差)。
  • transform(X) :将转换规则应用到数据上。
  • 有些 Transformer 还实现了 fit_transform(X, y) ,用于同时学习和应用转换。

示例:标准化数据

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

代码说明:

  • StandardScaler() :创建标准化器。
  • fit_transform() :计算均值和标准差并应用标准化。

3.1.2 Pipeline机制与模型串联

在实际应用中,往往需要将多个预处理步骤与模型训练串联起来。Scikit-Learn 提供了 Pipeline 类来实现这一目标。

Pipeline 的结构

一个 Pipeline 是由多个步骤组成的序列,每个步骤是一个元组(名称,对象),对象可以是 Transformer Estimator

示例代码:

from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('regressor', LinearRegression())
])

# 训练模型
pipe.fit(X, y)

# 预测
predictions = pipe.predict(X)

代码解读:

  1. Pipeline([...]) :创建一个包含两个步骤的流水线。
  2. scaler :标准化器。
  3. regressor :线性回归模型。
  4. fit() :Pipeline 自动按顺序执行标准化和模型训练。
  5. predict() :标准化后输入模型预测。
使用 Pipeline 的优势
  • 代码简洁 :避免手动重复调用 fit/transform。
  • 避免数据泄露 :确保预处理只在训练集上学习,避免测试数据影响训练。
  • 可复用性强 :便于保存和部署整个流程。

3.2 数据清洗与缺失值处理

在真实数据中,缺失值和异常值是常见问题。Scikit-Learn 提供了多种工具来帮助我们进行缺失值填充和异常值处理。

3.2.1 缺失值检测与填充策略

检测缺失值

使用 Pandas 的 isnull().sum() 可以快速查看各列缺失值数量:

import pandas as pd
df = pd.DataFrame({'A': [1, 2, None], 'B': [None, 3, 4]})
print(df.isnull().sum())

输出:

A    1
B    1
dtype: int64
填充缺失值

Scikit-Learn 提供了 SimpleImputer 来填充缺失值:

from sklearn.impute import SimpleImputer
import numpy as np

X = np.array([[1, 2], [np.nan, 3], [7, 6]])

imputer = SimpleImputer(strategy='mean')
X_imputed = imputer.fit_transform(X)

参数说明:

  • strategy='mean' :使用均值填充。
  • 其他策略包括 'median' , 'most_frequent' , 'constant'

3.2.2 异常值识别与处理方法

异常值检测方法

常用的方法包括:

  • Z-Score 法 :判断某点是否偏离均值超过3个标准差。
  • IQR 法 :基于四分位数间距,超出1.5倍IQR为异常。

示例:使用 IQR 方法识别异常值

Q1 = df.quantile(0.25)
Q3 = df.quantile(0.75)
IQR = Q3 - Q1

# 判断是否为异常值
outliers = (df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))
print(outliers)
异常值处理方式
  • 删除记录 :若异常值比例小,可直接删除。
  • 截尾处理 :设定上下限。
  • 替换为缺失值再填充
  • 使用鲁棒模型(如随机森林)

3.3 数据标准化与归一化

特征的尺度差异会显著影响模型性能,尤其是K近邻、SVM、逻辑回归等对距离敏感的算法。

3.3.1 标准化(Z-Score)与归一化(Min-Max)原理

方法 公式 适用场景
Z-Score $ x’ = \frac{x - \mu}{\sigma} $ 正态分布、离群值多
Min-Max $ x’ = \frac{x - x_{min}}{x_{max} - x_{min}} $ 范围明确、无离群值

3.3.2 使用Scikit-Learn实现标准化与归一化

标准化:StandardScaler
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
归一化:MinMaxScaler
from sklearn.preprocessing import MinMaxScaler

minmax_scaler = MinMaxScaler()
X_normalized = minmax_scaler.fit_transform(X)

流程图展示数据预处理过程:

graph TD
    A[原始数据] --> B{是否存在缺失值?}
    B -->|是| C[填充缺失值]
    B -->|否| D[继续]
    D --> E{是否存在异常值?}
    E -->|是| F[处理异常值]
    E -->|否| G[继续]
    G --> H{是否需要标准化?}
    H -->|是| I[StandardScaler/MinMaxScaler]
    H -->|否| J[完成预处理]

3.4 类别特征编码

机器学习模型通常无法直接处理字符串类型的类别特征,需要将其转换为数值形式。

3.4.1 One-Hot编码与Label编码

LabelEncoder(适用于目标变量)
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
y_encoded = le.fit_transform(["cat", "dog", "cat", "bird"])

输出为 [0, 1, 0, 2] ,适用于目标变量。

One-Hot 编码(适用于特征变量)
from sklearn.preprocessing import OneHotEncoder

encoder = OneHotEncoder()
X = [["red"], ["blue"], ["green"], ["red"]]
X_encoded = encoder.fit_transform(X).toarray()

输出为:

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [1. 0. 0.]]

One-Hot 编码流程图:

graph LR
    A[原始类别特征] --> B[OneHotEncoder]
    B --> C[独热编码向量]
    C --> D[输入模型训练]

3.4.2 Ordinal特征的处理方式

对于具有顺序关系的类别变量(如“低”、“中”、“高”),可以使用 OrdinalEncoder

from sklearn.preprocessing import OrdinalEncoder

enc = OrdinalEncoder(categories=[["low", "medium", "high"]])
X = [["medium"], ["low"], ["high"]]
X_encoded = enc.fit_transform(X)

输出为:

[[1.]
 [0.]
 [2.]]

适用场景总结表:

编码方式 输入数据类型 是否保留顺序 适用模型类型
LabelEncoder 目标变量 分类任务目标变量
OneHotEncoder 特征变量 所有模型
OrdinalEncoder 特征变量(有序) 决策树类模型等

本章通过深入解析 Scikit-Learn 的核心模块和数据预处理流程,为后续的模型构建与调优打下了坚实的基础。下一章节我们将深入探讨常见机器学习模型的实现与调优方法,进一步提升模型性能。

4. 常见机器学习模型的实现与调优

机器学习模型是整个学习过程的核心。本章将深入探讨几种最常见的机器学习模型,包括线性回归、逻辑回归、决策树以及随机森林,分别从理论原理、实现方法、调优技巧和实际应用四个方面展开分析。通过本章的学习,你将掌握如何使用 Scikit-Learn 构建这些模型,并学会在实际项目中进行调优以提升模型性能。

4.1 线性回归模型与实现

线性回归是最基础的监督学习模型之一,广泛应用于回归任务中。其核心思想是通过线性关系对输入特征与目标变量之间的关系进行建模。

4.1.1 线性回归基本原理与损失函数

线性回归模型的基本形式如下:

y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \cdots + \beta_n x_n + \epsilon

其中:
- $ y $:目标变量(输出)
- $ x_i $:第 $ i $ 个特征
- $ \beta_0 $:截距项
- $ \beta_i $:第 $ i $ 个特征的权重系数
- $ \epsilon $:误差项

损失函数通常采用 最小二乘法 (Ordinary Least Squares, OLS):

L(\beta) = \sum_{i=1}^{m}(y_i - \hat{y}_i)^2

目标是找到使损失函数最小的 $ \beta $ 值。

4.1.2 使用Scikit-Learn实现线性回归并评估

下面我们将使用 Scikit-Learn 来实现一个简单的线性回归模型,并使用波士顿房价数据集进行演示。

from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
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)

# 构建模型
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"Mean Squared Error: {mse}")
print(f"R^2 Score: {r2}")

逐行代码解读与参数说明:

  1. load_boston() :加载波士顿房价数据集。
  2. train_test_split() :将数据集划分为训练集和测试集, test_size=0.2 表示测试集占总样本的 20%, random_state=42 用于保证结果可复现。
  3. LinearRegression() :实例化线性回归模型。
  4. fit() :在训练集上训练模型。
  5. predict() :使用训练好的模型在测试集上进行预测。
  6. mean_squared_error() :计算均方误差(MSE)。
  7. r2_score() :计算决定系数 $ R^2 $,衡量模型解释能力。

评估结果分析:

输出示例:

Mean Squared Error: 24.89
R^2 Score: 0.67
  • MSE 越小越好,表示预测值与真实值之间的平均平方误差。
  • $ R^2 $ 接近 1 表示模型解释能力强,0.67 表示模型解释了约 67% 的方差。

4.2 逻辑回归模型与分类任务

逻辑回归虽然名称中带有“回归”,但其本质上是一个 分类模型 ,尤其适用于二分类问题。

4.2.1 Sigmoid函数与分类边界

逻辑回归通过 Sigmoid 函数 将线性输出映射到 [0, 1] 区间,表示属于某一类的概率:

\sigma(z) = \frac{1}{1 + e^{-z}}

其中 $ z = \beta_0 + \beta_1 x_1 + \cdots + \beta_n x_n $

当 $ \sigma(z) \geq 0.5 $ 时,预测为类别 1;否则为类别 0。

4.2.2 模型训练与分类性能评估

我们使用 Scikit-Learn 的乳腺癌数据集进行二分类演示。

from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

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

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

# 训练模型
model = LogisticRegression(max_iter=10000)
model.fit(X_train, y_train)

# 预测与评估
y_pred = model.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"Accuracy: {acc:.4f}")
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))

代码说明:

  • max_iter=10000 :增加最大迭代次数以确保模型收敛。
  • accuracy_score :计算准确率。
  • classification_report :输出精确率、召回率、F1值等指标。
  • confusion_matrix :输出混淆矩阵。

输出示例:

Accuracy: 0.97
              precision    recall  f1-score   support

           0       0.97      0.96      0.97        44
           1       0.97      0.98      0.98        68

    accuracy                           0.97       112
   macro avg       0.97      0.97      0.97       112
weighted avg       0.97      0.97      0.97       112

[[42  2]
 [ 1 67]]

分析:

  • 准确率达到 97%,说明模型在测试集上表现良好。
  • 混淆矩阵显示:预测错误的样本仅 3 个(2 个误判为 0,1 个误判为 1)。

4.3 决策树模型构建与可视化

决策树是一种非参数的监督学习方法,能够用于分类和回归任务。它通过树状结构对数据进行划分,具有可解释性强的优点。

4.3.1 信息增益与树的分裂策略

决策树通过 信息增益 (Information Gain)来选择最佳特征进行分裂。信息增益越大,说明该特征对分类的贡献越高。

公式(以ID3算法为例):

IG(S, A) = Entropy(S) - \sum_{v \in Values(A)} \frac{|S_v|}{|S|} Entropy(S_v)

其中:
- $ Entropy(S) $:当前数据集的熵
- $ S_v $:特征 A 取值为 v 的子集

4.3.2 使用Graphviz可视化决策树

我们可以使用 Scikit-Learn 和 Graphviz 可视化决策树。

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, export_graphviz
import graphviz

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

# 构建模型
clf = DecisionTreeClassifier(max_depth=3)
clf.fit(X, y)

# 导出DOT格式
dot_data = export_graphviz(clf, out_file=None, 
                           feature_names=iris.feature_names,
                           class_names=iris.target_names,
                           filled=True, rounded=True,
                           special_characters=True)

# 使用Graphviz渲染
graph = graphviz.Source(dot_data)
graph.view()

代码说明:

  • export_graphviz :将决策树导出为 DOT 格式。
  • graphviz.Source :读取 DOT 数据并生成图形。
  • graph.view() :打开 PDF 查看决策树结构。

可视化结果说明:

生成的树结构将展示每个节点的分裂特征、阈值、样本数量、类别分布等信息。例如,第一个节点按 petal width (cm) <= 0.8 分裂。

4.4 随机森林模型与集成学习

随机森林是一种典型的 集成学习 方法,通过构建多个决策树并投票来提升模型的泛化能力。

4.4.1 Bagging与随机森林的基本思想

随机森林基于 Bagging (Bootstrap Aggregating) 方法构建多个弱学习器(决策树),并通过投票机制综合预测结果。

核心步骤:

  1. 从原始数据集中进行有放回抽样(Bootstrap)生成多个子样本集。
  2. 对每个子样本集训练一个决策树。
  3. 每棵树对样本进行预测,最终结果由所有树的结果投票(分类)或平均(回归)决定。

4.4.2 参数调优与特征重要性分析

我们以乳腺癌数据集为例,使用随机森林进行分类并分析特征重要性。

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import pandas as pd

# 加载数据
data = load_breast_cancer()
X, y = data.data, data.target
df = pd.DataFrame(X, columns=data.feature_names)

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

# 构建模型
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

# 预测与评估
y_pred = rf.predict(X_test)
print(classification_report(y_test, y_pred))

# 特征重要性
importances = rf.feature_importances_
feat_df = pd.DataFrame({'Feature': data.feature_names, 'Importance': importances})
feat_df.sort_values(by='Importance', ascending=False, inplace=True)
print(feat_df.head(10))

输出示例:

              precision    recall  f1-score   support

           0       0.97      0.98      0.97        44
           1       0.98      0.97      0.98        68

    accuracy                           0.97       112
   macro avg       0.98      0.97      0.98       112
weighted avg       0.98      0.97      0.98       112

           Feature  Importance
22  worst concave points    0.113818
20         worst concavity    0.092355
23      worst symmetry     0.074915
24  worst fractal dimension 0.063287
2   worst radius          0.061328

分析:

  • 模型准确率高达 97%,性能优于单一决策树。
  • worst concave points 是最重要的特征,表示凹陷点的最大值对分类影响最大。
  • 特征重要性分析可用于特征选择和模型解释。

总结

本章系统地讲解了四种常见机器学习模型:线性回归、逻辑回归、决策树和随机森林。通过理论讲解与代码实现相结合,我们不仅理解了每个模型的数学原理,还掌握了在 Scikit-Learn 中的具体实现方式。此外,我们还介绍了模型评估方法、参数调优技巧以及特征重要性分析,帮助你在实际项目中更好地应用这些模型。

在下一章中,我们将深入探讨模型评估与调优技术,包括交叉验证、超参数搜索等进阶内容,进一步提升模型的泛化能力和工程化能力。

5. 模型评估与调优技术

在机器学习项目中,模型训练完成后,如何评估其性能、如何进行参数调优,是决定模型是否具有实用价值的关键环节。本章将系统性地介绍模型评估指标、交叉验证技术以及超参数调优方法,并通过实际代码演示和图表说明,帮助读者掌握如何科学地评估与优化模型。

5.1 模型评估指标

模型评估是衡量模型性能的重要步骤。不同的任务类型(如分类和回归)需要不同的评估指标。本节将详细介绍分类任务与回归任务中的常用评估指标,并通过代码示例展示其在 Scikit-Learn 中的具体实现。

5.1.1 分类任务的评估指标(准确率、精确率、召回率、F1值)

分类任务中常见的评估指标包括:

指标 公式 说明
准确率(Accuracy) (TP + TN) / (TP + TN + FP + FN) 表示预测正确的样本比例
精确率(Precision) TP / (TP + FP) 表示预测为正类中实际为正类的比例
召回率(Recall) TP / (TP + FN) 表示所有真实正类中被正确识别的比例
F1值(F1-Score) 2 * (Precision * Recall) / (Precision + Recall) 精确率与召回率的调和平均数

说明:
- TP:真正例(True Positive)
- TN:真反例(True Negative)
- FP:假正例(False Positive)
- FN:假反例(False Negative)

示例代码:使用 Scikit-Learn 计算分类指标
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# 生成模拟二分类数据
X, y = make_classification(n_samples=1000, n_features=4, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 模型训练
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# 指标计算
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)

print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1 Score: {f1:.4f}")
代码逐行解读:
  • 第1行:导入所需的评估指标模块。
  • 第2-4行:生成模拟数据并划分训练集与测试集。
  • 第6-7行:使用逻辑回归模型进行训练。
  • 第9-13行:分别计算准确率、精确率、召回率和 F1 值。
  • 第15-18行:输出结果。
指标适用场景分析:
  • 准确率 适用于类别平衡的场景,但在类别不平衡时容易误导。
  • 精确率与召回率 在医疗、金融等对误报敏感的领域尤为重要。
  • F1值 综合考虑了精确率和召回率,在类别不平衡时是更优的评估标准。

5.1.2 回归任务的评估指标(MSE、MAE、R²)

回归任务中常用的评估指标如下:

指标 公式 说明
均方误差(MSE) (1/n) * Σ(y_true - y_pred)^2 对大误差惩罚更大
平均绝对误差(MAE) (1/n) * Σ y_true - y_pred
决定系数 R² 1 - Σ(y_true - y_pred)^2 / Σ(y_true - ȳ)^2 表示模型解释数据变异的比例
示例代码:计算回归指标
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression

# 生成模拟回归数据
X, y = make_regression(n_samples=1000, n_features=4, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, 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)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"MSE: {mse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"R²: {r2:.4f}")
代码逐行解读:
  • 第1行:导入评估指标函数。
  • 第2-4行:生成模拟回归数据并划分训练集与测试集。
  • 第6-7行:线性回归模型训练与预测。
  • 第9-13行:分别计算 MSE、MAE 和 R²。
  • 第15-18行:输出评估结果。
指标适用场景分析:
  • MSE 适用于对误差平方敏感的场景,例如金融预测。
  • MAE 适用于对异常值不敏感的场景。
  • 用于衡量模型解释变量的变异程度,越接近 1 表示模型拟合越好。

5.2 交叉验证技术

交叉验证是评估模型泛化性能的重要方法,它能更准确地估计模型在未知数据上的表现。本节将介绍 K 折交叉验证、分层交叉验证与时间序列交叉验证。

5.2.1 K 折交叉验证的原理与实现

K 折交叉验证(K-Fold Cross Validation)是一种将数据划分为 K 个子集(Fold)并依次使用其中 1 个作为验证集、其余作为训练集的评估方法。

流程图说明(mermaid 格式):
graph TD
    A[原始数据集] --> B[划分为 K 个子集]
    B --> C[循环 K 次]
    C --> D[第 i 次: 子集 i 为验证集]
    D --> E[其余 K-1 个子集合并为训练集]
    E --> F[训练模型并验证]
    F --> G[计算平均性能]
示例代码:K 折交叉验证
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

# 生成模拟数据
X, y = make_classification(n_samples=1000, n_features=4, random_state=42)

# 模型定义
model = LogisticRegression()

# K 折交叉验证(K=5)
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')

print(f"交叉验证准确率: {scores}")
print(f"平均准确率: {scores.mean():.4f}")
代码逐行解读:
  • 第1行:导入 cross_val_score
  • 第2-3行:生成分类数据。
  • 第5行:定义逻辑回归模型。
  • 第7行:使用 5 折交叉验证评估模型准确率。
  • 第9-10行:输出每次验证结果与平均值。
优点与适用场景:
  • 优点:充分利用数据,降低模型评估的方差。
  • 适用:数据量较小的场景。

5.2.2 分层交叉验证与时间序列交叉验证

分层交叉验证(Stratified K-Fold)

适用于类别不平衡的数据集,保证每个子集中类别分布与整体一致。

from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=1000, n_features=4, n_informative=2, n_classes=2, random_state=42)
model = LogisticRegression()
skf = StratifiedKFold(n_splits=5)

scores = cross_val_score(model, X, y, cv=skf, scoring='accuracy')
print(f"分层交叉验证准确率: {scores.mean():.4f}")
时间序列交叉验证(TimeSeriesSplit)

适用于具有时间顺序的数据,如股票预测、用户行为分析等。

from sklearn.model_selection import TimeSeriesSplit
from sklearn.linear_model import LinearRegression
import numpy as np

# 模拟时间序列数据
X = np.sort(5 * np.random.rand(100, 1), axis=0)
y = np.sin(X).ravel() + np.random.normal(0, 0.1, X.shape[0])

tscv = TimeSeriesSplit(n_splits=5)
model = LinearRegression()
scores = []

for train_index, test_index in tscv.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    model.fit(X_train, y_train)
    score = model.score(X_test, y_test)
    scores.append(score)

print(f"时间序列交叉验证 R²: {np.mean(scores):.4f}")

5.3 超参数调优方法

超参数是模型训练前需要设定的参数,如学习率、树的深度等。本节将介绍网格搜索和随机搜索,并通过 Scikit-Learn 实现自动化调参。

5.3.1 网格搜索(Grid Search)与随机搜索(Random Search)

方法 特点 适用场景
网格搜索 遍历所有参数组合,精确但计算开销大 参数空间较小
随机搜索 随机选择参数组合,效率高但可能遗漏最优解 参数空间较大
示例代码:网格搜索
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

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

# 定义模型
model = RandomForestClassifier(random_state=42)

# 参数空间
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20],
    'min_samples_split': [2, 5]
}

# 网格搜索
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid_search.fit(X, y)

# 输出最优参数与得分
print("最优参数:", grid_search.best_params_)
print("最优得分:", grid_search.best_score_)
示例代码:随机搜索
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

data = load_iris()
X, y = data.data, data.target

model = RandomForestClassifier(random_state=42)

param_dist = {
    'n_estimators': randint(50, 300),
    'max_depth': [None, 10, 20, 30],
    'min_samples_split': uniform(0.1, 0.9)
}

random_search = RandomizedSearchCV(model, param_dist, n_iter=30, cv=5, scoring='accuracy', n_jobs=-1, random_state=42)
random_search.fit(X, y)

print("最优参数:", random_search.best_params_)
print("最优得分:", random_search.best_score_)

5.3.2 使用 Scikit-Learn 进行自动化调参

自动化调参可以结合交叉验证与超参数搜索方法,提高模型调优效率。

示例:结合交叉验证与网格搜索进行调参
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
model = SVC()

param_grid = {
    'C': [0.1, 1, 10],
    'gamma': ['scale', 'auto', 0.1, 1]
}

grid = GridSearchCV(model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X, y)

print("最优参数:", grid.best_params_)
print("最优准确率:", grid.best_score_)
调参技巧:
  • 先粗调后细调 :先大范围搜索,再聚焦局部最优。
  • 并行计算 :设置 n_jobs=-1 可充分利用多核 CPU。
  • 关注模型稳定性 :多次运行观察得分波动。

本章从模型评估指标入手,深入探讨了分类与回归任务中的核心评估方法,并通过交叉验证技术提升模型泛化能力。最后,介绍了网格搜索与随机搜索两种主流的超参数调优方法,并通过代码实例展示了如何在 Scikit-Learn 中实现自动化调参。这些技术是构建高性能机器学习系统的基石。

6. 模型部署与项目实战

6.1 模型保存与加载

在机器学习项目中,模型训练完成后,通常需要将其保存下来,以便在生产环境中重复使用或进行部署。Python 提供了多种方式用于模型的序列化与反序列化,其中最常用的是 joblib pickle

6.1.1 使用 Joblib 与 Pickle 进行模型序列化

joblib 是 Scikit-Learn 自带的模块,相比 pickle 更适合处理包含大量 NumPy 数组的对象,尤其在保存大型模型时效率更高。

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
import joblib

# 加载数据集
X, y = load_iris(return_X_y=True)
model = LogisticRegression(max_iter=200)
model.fit(X, y)

# 使用 joblib 保存模型
joblib.dump(model, 'logistic_regression_model.pkl')

# 使用 pickle 保存模型
import pickle
with open('logistic_regression_model.pkl', 'wb') as f:
    pickle.dump(model, f)

代码解释
- joblib.dump() :将模型对象保存为 .pkl 文件。
- pickle.dump() :通过文件流方式将模型写入磁盘。

6.1.2 加载模型并进行预测

模型保存后,可以在其他脚本或服务中加载并进行预测。

# 使用 joblib 加载模型
loaded_model = joblib.load('logistic_regression_model.pkl')

# 使用 pickle 加载模型
with open('logistic_regression_model.pkl', 'rb') as f:
    loaded_model = pickle.load(f)

# 进行预测
import numpy as np
test_sample = np.array([[5.1, 3.5, 1.4, 0.2]])
prediction = loaded_model.predict(test_sample)
print("预测类别:", prediction)

参数说明
- test_sample :输入特征向量,格式应与训练数据一致。
- predict() :返回预测的类别标签。

6.2 构建端到端机器学习项目流程

一个完整的机器学习项目通常包括以下几个阶段:数据获取、数据预处理、特征工程、模型训练与评估、模型部署。

6.2.1 数据获取与预处理阶段

数据获取可以通过数据库查询、API 接口、文件读取等方式完成。以 Pandas 为例,读取 CSV 文件并进行缺失值处理:

import pandas as pd
df = pd.read_csv('data.csv')
df.dropna(inplace=True)  # 删除缺失值行

6.2.2 特征工程与模型选择

特征工程包括标准化、编码、特征选择等步骤。以 Scikit-Learn 为例:

from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer

numeric_features = ['age', 'income']
categorical_features = ['gender', 'occupation']

preprocessor = ColumnTransformer(
    transformers=[
        ('num', StandardScaler(), numeric_features),
        ('cat', OneHotEncoder(), categorical_features)])

X_processed = preprocessor.fit_transform(df)

6.2.3 模型训练、评估与部署

训练模型并评估性能:

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

X_train, X_test, y_train, y_test = train_test_split(X_processed, y, test_size=0.2)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("准确率:", accuracy_score(y_test, y_pred))

最后,将模型保存并部署到生产环境(如 Flask API、Docker 容器等)。

6.3 实战案例:客户流失预测系统

6.3.1 项目背景与目标设定

客户流失(Churn)是指用户停止使用产品或服务的行为。在电信行业、互联网平台等场景中,流失预测系统可以帮助企业提前识别潜在流失客户,从而采取干预措施。

目标 :基于客户历史行为数据,构建分类模型预测客户是否会流失。

6.3.2 数据分析与特征工程

使用 Telco 客户流失数据集(可从 Kaggle 获取),加载并进行特征工程:

import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer

df = pd.read_csv('telco_churn.csv')
df['TotalCharges'] = pd.to_numeric(df['TotalCharges'], errors='coerce')
df.fillna(df['TotalCharges'].median(), inplace=True)

# 特征选择
X = df.drop('Churn', axis=1)
y = df['Churn'].map({'Yes': 1, 'No': 0})

numeric_features = X.select_dtypes(include=['int64', 'float64']).columns
categorical_features = X.select_dtypes(include=['object']).columns

numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())])

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))])

preprocessor = ColumnTransformer(
    transformers=[('num', numeric_transformer, numeric_features),
                  ('cat', categorical_transformer, categorical_features)])

6.3.3 模型训练与评估部署

构建完整流水线并训练模型:

from sklearn.ensemble import RandomForestClassifier

model = Pipeline(steps=[('preprocessor', preprocessor),
                        ('classifier', RandomForestClassifier())])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("F1 Score:", f1_score(y_test, y_pred))

模型训练完成后,使用 joblib 保存模型并部署到 Web 服务中(如 Flask)。

6.3.4 结果分析与业务建议

通过模型预测结果,企业可以:

  • 对高流失风险客户进行定向营销或提供优惠。
  • 分析特征重要性(通过 model.named_steps['classifier'].feature_importances_ )找出影响流失的关键因素。
  • 优化客户生命周期管理策略,提升留存率。

mermaid 流程图

graph TD
A[数据采集] --> B[数据清洗]
B --> C[特征工程]
C --> D[模型训练]
D --> E[模型评估]
E --> F[模型部署]
F --> G[结果反馈]

表格:模型评估指标对比

模型类型 准确率 精确率 召回率 F1 值
逻辑回归 0.81 0.78 0.72 0.75
随机森林 0.85 0.83 0.80 0.81
XGBoost 0.86 0.84 0.82 0.83

下一章我们将深入探讨机器学习模型在生产环境中的服务化部署与监控机制。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:机器学习是人工智能的重要分支,Python凭借其简洁高效的语法和丰富的库(如Scikit-Learn)成为实现机器学习任务的首选语言。本资料包“machinelearninginaction”包含大量Python代码实例,覆盖监督学习、无监督学习及半监督学习的核心算法,帮助学习者通过实践掌握数据预处理、模型构建、评估优化和部署全流程。适合初学者入门及开发者进阶,理论结合实践,提升机器学习编程与数据分析能力。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐