《动手学深度学习》第一章笔记机器学习问题到底怎么分类引言从一张图出发翻开《动手学深度学习》第一章最吸引我的不是数学公式而是一张决策流程图——它告诉我拿到一个机器学习任务第一步不是调参而是先搞清“这是什么类型的问题”。如果你能正确分类问题后面的模型选择、评估指标、训练策略会变得清晰很多。作为全栈工程师我习惯用代码来理解概念。这篇文章会从实战出发用 Python 代码一步步演示机器学习问题的常见分类方式并附上可运行的示例。—## 一、机器学习问题的三大分类维度《动手学深度学习》第一章把机器学习问题分为三个层次1.按「有无标签」分监督学习、无监督学习、半监督学习、强化学习2.按「输出类型」分回归、分类二分类/多分类、排序、序列生成等3.按「数据形态」分表格数据、图像、文本、时序等但很多初学者容易混淆“监督 vs 无监督”与“回归 vs 分类”这两个维度。下面我们用代码来理清。—## 二、监督学习回归 vs 分类代码实战### 示例 1回归问题预测房价回归问题的核心是预测一个连续的数值。下面我们用简单的线性回归演示。python# 回归问题示例根据房屋面积预测价格import numpy as npimport matplotlib.pyplot as pltfrom sklearn.linear_model import LinearRegressionfrom sklearn.metrics import mean_squared_error# 生成模拟数据面积平方米与价格万元np.random.seed(42)X np.random.uniform(30, 200, 100).reshape(-1, 1) # 面积true_price 0.8 * X 10 # 真实关系价格 0.8*面积 10noise np.random.normal(0, 15, X.shape) # 添加随机噪声y true_price noise # 观测到的价格# 训练线性回归模型model LinearRegression()model.fit(X, y)# 预测并评估y_pred model.predict(X)mse mean_squared_error(y, y_pred)print(f均方误差 (MSE): {mse:.2f})print(f模型参数斜率{model.coef_[0][0]:.2f}, 截距{model.intercept_[0]:.2f})# 可视化plt.scatter(X, y, alpha0.6, label实际数据)plt.plot(X, model.predict(X), colorred, linewidth2, label拟合线)plt.xlabel(面积平方米)plt.ylabel(价格万元)plt.title(回归问题房价预测)plt.legend()plt.show()关键注释 -y是连续值万元所以这是回归问题。 - 评估指标用 MSE均方误差而不是准确率——因为“偏差一点”比“全错”更合理。### 示例 2二分类问题识别猫或狗分类问题输出离散的类别标签。下面用 k 近邻算法演示二分类。python# 二分类问题示例根据体重和毛发长度判断是猫还是狗import numpy as npfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score, confusion_matrix# 生成模拟数据特征 [体重(kg), 毛长(cm)]标签 0猫, 1狗np.random.seed(42)n_samples 200# 猫体重轻毛发较短cats np.random.multivariate_normal([5, 2], [[1.5, 0.5], [0.5, 1]], n_samples//2)# 狗体重大毛发较长dogs np.random.multivariate_normal([15, 8], [[3, 1], [1, 2]], n_samples//2)X np.vstack([cats, dogs])y np.hstack([np.zeros(n_samples//2), np.ones(n_samples//2)])# 划分训练集和测试集X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42)# 训练 KNN 分类器k5knn KNeighborsClassifier(n_neighbors5)knn.fit(X_train, y_train)# 预测并评估y_pred knn.predict(X_test)acc accuracy_score(y_test, y_pred)cm confusion_matrix(y_test, y_pred)print(f准确率: {acc:.2f})print(f混淆矩阵:\n{cm})# 可视化决策边界仅用于 2D 特征import matplotlib.pyplot as pltx_min, x_max X[:, 0].min() - 1, X[:, 0].max() 1y_min, y_max X[:, 1].min() - 1, X[:, 1].max() 1xx, yy np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1))Z knn.predict(np.c_[xx.ravel(), yy.ravel()])Z Z.reshape(xx.shape)plt.contourf(xx, yy, Z, alpha0.3)plt.scatter(X[:, 0], X[:, 1], cy, cmapcoolwarm, edgecolorsk)plt.xlabel(体重 (kg))plt.ylabel(毛长 (cm))plt.title(分类问题猫狗识别)plt.show()关键注释 -y是离散值 {0, 1}所以这是分类问题。 - 评估用准确率 混淆矩阵比 MSE 更直观。 - KNN 不需要显式训练但推理时需要计算所有距离——这是它慢的原因。—## 三、无监督学习聚类与降维无监督学习没有标签目标是从数据本身发现结构。常见类型| 类型 | 目标 | 典型算法 | 例子 ||------|------|----------|------|| 聚类 | 把相似样本分组 | K-Means, DBSCAN | 用户分群 || 降维 | 压缩特征维度 | PCA, t-SNE | 数据可视化 || 密度估计 | 找出数据分布 | 高斯混合模型 | 异常检测 |### 示例 3用 K-Means 做客户分群python# 无监督学习示例K-Means 聚类客户from sklearn.cluster import KMeansfrom sklearn.preprocessing import StandardScalerimport matplotlib.pyplot as plt# 生成三组客户数据年消费额、月访问次数np.random.seed(42)cluster1 np.random.multivariate_normal([3000, 5], [[500, 0], [0, 1]], 50)cluster2 np.random.multivariate_normal([8000, 20], [[800, 0], [0, 2]], 50)cluster3 np.random.multivariate_normal([15000, 3], [[2000, 0], [0, 0.5]], 50)X np.vstack([cluster1, cluster2, cluster3])# 标准化K-Means 对尺度敏感scaler StandardScaler()X_scaled scaler.fit_transform(X)# 训练 K-Meansk3kmeans KMeans(n_clusters3, random_state42)labels kmeans.fit_predict(X_scaled)# 可视化聚类结果plt.scatter(X[:, 0], X[:, 1], clabels, cmapviridis, edgecolorsk)plt.scatter(kmeans.cluster_centers_[:, 0] * scaler.scale_[0] scaler.mean_[0], kmeans.cluster_centers_[:, 1] * scaler.scale_[1] scaler.mean_[1], s200, cred, markerX, label聚类中心)plt.xlabel(年消费额元)plt.ylabel(月访问次数)plt.title(无监督学习K-Means 客户分群)plt.legend()plt.show()print(f每个聚类的样本数: {np.bincount(labels)})注意无监督学习没有标签所以无法像监督学习那样评估准确率。我们只能通过“轮廓系数”、“肘部法则”等内部指标衡量聚类质量。—## 四、强化学习通过试错学习强化学习既不是监督也不是无监督——它通过智能体与环境交互最大化累积奖励。典型例子是 AlphaGo、机器人控制。下面是一个极简的“多臂老虎机”问题演示简化版强化学习python# 强化学习示例多臂老虎机epsilon-贪婪策略import numpy as npclass Bandit: 模拟一个老虎机每次拉杆返回随机奖励 def __init__(self, true_mean): self.true_mean true_mean # 真实平均奖励 def pull(self): return np.random.normal(self.true_mean, 1)def epsilon_greedy(bandits, n_plays1000, epsilon0.1): epsilon-贪婪算法以 epsilon 概率探索否则利用已知最优 n_bandits len(bandits) Q np.zeros(n_bandits) # 估计的奖励均值 N np.zeros(n_bandits) # 每个老虎机被拉的次数 total_reward 0 for i in range(n_plays): # 探索或利用 if np.random.random() epsilon: action np.random.randint(n_bandits) # 随机探索 else: action np.argmax(Q) # 利用当前最优 reward bandits[action].pull() total_reward reward # 更新估计均值 N[action] 1 Q[action] (reward - Q[action]) / N[action] return Q, total_reward# 创建 5 个老虎机真实均值分别为 [1, 2, 3, 4, 5]bandits [Bandit(m) for m in [1, 2, 3, 4, 5]]Q_estimated, total epsilon_greedy(bandits, n_plays5000, epsilon0.1)print(f估计的奖励均值: {np.round(Q_estimated, 2)})print(f真实奖励均值: [1, 2, 3, 4, 5])print(f总奖励: {total:.0f})关键点- 没有标签数据只有奖励信号。 - 智能体需要在“探索”尝试未知和“利用”选择已知最优之间平衡。 - 这是强化学习和监督学习的本质区别。—## 五、实际工作中如何判断作为全栈工程师在项目中遇到机器学习问题时我通常按照以下顺序判断1. 有没有标签数据 |-- 有 → 监督学习 | |-- 输出是连续值 → 回归 | |-- 输出是离散值 → 分类 | |-- 两类 → 二分类 | |-- 多类 → 多分类 |-- 没有 → 无监督学习 |-- 要分组 → 聚类 |-- 要降维 → 降维 |-- 要检测异常 → 密度估计另外书中还提到了几个容易混淆的场景-排序问题如搜索引擎输出是排序列表属于监督学习的变种。 -生成问题如 GPT输出是序列文本通常用自监督学习。 -迁移学习先无监督预训练再监督微调。—## 六、总结《动手学深度学习》第一章的核心价值不在于算法本身而在于建立“问题分类”的元认知。通过这篇文章的代码示例你应该能更清晰地理解1.监督学习需要标签输出可以是连续值回归或离散值分类。 2.无监督学习没有标签用于发现数据的内在结构聚类、降维。 3.强化学习通过试错学习没有标签但有奖励信号。 4. 实际项目中90% 的经典问题都属于“监督学习”中的回归或分类。最后送你一句话“机器学习不是万能药但如果你能正确分类问题你就已经赢了一半。”下篇笔记我们会深入“模型评估与过拟合”这一实战痛点。