系列文章目录
文章目录
一、RNN
1.1、核心特点
处理序列数据: RNN最大的特点是引入时间维度,通过循环结构保留前序输入的信息,能够处理长度可变的序列数据,比如文件,语音,时间序列等
记忆性:网络中包含隐藏状态,用于存储历史信息,理论上能够捕捉长距离依赖关系
变种众多:解决原始RNN长期依赖(梯度消失/爆炸)问题的变种更常用
LSTM-长短期记忆网络:通过门控机制,输入门,遗忘门,输出门,选择性保留或者遗忘信息,适合长序列
GRU-门控循环单元:简化LSTM结构,计算效率高,性能接近LSTM
1.2、主要用处
自然语言处理NLP: 文本生成,机器翻译,情感分析,命名实体识别(比如北京是地名)
时间序列预测:股票价格预测,气象数据预测,设备故障预警
语音处理:语音识别,语音合成
二、CNN
2.1、核心特点
处理网络结构数据:专门为二维图像设计,扩展一维信号,三维视频,通过卷积操作提取局部特征,例如,图像中边缘纹理等局部特征是构成物体的基础,CNN能自动学习这些特征
权值共享与局部感受:
卷积核(过滤器)在图像上滑动时,参数共享,大幅减少计算量
每个神经元仅关注局部区域,符合视觉系统的局部感知特性
池化操作:通过下采样减少特征维度(如最大池化,平均池化),增强平移不变性(如猫的图像平移后仍能被识别)
2.2、示例说明
示例实现了MNIST手写数字识别(0-9的分类),核心部分包括:
-
数据准备:
- 使用MNIST数据集(28x28的灰度手写数字图像)
- 数据转换为张量并标准化
- 可视化展示了一些样本图像
-
CNN模型结构:
- 仅包含1个卷积层(提取图像局部特征)
- 1个池化层(降低特征图尺寸,保留关键信息)
- 1个全连接层(最终分类)
- 这是CNN的最基础结构,体现了"卷积-池化-分类"的核心流程
-
训练过程:
- 使用交叉熵损失函数(适合多分类任务)
- 使用Adam优化器更新参数
- 仅训练3轮,快速演示训练过程
-
模型评估:
- 在测试集上计算准确率(通常能达到97%以上)
- 可视化展示预测结果,对比预测值和实际标签
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import numpy as np
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 设置随机种子,保证结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 1. 数据准备
# 定义数据转换:将图像转换为张量并标准化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # 标准化到[-1, 1]范围
])
# 加载MNIST数据集(手写数字识别数据集)
train_dataset = datasets.MNIST(
root='./data', train=True, download=True, transform=transform
)
test_dataset = datasets.MNIST(
root='./data', train=False, download=True, transform=transform
)
# 创建数据加载器
batch_size = 64
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 可视化一些样本
def show_samples(dataset, num_samples=5):
fig, axes = plt.subplots(1, num_samples, figsize=(10, 2))
for i in range(num_samples):
image, label = dataset[i]
axes[i].imshow(image.squeeze().numpy(), cmap='gray')
axes[i].set_title(f'标签: {label}')
axes[i].axis('off')
plt.show()
print("样本图像:")
show_samples(train_dataset)
# 2. 定义最简单的CNN模型
class SimpleCNN(nn.Module):
def __init__(self):
super().__init__()
# 卷积层:输入1个通道(灰度图),输出16个特征图,卷积核大小3x3
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=1)
# 池化层:2x2最大池化
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 全连接层:将特征映射到10个类别(0-9)
self.fc = nn.Linear(16 * 14 * 14, 10) # 14x14是池化后的尺寸
def forward(self, x):
# 卷积 -> ReLU激活 -> 池化
x = self.pool(torch.relu(self.conv1(x)))
# 展平特征图
x = x.view(-1, 16 * 14 * 14)
# 全连接层输出
x = self.fc(x)
return x
# 初始化模型、损失函数和优化器
model = SimpleCNN()
criterion = nn.CrossEntropyLoss() # 交叉熵损失,适用于分类
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 3. 训练模型
epochs = 3 # 只训练3轮,简单演示
train_losses = []
for epoch in range(epochs):
model.train()
running_loss = 0.0
for images, labels in train_loader:
# 前向传播
outputs = model(images)
loss = criterion(outputs, labels)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
# 计算平均损失
avg_loss = running_loss / len(train_loader)
train_losses.append(avg_loss)
print(f'Epoch {epoch + 1}/{epochs}, 训练损失: {avg_loss:.4f}')
# 绘制训练损失曲线
plt.plot(range(1, epochs + 1), train_losses)
plt.xlabel('Epoch')
plt.ylabel('损失')
plt.title('训练损失变化')
plt.show()
# 4. 评估模型
model.eval()
correct = 0
total = 0
with torch.no_grad(): # 关闭梯度计算
for images, labels in test_loader:
outputs = model(images)
_, predicted = torch.max(outputs.data, 1) # 获取预测类别
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'测试集准确率: {100 * correct / total:.2f}%')
# 5. 可视化预测结果
def show_predictions(loader, model, num_samples=5):
model.eval()
images, labels = next(iter(loader))
with torch.no_grad():
outputs = model(images)
_, predicted = torch.max(outputs, 1)
fig, axes = plt.subplots(1, num_samples, figsize=(10, 2))
for i in range(num_samples):
axes[i].imshow(images[i].squeeze().numpy(), cmap='gray')
axes[i].set_title(f'预测: {predicted[i]}, 实际: {labels[i]}')
axes[i].axis('off')
plt.show()
print("预测结果示例:")
show_predictions(test_loader, model)
2.3、运行后显示
- 5个样本图像及其标签
- 训练过程中的损失变化曲线
- 模型在测试集上的准确率
- 5个测试样本的预测结果
CNN的核心思想:通过卷积操作提取图像的局部特征(如边缘、纹理等),通过池化减少特征维度,最后通过全连接层完成分类。你可以尝试增加卷积层数量或调整卷积核大小,观察对模型性能的影响。
2.4、主要用处
计算机视觉: 图像分类(比如识别猫狗),目标检测(如检测照片中的行人,车辆),图像分割(比如医学影像中分割肿瘤区域),人脸识别
其他领域: 一维CNN可以处理音频信号,二维CNN可以处理雷达数据,三维CNN可以处理视频帧序列
2.5、使用tensorflow测试
PyTorch 和Tensorflow都是功能相近的深度学习框架,提供了从数据处理,模型搭建,训练到部署的全流程支持,都能实现开箱即用的体验,都提供了
张量计算:类似于GPU加速的NumPy
自动微分:自动计算梯度,无需手动推导
丰富的神经网络层
优化器和损失函数
数据加载和预处理工具
下面为你提供一个使用TensorFlow/Keras实现的CNN(卷积神经网络)简单示例,用于MNIST手写数字识别任务。代码简洁且包含详细注释,适合入门学习。
2.5.1、示例
TensorFlow/Keras实现了一个简单的CNN,用于MNIST手写数字识别(0-9分类),主要包含以下部分:
-
数据处理:
- 加载MNIST数据集(28x28像素的灰度手写数字图像)
- 数据归一化(将像素值从0-255转换为0-1)
- 增加通道维度(CNN需要[高度, 宽度, 通道数]格式的输入,灰度图通道数为1)
-
CNN模型结构:
- 1个卷积层(32个3x3卷积核):负责提取图像局部特征(如边缘、线条)
- 1个池化层(2x2最大池化):降低特征图尺寸,保留关键信息,减少计算量
- 1个展平层:将二维特征图转换为一维向量
- 1个全连接层(10个输出):通过softmax激活函数输出0-9的分类概率
-
模型训练与评估:
- 使用Adam优化器和交叉熵损失函数
- 训练3轮(快速演示),使用64的批次大小
- 自动划分10%的训练数据作为验证集,监控过拟合情况
- 在测试集上评估最终性能(通常准确率可达98%以上)
-
可视化:
- 展示样本图像及其标签
- 绘制训练过程中的损失和准确率变化曲线
- 展示测试样本的预测结果与实际标签对比
5. 运行后会自动下载MNIST数据集(首次运行)
- 5个训练样本的图像及标签
- 模型结构摘要
- 训练过程中的损失和准确率变化曲线
- 测试集上的最终准确率
- 5个测试样本的预测结果
# _*_coding : utf-8 _*_
# @Time : 2025/10/6 23:32
# @Author : Leo
# @File : tensorflow_test
# @Project : nn
import tensorflow as tf
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
import numpy as np
# 设置随机种子,保证结果可复现
tf.random.set_seed(42)
np.random.seed(42)
# 1. 加载并预处理数据
# 加载MNIST数据集(手写数字识别数据集)
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 数据预处理:归一化并增加通道维度(灰度图通道数为1)
x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0
x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0
# 可视化一些样本
plt.figure(figsize=(10, 2))
for i in range(5):
plt.subplot(1, 5, i + 1)
plt.imshow(x_train[i].squeeze(), cmap='gray')
plt.title(f'标签: {y_train[i]}')
plt.axis('off')
plt.show()
# 2. 构建最简单的CNN模型
model = models.Sequential([
# 第一个卷积层:32个3x3卷积核,ReLU激活
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
# 池化层:2x2最大池化
layers.MaxPooling2D((2, 2)),
# 展平层:将多维特征转为一维
layers.Flatten(),
# 全连接层:10个输出(对应0-9数字)
layers.Dense(10, activation='softmax')
])
# 打印模型结构
model.summary()
# 3. 编译模型
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy', # 适用于整数标签的多分类
metrics=['accuracy']
)
# 4. 训练模型
history = model.fit(
x_train, y_train,
epochs=3, # 简单演示,训练3轮
batch_size=64,
validation_split=0.1 # 用10%的训练数据作为验证集
)
# 绘制训练曲线
plt.figure(figsize=(12, 4))
# 损失曲线
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='训练损失')
plt.plot(history.history['val_loss'], label='验证损失')
plt.xlabel('Epoch')
plt.ylabel('损失')
plt.legend()
plt.title('损失变化')
# 准确率曲线
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='训练准确率')
plt.plot(history.history['val_accuracy'], label='验证准确率')
plt.xlabel('Epoch')
plt.ylabel('准确率')
plt.legend()
plt.title('准确率变化')
plt.tight_layout()
plt.show()
# 5. 在测试集上评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f'\n测试集准确率: {test_acc:.4f}')
# 6. 可视化预测结果
predictions = model.predict(x_test)
plt.figure(figsize=(10, 2))
for i in range(5):
plt.subplot(1, 5, i + 1)
plt.imshow(x_test[i].squeeze(), cmap='gray')
predicted_label = np.argmax(predictions[i])
actual_label = y_test[i]
plt.title(f'预测: {predicted_label}\n实际: {actual_label}')
plt.axis('off')
plt.tight_layout()
plt.show()
三、其他机器学习算法
3.1、线性回归
特点:最简单的监督学习算法,假设特征与目标值呈线性关系,通过拟合直线(高维空间为超平面)预测连续值
用处:房价预测,销售额预测,气温预测等回归任务
# _*_coding : utf-8 _*_
# @Time : 2025/10/6 20:26
# @Author : Leo
# @File : linear_test
# @Project : nn
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import numpy as np
# 设置随机种子,保证结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 1. 生成模拟数据
# 假设我们的数据符合 y = 3x + 2 + 噪声 这个线性关系
x = torch.linspace(0, 10, 100).unsqueeze(1) # 生成0到10之间的100个点,形状为(100, 1)
noise = torch.randn(100, 1) * 0.5 # 生成噪声
y = 3 * x + 2 + noise # 生成目标值
# 可视化生成的数据
plt.scatter(x.numpy(), y.numpy(), label='数据点')
plt.xlabel('x')
plt.ylabel('y')
plt.title('模拟数据')
plt.legend()
plt.show()
# 2. 定义线性回归模型
class LinearRegressionModel(nn.Module):
def __init__(self):
super().__init__()
# 定义一个线性层:输入维度1,输出维度1
self.linear = nn.Linear(in_features=1, out_features=1)
def forward(self, x):
# 前向传播:直接通过线性层计算
return self.linear(x)
# 初始化模型
model = LinearRegressionModel()
# 3. 定义损失函数和优化器
criterion = nn.MSELoss() # 均方误差损失,适用于回归问题
optimizer = optim.SGD(model.parameters(), lr=0.01) # 随机梯度下降优化器,学习率0.01
# 4. 训练模型
epochs = 1000 # 训练轮次
losses = [] # 记录损失变化
for epoch in range(epochs):
# 前向传播:计算模型预测值
y_pred = model(x)
# 计算损失
loss = criterion(y_pred, y)
losses.append(loss.item())
# 反向传播和参数更新
optimizer.zero_grad() # 清零梯度
loss.backward() # 计算梯度
optimizer.step() # 更新参数
# 每100轮打印一次损失
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}')
# 5. 可视化损失变化
plt.plot(range(epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('训练损失变化')
plt.show()
# 6. 查看训练得到的参数
# 原始公式是 y = 3x + 2,看看我们学到的参数是否接近
print("\n训练得到的参数:")
for name, param in model.named_parameters():
print(f"{name}: {param.item():.4f}")
# 7. 用训练好的模型进行预测并可视化
y_pred = model(x)
plt.scatter(x.numpy(), y.numpy(), label='原始数据')
plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', label='拟合直线')
plt.xlabel('x')
plt.ylabel('y')
plt.title('线性回归拟合结果')
plt.legend()
plt.show()
# 8. 使用模型进行新的预测
new_x = torch.tensor([[5.5], [7.2], [9.8]]) # 新的输入数据
new_y_pred = model(new_x) # 预测结果
print("\n新数据的预测结果:")
for i in range(len(new_x)):
print(f"x = {new_x[i].item()}, 预测y = {new_y_pred[i].item():.4f}")
3.2、逻辑回归
特点:属于分类算法,通过sigmoid函数将线性输出映射到[0,1]区间,用于二分类(如”是/否“, ”垃圾邮件/正常邮件“)
用处:信用评分,疾病诊断,点击率预测
运行后会显示:
原始数据集的散点图
训练和测试损失随迭代的变化曲线
模型在训练集和测试集上的准确率
逻辑回归的决策边界可视化
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# 设置随机种子,保证结果可复现
torch.manual_seed(42)
np.random.seed(42)
# 1. 生成模拟的二分类数据
# 生成100个样本,2个特征,2个类别
X, y = make_classification(
n_samples=100, # 样本数量
n_features=2, # 特征数量
n_informative=2, # 有效特征数量
n_redundant=0, # 冗余特征数量
n_classes=2, # 类别数量
random_state=42
)
# 转换为PyTorch张量
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.float32).unsqueeze(1) # 增加一个维度,使其形状为(100, 1)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 可视化生成的数据
plt.scatter(X[y[:, 0] == 0, 0], X[y[:, 0] == 0, 1], label='类别 0', marker='o')
plt.scatter(X[y[:, 0] == 1, 0], X[y[:, 0] == 1, 1], label='类别 1', marker='x')
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('二分类数据集')
plt.legend()
plt.show()
# 2. 定义逻辑回归模型
class LogisticRegressionModel(nn.Module):
def __init__(self, input_dim):
super().__init__()
# 线性层:输入维度为特征数,输出维度为1(二分类)
self.linear = nn.Linear(input_dim, 1)
# 逻辑回归的sigmoid激活函数会在计算损失时一起使用
def forward(self, x):
# 前向传播:线性变换 + sigmoid激活
return torch.sigmoid(self.linear(x))
# 初始化模型(输入维度为2,因为我们有2个特征)
model = LogisticRegressionModel(input_dim=2)
# 3. 定义损失函数和优化器
criterion = nn.BCELoss() # 二元交叉熵损失,适用于二分类问题
optimizer = optim.SGD(model.parameters(), lr=0.01) # 随机梯度下降优化器
# 4. 训练模型
epochs = 10000 # 训练轮次
train_losses = []
test_losses = []
for epoch in range(epochs):
# 训练模式
model.train()
# 前向传播:计算训练集预测值
y_pred_train = model(X_train)
# 计算训练损失
train_loss = criterion(y_pred_train, y_train)
train_losses.append(train_loss.item())
# 反向传播和参数更新
optimizer.zero_grad() # 清零梯度
train_loss.backward() # 计算梯度
optimizer.step() # 更新参数
# 评估模式
model.eval()
with torch.no_grad(): # 关闭梯度计算
y_pred_test = model(X_test)
test_loss = criterion(y_pred_test, y_test)
test_losses.append(test_loss.item())
# 每1000轮打印一次损失
if (epoch + 1) % 1000 == 0:
print(f'Epoch [{epoch + 1}/{epochs}], 训练损失: {train_loss.item():.4f}, 测试损失: {test_loss.item():.4f}')
# 5. 可视化损失变化
plt.plot(range(epochs), train_losses, label='训练损失')
plt.plot(range(epochs), test_losses, label='测试损失')
plt.xlabel('Epoch')
plt.ylabel('损失')
plt.title('训练和测试损失变化')
plt.legend()
plt.show()
# 6. 评估模型准确率
model.eval()
with torch.no_grad():
# 训练集准确率
y_pred_train = model(X_train)
y_pred_train_class = (y_pred_train > 0.5).float() # 大于0.5预测为1,否则为0
train_acc = (y_pred_train_class == y_train).float().mean()
# 测试集准确率
y_pred_test = model(X_test)
y_pred_test_class = (y_pred_test > 0.5).float()
test_acc = (y_pred_test_class == y_test).float().mean()
print(f'\n训练集准确率: {train_acc.item():.4f}')
print(f'测试集准确率: {test_acc.item():.4f}')
# 7. 可视化决策边界
# 生成网格点用于绘制决策边界
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, 0.02),
np.arange(y_min, y_max, 0.02))
# 预测网格点的类别
with torch.no_grad():
inputs = torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype=torch.float32)
outputs = model(inputs)
predicted = (outputs > 0.5).float()
Z = predicted.reshape(xx.shape)
# 绘制决策边界和数据点
plt.contourf(xx, yy, Z, alpha=0.4, cmap=plt.cm.RdBu)
plt.scatter(X[y[:, 0] == 0, 0], X[y[:, 0] == 0, 1], label='类别 0', marker='o', c='blue')
plt.scatter(X[y[:, 0] == 1, 0], X[y[:, 0] == 1, 1], label='类别 1', marker='x', c='red')
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('逻辑回归决策边界')
plt.legend()
plt.show()
3.3、决策树(Decision Tree)
特点:模拟人类决策过程,通过对特征的 “提问”(如 “年龄是否 > 30?”)逐步划分数据,最终得到分类或回归结果。可解释性强(类似 “流程图”)。
用处:客户流失分析、风险评估、医疗诊断(直观展示决策依据)。
3.1、demo
这个决策树示例使用鸢尾花数据集实现了一个多分类任务,主要包含以下几个部分:
-
数据准备:
- 使用scikit-learn内置的鸢尾花数据集,包含3种鸢尾花的特征数据
- 为了便于可视化,仅使用了前两个特征(花萼长度和花萼宽度)
- 将数据集划分为训练集(70%)和测试集(30%)
-
模型训练:
- 使用
DecisionTreeClassifier创建决策树分类器 - 通过
max_depth=3限制决策树深度,避免过拟合 - 使用训练集训练模型
- 使用
-
模型评估:
- 在测试集上进行预测并计算准确率
- 生成详细的分类报告,包括精确率、召回率和F1分数
-
可视化:
- 展示原始数据集的分布情况
- 可视化决策树的结构,清晰展示每个节点的分裂条件和类别判断
- 绘制决策边界,直观展示模型如何对特征空间进行划分
-
运行后显示:
- 鸢尾花数据集的散点图
- 模型的准确率和详细分类报告
- 决策树的结构可视化
- 决策边界的可视化
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score, classification_report
# 1. 加载数据集(使用经典的鸢尾花数据集)
iris = load_iris()
X = iris.data[:, :2] # 仅使用前两个特征,方便可视化
y = iris.target
# 数据集信息
print(f"特征名称: {iris.feature_names[:2]}")
print(f"类别名称: {iris.target_names}")
print(f"数据集大小: {X.shape[0]}个样本, {X.shape[1]}个特征")
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 可视化数据集
plt.figure(figsize=(8, 6))
colors = ['red', 'green', 'blue']
for i in range(3):
plt.scatter(
X[y == i, 0], X[y == i, 1],
c=colors[i], label=iris.target_names[i]
)
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('鸢尾花数据集可视化')
plt.legend()
plt.show()
# 2. 创建并训练决策树模型
# 初始化决策树分类器,限制最大深度为3,避免过拟合
clf = DecisionTreeClassifier(max_depth=3, random_state=42)
clf.fit(X_train, y_train)
# 3. 模型预测与评估
# 在测试集上进行预测
y_pred = clf.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"\n模型准确率: {accuracy:.4f}")
# 详细分类报告
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# 4. 可视化决策树
plt.figure(figsize=(12, 8))
plot_tree(
clf,
feature_names=iris.feature_names[:2],
class_names=iris.target_names,
filled=True, # 填充颜色
rounded=True, # 圆角矩形
proportion=True # 显示每个节点中各类别的比例
)
plt.title('决策树结构可视化')
plt.show()
# 5. 可视化决策边界
# 创建网格用于绘制决策边界
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, 0.02),
np.arange(y_min, y_max, 0.02))
# 预测网格点的类别
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界和数据点
plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
for i in range(3):
plt.scatter(
X[y == i, 0], X[y == i, 1],
c=colors[i], label=iris.target_names[i]
)
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.title('决策树决策边界')
plt.legend()
plt.show()
3.4、随机森林(Random Forest)
特点:由多个决策树组成的集成算法,通过 “bootstrap 抽样” 和 “随机特征选择” 减少过拟合,预测精度高于单棵决策树。
用处: Kaggle 竞赛常用模型,适用于分类(如疾病风险分类)和回归(如房价预测),也可用于特征重要性评估。
3.4.1、 demo
使用月牙形数据集实现了二分类任务
-
数据准备:
- 使用
make_moons生成非线性可分的月牙形数据集,更能体现随机森林处理复杂模式的能力 - 将数据集划分为训练集(70%)和测试集(30%)
- 可视化展示数据集分布
- 使用
-
模型训练:
- 使用
RandomForestClassifier创建随机森林分类器 - 核心参数:
n_estimators=100(由100棵决策树组成)、max_depth=5(控制单棵树复杂度) - 随机森林通过集成多棵决策树的预测结果(多数投票)来提高性能
- 使用
-
模型评估:
- 计算模型在测试集上的准确率
- 生成详细分类报告(精确率、召回率、F1分数)
- 可视化混淆矩阵,展示分类错误情况
-
特征重要性:
- 随机森林可以自动计算并输出特征重要性得分
- 帮助理解哪些特征对分类决策贡献更大
-
决策边界可视化:
- 展示随机森林学习到的决策边界
- 可以看到随机森林能处理非线性边界,比单棵决策树更稳健
-
运行后会显示:
- 月牙形数据集的分布散点图
- 模型准确率和详细分类报告
- 混淆矩阵热图
- 特征重要性柱状图
- 随机森林的决策边界可视化
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns
# 1. 生成模拟数据集(月牙形数据集,更适合展示随机森林的优势)
X, y = make_moons(n_samples=300, noise=0.2, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 可视化数据集
plt.figure(figsize=(8, 6))
plt.scatter(X[y == 0, 0], X[y == 0, 1], c='blue', label='类别 0', alpha=0.7)
plt.scatter(X[y == 1, 0], X[y == 1, 1], c='red', label='类别 1', alpha=0.7)
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('模拟月牙形数据集')
plt.legend()
plt.show()
# 2. 创建并训练随机森林模型
# 初始化随机森林分类器
# n_estimators: 森林中树的数量
# max_depth: 每棵树的最大深度,控制复杂度
rf = RandomForestClassifier(
n_estimators=100, # 100棵决策树
max_depth=5, # 每棵树最大深度为5
random_state=42 # 随机种子,保证结果可复现
)
# 训练模型
rf.fit(X_train, y_train)
# 3. 模型预测与评估
# 在测试集上进行预测
y_pred = rf.predict(X_test)
y_pred_proba = rf.predict_proba(X_test) # 预测概率
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {accuracy:.4f}")
# 详细分类报告
print("\n分类报告:")
print(classification_report(y_test, y_pred))
# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(6, 4))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['类别 0', '类别 1'],
yticklabels=['类别 0', '类别 1'])
plt.xlabel('预测类别')
plt.ylabel('实际类别')
plt.title('混淆矩阵')
plt.show()
# 4. 可视化特征重要性
feature_importance = rf.feature_importances_
plt.figure(figsize=(6, 4))
plt.bar(['特征 1', '特征 2'], feature_importance)
plt.ylabel('重要性得分')
plt.title('随机森林特征重要性')
plt.show()
# 5. 可视化决策边界
# 创建网格用于绘制决策边界
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
# 预测网格点的类别
Z = rf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界和数据点
plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
plt.scatter(X[y == 0, 0], X[y == 0, 1], c='blue', label='类别 0', alpha=0.7)
plt.scatter(X[y == 1, 0], X[y == 1, 1], c='red', label='类别 1', alpha=0.7)
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title('随机森林决策边界')
plt.legend()
plt.show()
随机森林是一种集成学习算法,通过组合多棵决策树的预测结果来提高性能和稳定性,同时减少过拟合风险。你可以尝试修改n_estimators(树的数量)和max_depth(树的深度)等参数,观察对模型性能的影响。一般来说,增加树的数量可以提高性能(但会增加计算成本),适当限制树的深度可以防止过拟合。
3.5、支持向量机(SVM,Support Vector Machine)
特点:寻找 “最优超平面” 最大化分类间隔,通过核函数(如 RBF 核)处理非线性数据,在小样本场景表现优异。
用处:文本分类、图像识别(早期)、生物信息学(如蛋白质分类)。
3.6、K - 近邻(KNN,K-Nearest Neighbors)
特点:无训练过程的 “惰性学习” 算法,通过计算新样本与训练样本的距离(如欧氏距离),取最近的 K 个样本的多数类别作为预测结果。
用处:推荐系统(如 “相似用户喜欢的商品”)、手写数字识别、异常检测。
3.7、聚类算法(如 K-Means)
特点:无监督学习算法,将相似样本自动归为一类,无需标签数据。K-Means 通过迭代优化聚类中心实现分类。
用处:用户分群(如电商用户画像聚类)、异常检测(远离聚类中心的样本)、图像分割(像素聚类)。
3.8、朴素贝叶斯(Naive Bayes)
特点:基于贝叶斯定理和 “特征条件独立假设” 的分类算法,计算高效,适合高维数据(如文本)。
用处:垃圾邮件过滤(词袋模型 + 贝叶斯)、文本分类(如新闻主题分类)、情感分析。
3.9、算法选择的核心依据
数据类型:
序列数据(文本、语音、时间序列)→ RNN/LSTM/GRU;
网格数据(图像、视频)→ CNN;
结构化数据(表格数据)→ 决策树、随机森林、逻辑回归等。
任务类型:
分类(离散标签)→ 逻辑回归、SVM、随机森林、CNN/RNN;
回归(连续值)→ 线性回归、决策树、随机森林;
无监督学习(无标签)→ 聚类算法、PCA(降维)。
数据规模:
小样本 → SVM、朴素贝叶斯;
大样本 → 深度学习(CNN/RNN)、随机森林。
909

被折叠的 条评论
为什么被折叠?



