谁看我谁 狼家二丫2026-07-28 10:17
机器学习漫游(1) 基本设定
引言:从零开始理解机器学习你是否好奇过,为什么你的手机相册能自动识别出"猫"和"狗"?为什么购物网站能猜中你下一步想买什么?这些背后都依赖一种强大的技术------机器学习。简单来说,机器学习就是让计算机从数据中"学习"规律,而不是由程序员一步步书写明确的规则。就像一个孩子通过看大量猫的图片,慢慢学会区分猫和狗一样,机器通过分析数据,自动发现模式。在这第一篇文章中,我们将打好机器学习的基础:理解它的核心设定、基本概念,并通过两个具体的Python代码示例,让你亲手体验"学习"的过程。我们将从最简单的"监督学习"开始,然后过渡到更抽象的"特征工程"概念。## 什么是机器学习的基本设定?任何机器学习任务,都离不开三个核心要素:1. 数据 :这是学习的原材料。例如,房价预测需要过去房屋的面积、卧室数量、价格等数据。2. 模型 :这是学习的"大脑",一个数学函数或结构,负责从输入(如面积)到输出(如价格)的映射。3. 学习算法 :这是学习的方法,通过调整模型内部的参数,让模型的预测越来越准确。在"监督学习"中,数据包含"输入特征"和"正确答案"(标签)。模型的目标是学习一个函数,使得给定输入,输出尽可能接近正确答案。这就像学生做完习题后对照答案订正一样。## 第一个示例:线性回归的"学习"让我们用一个最经典的例子来感受这个设定:线性回归 。假设我们想预测一个城市的冰淇淋销量与温度的关系。我们有过去几天的数据:温度(摄氏度)和对应的销量(杯)。我们定义模型为一条直线:销量 = 斜率 * 温度 + 截距。学习算法就是通过数据,自动找到最佳的"斜率"和"截距"。python# 导入必要的库import numpy as npimport matplotlib.pyplot as plt# 1. 数据:模拟温度与销量的关系# 真实数据通常有噪声,这里我们人为生成np.random.seed(42) # 固定随机种子,使结果可重复temperatures = np.array([15, 18, 20, 22, 25, 28, 30]) # 温度(摄氏度)sales = 2.5 * temperatures + 10 + np.random.randn(len(temperatures)) * 3 # 真实规律:销量 = 2.5 * 温度 + 10,加上随机噪声# 2. 模型初始化:随机猜测斜率和截距slope = 0.0 # 斜率intercept = 0.0 # 截距learning_rate = 0.01 # 学习率:控制每次调整的步长# 3. 学习算法:梯度下降(简单版)# 我们定义损失函数为均方误差(MSE),目标是让它最小def compute_loss(temperatures, sales, slope, intercept): predictions = slope * temperatures + intercept loss = np.mean((predictions - sales) ** 2) return loss# 训练循环:重复调整参数num_epochs = 1000 # 迭代次数for epoch in range(num_epochs): # 计算预测值 predictions = slope * temperatures + intercept # 计算梯度(偏导数) gradient_slope = np.mean(2 * (predictions - sales) * temperatures) gradient_intercept = np.mean(2 * (predictions - sales)) # 更新参数:向梯度反方向移动 slope -= learning_rate * gradient_slope intercept -= learning_rate * gradient_intercept # 每100步打印一次损失 if epoch % 100 == 0: loss = compute_loss(temperatures, sales, slope, intercept) print(f"Epoch {epoch}: 斜率={slope:.2f}, 截距={intercept:.2f}, 损失={loss:.2f}")# 4. 结果可视化print(f"\n最终模型:销量 = {slope:.2f} * 温度 + {intercept:.2f}")plt.scatter(temperatures, sales, label='真实数据')plt.plot(temperatures, slope * temperatures + intercept, color='red', label='学习到的直线')plt.xlabel('温度 (℃)')plt.ylabel('销量 (杯)')plt.legend()plt.show()代码解析 :- 我们定义了简单的线性模型,用梯度下降算法不断调整斜率和截距。- 损失函数(均方误差)衡量预测值与真实值的差距,学习算法通过最小化这个差距来"学习"。- 最终,模型学会了近似 销量 = 2.5 * 温度 + 10 的规律,尽管数据有噪声。## 第二个示例:特征工程与多项式回归现实世界很少是简单的线性关系。比如,车速与油耗的关系可能呈U形:低速和高速都费油,中间最省油。如果用直线去拟合,效果会很差。这时我们需要特征工程 :对原始输入进行变换,让模型能表达复杂关系。例如,我们可以将温度平方作为新特征,构建一个二次模型:销量 = a * 温度^2 + b * 温度 + c。这仍然是线性回归,但对特征进行了非线性变换。python# 导入库import numpy as npimport matplotlib.pyplot as plt# 1. 生成更复杂的数据:二次关系 + 噪声np.random.seed(42)X = np.linspace(0, 10, 20) # 0到10均匀分布# 真实关系:y = 2 * X^2 - 3 * X + 5 + 噪声y_true = 2 * X**2 - 3 * X + 5y = y_true + np.random.randn(len(X)) * 10 # 添加噪声# 2. 特征工程:构建多项式特征# 将输入 X 扩展为 [X^0, X^1, X^2] 的形式(注意:X^0=1对应截距)X_poly = np.column_stack([np.ones(len(X)), X, X**2]) # 形状:(20, 3)# 3. 使用正规方程求解最优参数(比梯度下降更直接)# 公式:theta = (X^T * X)^(-1) * X^T * ytheta = np.linalg.inv(X_poly.T @ X_poly) @ X_poly.T @ yprint(f"学习到的参数:常数项={theta[0]:.2f}, 一次项={theta[1]:.2f}, 二次项={theta[2]:.2f}")# 4. 预测并可视化X_test = np.linspace(0, 10, 100)X_test_poly = np.column_stack([np.ones(len(X_test)), X_test, X_test**2])y_pred = X_test_poly @ thetaplt.scatter(X, y, label='带噪声的数据')plt.plot(X_test, y_pred, color='red', label='多项式回归曲线')plt.plot(X_test, 2 * X_test**2 - 3 * X_test + 5, 'g--', label='真实曲线')plt.xlabel('X')plt.ylabel('y')plt.legend()plt.title('特征工程:多项式回归')plt.show()代码解析 :- 我们手动将输入 X 扩展为 [1, X, X^2],这相当于增加了"X的平方"这个新特征。- 使用正规方程直接求解参数,无需迭代。这展示了特征工程如何让线性模型拟合非线性关系。- 注意:特征工程需要人类的知识和直觉,选择合适的变换(如平方、对数、交互项等)往往能大幅提升模型性能。## 总结通过这篇文章,我们建立了机器学习的基本设定:- 数据、模型、学习算法 是三大基石。- 监督学习 中,我们通过最小化损失函数来让模型逼近真实规律。- 特征工程是提升模型能力的关键,它允许简单的模型处理复杂数据。第一个例子展示了线性回归和梯度下降的直观过程,第二个例子则揭示了特征工程的威力。在后续的"机器学习漫游"系列中,我们将深入探讨更复杂的模型(如决策树、神经网络)、不同的学习范式(无监督学习、强化学习),以及如何评估和优化模型。现在,你已经拥有了打开机器学习大门的钥匙------动手运行这些代码,调整参数,观察变化,这就是学习的最佳方式!