机器学习 6 大范式实战对比:监督/无监督/强化/半监督/自监督/迁移学习代码解析
·
机器学习6大范式代码实战全解析:从理论到落地
1. 机器学习范式全景图
在当今AI技术爆发的时代,理解不同机器学习范式的核心差异已成为开发者必备技能。不同于教科书式的概念罗列,我们将通过6个可运行的代码示例,带您深入每种范式的技术本质。
机器学习范式本质上反映了算法从数据中提取知识的不同方式。就像画家可以用油画、水彩或素描表现同一主题,不同范式对相同问题会给出截然不同的解决方案。选择正确的范式,往往比调参更能决定项目成败。
核心差异矩阵 :
| 范式 | 数据要求 | 典型任务 | 优势 | 挑战 |
|---|---|---|---|---|
| 监督学习 | 标注数据 | 分类/回归 | 预测精准 | 标注成本高 |
| 无监督学习 | 无标注数据 | 聚类/降维 | 发现隐藏模式 | 结果难评估 |
| 强化学习 | 环境交互 | 决策优化 | 长期收益最大化 | 训练不稳定 |
| 半监督学习 | 少量标注+大量未标注 | 分类 | 降低标注依赖 | 未标注数据质量敏感 |
| 自监督学习 | 自动生成标签 | 表征学习 | 无需人工标注 | 任务设计复杂 |
| 迁移学习 | 源领域数据 | 跨领域应用 | 快速适应新场景 | 领域差异影响效果 |
2. 监督学习:精准预测的艺术
监督学习如同有导师指导的学生,每个训练样本都带有明确的"正确答案"。我们以手写数字识别为例,展示如何构建一个实用的分类器。
from sklearn.datasets import load_digits
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载数据
digits = load_digits()
X, y = digits.data, digits.target
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 构建随机森林模型
model = RandomForestClassifier(n_estimators=100, max_depth=10)
model.fit(X_train, y_train)
# 评估性能
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
关键要点 :
- 特征工程决定模型上限:手写数字的像素特征需要标准化处理
- 过拟合是常见陷阱:通过交叉验证选择适当的树深度(max_depth)
- 类别不平衡时需要特殊处理:可采用class_weight参数调整
提示:对于高维稀疏数据(如文本),建议先使用TF-IDF或嵌入技术降维后再应用随机森林
3. 无监督学习:发现数据的内在秩序
当没有标注数据时,无监督学习能揭示数据中隐藏的结构。以下示例展示如何用聚类算法对客户进行分群。
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
# 生成模拟客户数据
X, _ = make_blobs(n_samples=1000, centers=4, cluster_std=1.5, random_state=42)
X = StandardScaler().fit_transform(X)
# 肘部法则确定最佳K值
inertia = []
for k in range(2, 8):
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
inertia.append(kmeans.inertia_)
plt.plot(range(2, 8), inertia, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Inertia')
plt.show()
# 最终聚类
optimal_k = 4
kmeans = KMeans(n_clusters=optimal_k, random_state=42)
clusters = kmeans.fit_predict(X)
# 可视化
plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0],
kmeans.cluster_centers_[:, 1],
s=300, c='red', marker='X')
plt.title('Customer Segmentation')
plt.show()
聚类实战技巧 :
- 数据标准化是必须步骤,避免量纲影响距离计算
- 轮廓系数(silhouette_score)比肘部法则更可靠
- 高维数据建议先使用PCA降维再聚类
4. 强化学习:智能决策的试错之道
强化学习通过与环境交互学习最优策略。以下是一个简化版的Q-learning实现:
import numpy as np
# 定义迷宫环境
class MazeEnv:
def __init__(self):
self.grid = np.array([
[0, 0, 0, 1],
[0, -1, 0, -1],
[0, 0, 0, 0]
])
self.start = (2, 0)
self.goal = (0, 3)
self.current = self.start
def reset(self):
self.current = self.start
return self.current
def step(self, action):
moves = [(0, -1), (0, 1), (-1, 0), (1, 0)] # 上下左右
new_pos = (self.current[0] + moves[action][0],
self.current[1] + moves[action][1])
# 边界检查
if (0 <= new_pos[0] < self.grid.shape[0] and
0 <= new_pos[1] < self.grid.shape[1]):
self.current = new_pos
reward = self.grid[self.current]
done = (self.current == self.goal)
return self.current, reward, done
# Q-learning算法
def q_learning(env, episodes=1000, alpha=0.1, gamma=0.9, epsilon=0.1):
q_table = np.zeros((env.grid.shape[0], env.grid.shape[1], 4))
for _ in range(episodes):
state = env.reset()
done = False
while not done:
# ε-greedy策略
if np.random.random() < epsilon:
action = np.random.randint(4)
else:
action = np.argmax(q_table[state[0], state[1]])
next_state, reward, done = env.step(action)
# Q值更新
old_value = q_table[state[0], state[1], action]
next_max = np.max(q_table[next_state[0], next_state[1]])
new_value = old_value + alpha * (reward + gamma * next_max - old_value)
q_table[state[0], state[1], action] = new_value
state = next_state
return q_table
# 训练并测试
env = MazeEnv()
q_table = q_learning(env)
# 输出最优策略
policy = np.argmax(q_table, axis=2)
print("Optimal policy:")
print(policy)
强化学习关键点 :
- 奖励设计决定学习方向:稀疏奖励问题需特别处理
- 探索与利用的平衡:ε-greedy策略是经典解决方案
- 深度Q网络(DQN)可扩展至复杂环境
5. 半监督学习:有限标注的高效利用
当标注成本高昂时,半监督学习能最大化利用少量标注样本。以下展示标签传播算法:
from sklearn.semi_supervised import LabelPropagation
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score
# 生成数据
X, y = make_classification(n_samples=1000, n_features=20,
n_classes=3, n_informative=8,
random_state=42)
# 仅标记5%的数据
rng = np.random.RandomState(42)
random_unlabeled_points = rng.rand(len(y)) < 0.95
y_train = np.copy(y)
y_train[random_unlabeled_points] = -1 # 未标记样本设为-1
# 标签传播
label_prop_model = LabelPropagation(kernel='knn', n_neighbors=10)
label_prop_model.fit(X, y_train)
# 评估
y_pred = label_prop_model.predict(X)
print(f"Accuracy: {accuracy_score(y, y_pred):.2f}")
# 与纯监督学习对比
from sklearn.ensemble import RandomForestClassifier
# 仅使用已标注数据
labeled_idx = np.where(y_train != -1)[0]
supervised_model = RandomForestClassifier()
supervised_model.fit(X[labeled_idx], y[labeled_idx])
y_pred_sup = supervised_model.predict(X)
print(f"Supervised only accuracy: {accuracy_score(y, y_pred_sup):.2f}")
半监督实践建议 :
- 确保未标注数据与标注数据同分布
- 图半监督方法(label propagation)适合低维稠密数据
- 深度学习中的伪标签(Pseudo-labeling)效果显著
6. 自监督学习:创造监督信号的艺术
自监督学习通过设计前置任务让模型学习通用表征。以下是一个简单的图像旋转预测示例:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms, datasets
from torch.utils.data import DataLoader
# 自定义旋转数据集
class RotatedDataset(torch.utils.data.Dataset):
def __init__(self, dataset):
self.dataset = dataset
self.rotations = [0, 90, 180, 270]
def __len__(self):
return len(self.dataset) * len(self.rotations)
def __getitem__(self, idx):
img_idx = idx // len(self.rotations)
rot_idx = idx % len(self.rotations)
img, _ = self.dataset[img_idx]
rotation = self.rotations[rot_idx]
# 应用旋转
rotated_img = transforms.functional.rotate(img, rotation)
return rotated_img, rot_idx
# 加载MNIST
transform = transforms.Compose([
transforms.Grayscale(num_output_channels=3), # 适配预训练模型
transforms.Resize(32),
transforms.ToTensor()
])
mnist_train = datasets.MNIST('./data', train=True, download=True, transform=transform)
rotated_train = RotatedDataset(mnist_train)
# 构建自监督模型
class RotationPredictor(nn.Module):
def __init__(self, backbone):
super().__init__()
self.backbone = backbone
self.fc = nn.Linear(512, 4) # 预测4种旋转角度
def forward(self, x):
features = self.backbone(x)
return self.fc(features)
# 使用预训练ResNet18的特征提取器
backbone = torch.hub.load('pytorch/vision', 'resnet18', pretrained=True)
backbone = nn.Sequential(*list(backbone.children())[:-1]) # 移除最后一层
model = RotationPredictor(backbone)
# 训练设置
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
train_loader = DataLoader(rotated_train, batch_size=64, shuffle=True)
# 训练循环
for epoch in range(5):
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
自监督技巧 :
- 前置任务应与下游任务相关(如旋转预测适用于图像分类)
- 对比学习(SimCLR, MoCo)当前效果最佳
- 大batch size对对比学习至关重要
7. 迁移学习:知识复用的智慧
迁移学习将源领域知识应用于目标领域,极大降低数据需求。以下展示NLP中的迁移学习:
from transformers import BertTokenizer, BertForSequenceClassification
from transformers import Trainer, TrainingArguments
import torch
from datasets import load_dataset
# 加载情感分析数据集
dataset = load_dataset('imdb')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 数据预处理
def tokenize_function(examples):
return tokenizer(examples['text'], padding='max_length', truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
tokenized_datasets = tokenized_datasets.rename_column('label', 'labels')
tokenized_datasets.set_format('torch', columns=['input_ids', 'attention_mask', 'labels'])
# 加载预训练模型
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 训练参数
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=1,
per_device_train_batch_size=8,
save_steps=10_000,
save_total_limit=2,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets['train'].select(range(1000)), # 小样本
eval_dataset=tokenized_datasets['test'].select(range(100)),
)
# 微调
trainer.train()
# 评估
eval_result = trainer.evaluate()
print(f"Evaluation accuracy: {eval_result['eval_accuracy']:.2f}")
迁移学习最佳实践 :
- 领域适配(Domain Adaptation)可缓解领域差异
- 特征提取器冻结与微调需平衡
- 提示学习(Prompt Learning)是NLP新范式
8. 范式融合与前沿趋势
实际项目中,我们常组合多种范式。例如:
- 自监督预训练+监督微调
- 强化学习+迁移学习(如AlphaGo)
- 半监督+主动学习
2024年值得关注的方向 :
- 大语言模型中的指令微调
- 多模态自监督学习
- 基于扩散模型的生成式AI
- 强化学习与物理世界的交互
每种范式都有其独特的优势和适用场景,关键在于理解它们的数学本质而非简单调用API。在实际项目中,我常发现数据特性决定了范式选择——标注数据的可获得性、问题的奖励结构、计算资源限制等都是关键考量因素。
更多推荐

所有评论(0)