01 机器学习到底是什么?从基本概念到第一个预测模型

📅 2026/8/8 9:35:36
01 机器学习到底是什么?从基本概念到第一个预测模型
前言天气软件估计明天的气温邮箱识别垃圾邮件购物网站推荐可能感兴趣的商品这些功能背后都可能用到机器学习。不过机器学习并不是让计算机像人一样“凭空思考”它更像一种从已有数据中总结规律、再利用规律处理新数据的方法。这篇文章先建立几个最常用的概念再用 Python 和 scikit-learn 完成一个小型回归任务根据学习时长预测考试分数。示例数据由代码生成不代表真实教学研究它的用途是让我们看清一次机器学习实验的完整路径。什么是机器学习机器学习Machine Learning是让计算机从数据中学习规律并利用这些规律做出预测或决策的一类方法。这里的“学习”不是记住标准答案而是调整模型内部的参数使模型给出的结果尽量接近已知结果。例如我们收集一些学生的学习时长和考试分数。多数情况下学习时间增加分数也会发生相应变化。机器学习模型会尝试从这些成对数据中找出关系。之后给它一个没有见过的学习时长它就能给出预测分数。机器学习适合规律存在、但很难手写成大量精确规则的问题。它也有边界训练数据有偏差模型通常会继承这种偏差数据太少或输入与目标没有稳定关系预测也不会可靠。传统编程与机器学习的区别传统编程通常是“数据 人写的规则 → 结果”。例如规定成绩大于等于 60 分就是及格程序只需忠实执行这条规则。监督式机器学习更接近“数据 已知答案 → 模型”。我们不直接告诉程序学习 1 小时应得多少分而是提供多组学习时长和对应分数让算法自己估计两者的关系。训练完成后再使用“新数据 模型 → 预测结果”。两者并不是互相替代。规则明确、稳定并且必须严格执行时传统程序往往更合适规则难以逐条描述却有足够的代表性数据时可以考虑机器学习。实际系统也经常把两者组合起来。监督学习、无监督学习和强化学习按照获得反馈的方式机器学习常被分为三类监督学习Supervised Learning训练数据带有已知答案。预测房价、识别垃圾邮件都属于这一类。预测连续数值叫回归预测类别叫分类。本文的分数预测是回归任务。无监督学习Unsupervised Learning数据没有预先给出的答案算法尝试发现内部结构。例如根据消费行为把顾客分成若干组。聚类是常见的无监督学习任务。强化学习Reinforcement Learning智能体在环境中采取动作并从奖励或惩罚中逐步改进策略。例如让程序在模拟环境中学习如何完成游戏任务。三者解决的问题不同。初学时不必急着记住大量算法先判断“有没有答案”“希望预测什么”更重要。特征、标签、样本和模型这四个词会贯穿后续文章样本Sample一条观察记录。本例中一名学生的一组“学习时长与分数”就是一个样本。特征Feature模型用来进行预测的输入信息。本例只有“学习时长”一个特征真实任务还可能加入出勤率等特征。标签Label监督学习中希望模型预测的已知结果。本例的标签是考试分数。模型Model从训练数据中学到的数学关系。本文使用线性回归Linear Regression它尝试用一条直线描述学习时长与分数的关系。在 scikit-learn 中特征通常记为X标签通常记为y。即使只有一个特征X也通常写成“样本数 × 特征数”的二维数组。训练集与测试集如果把所有数据都交给模型训练再用同一批数据考试得到的分数容易过于乐观。因此我们通常先拆分数据训练集Training Set用于让模型学习参数测试集Test Set只在训练完成后用于检查模型对未见样本的表现。验证集Val Set模型确定后参加最终考试用来报告真实准确率。本文把 75% 的样本用于训练25% 留作测试并给train_test_split设置random_state42。固定随机种子意味着每次运行都会得到相同的拆分便于复现和核对。测试集不参与fit否则就失去了模拟“新数据”的意义。第一个机器学习案例我们用代码构造 20 条模拟数据学习时长从 1.0 小时增加到 10.5 小时分数总体随时长上升同时加入少量随机波动。随机数生成器也固定为 42所以数据本身每次都一致。任务流程是生成数据 → 拆分训练集和测试集 → 训练线性回归模型 → 预测测试集 → 计算评估指标 → 预测一个新的 6.5 小时样本。完整可运行代码将下面代码保存为01_demo.py在装有 NumPy 和 scikit-learn 的 Python 3 环境中运行根据学习时长预测考试分数。 import sys def check_environment(): 检查 Python 版本和示例依赖并给出可读的错误信息。 if sys.version_info (3, 8): raise RuntimeError(本示例需要 Python 3.8 或更高版本。) try: import numpy as np import sklearn except ImportError as exc: raise RuntimeError( 缺少 NumPy 或 scikit-learn请先在当前环境安装 requirements.txt 中的依赖。 ) from exc return np, sklearn def main(): np, sklearn check_environment() from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, r2_score from sklearn.model_selection import train_test_split # 构造一组教学用的模拟数据。固定种子使每次生成的数据完全一致。 random_seed 42 rng np.random.default_rng(random_seed) study_hours np.arange(1.0, 11.0, 0.5).reshape(-1, 1) scores 30.0 6.2 * study_hours.ravel() rng.normal( loc0.0, scale2.0, sizestudy_hours.shape[0] ) if study_hours.shape[0] ! scores.shape[0] or not np.isfinite(scores).all(): raise ValueError(示例数据无效特征和标签数量不一致或标签包含非有限值。) # 留出 25% 的样本作为测试集模型训练时不会看到它们。 x_train, x_test, y_train, y_test train_test_split( study_hours, scores, test_size0.25, random_staterandom_seed, ) model LinearRegression() model.fit(x_train, y_train) y_pred model.predict(x_test) mae mean_absolute_error(y_test, y_pred) r2 r2_score(y_test, y_pred) new_prediction model.predict(np.array([[6.5]]))[0] print(fPython: {sys.version.split()[0]}) print(fNumPy: {np.__version__}) print(fscikit-learn: {sklearn.__version__}) print(f训练集样本数: {len(x_train)}) print(f测试集样本数: {len(x_test)}) print(\n测试集预测结果:) for hours, actual, predicted in zip(x_test.ravel(), y_test, y_pred): print( f学习 {hours:4.1f} 小时 | 实际分数 {actual:5.2f} | f预测分数 {predicted:5.2f} ) print(f\n平均绝对误差MAE: {mae:.2f}) print(f决定系数R2: {r2:.3f}) print(f学习 6.5 小时的预测分数: {new_prediction:.2f}) if __name__ __main__: try: main() except (RuntimeError, ValueError) as exc: print(f程序无法继续{exc}, filesys.stderr) sys.exit(1)逐段代码解释check_environment先确认 Python 版本再尝试导入 NumPy 和 scikit-learn。如果依赖缺失程序会给出明确提示并正常进入错误处理而不是在后续步骤产生难懂的异常。np.arange(...).reshape(-1, 1)生成学习时长并把一维数据改为 scikit-learn 需要的二维特征矩阵。rng.normal生成均值为 0 的小幅随机波动。这里明确写出它是模拟数据不能把结果解释成真实学生群体的规律。train_test_split完成随机拆分。model.fit(x_train, y_train)是训练步骤线性回归会根据 15 个训练样本估计直线的斜率和截距。model.predict(x_test)则把 5 个未参与训练的学习时长放入模型得到预测分数。最后代码计算测试集上的 MAE 和 R²并预测学习 6.5 小时的分数。传入[[6.5]]而不是6.5是因为模型期待的输入形状仍然是“1 个样本、1 个特征”。这份代码已在 Conda 的base环境中实际运行版本为 Python 3.11.4、NumPy 1.24.3 和 scikit-learn 1.3.0。程序正常结束本次固定数据与拆分得到训练集 15 条、测试集 5 条MAE 为 1.66R² 为 0.992学习 6.5 小时的预测分数为 70.67。因为随机种子和库版本都固定在相同环境中应得到相同结果不同库版本可能出现很小的浮点差异。如何判断模型效果只看某一条预测并不够因此需要评估指标Evaluation Metric也就是把一组预测质量压缩成数值的方法。平均绝对误差Mean Absolute ErrorMAE会计算每条预测与真实值之差的绝对值再取平均。这里 MAE 为 1.66可以直观理解为在这 5 条测试样本上预测分数平均相差约 1.66 分。MAE 越接近 0 越好。决定系数R-squaredR²衡量模型相对于“总是预测平均值”的方法解释了多少变化。它通常越接近 1 越好0 表示没有优于简单的平均值基线也可能出现负数。本例的 0.992 接近1是因为模拟数据本来就接近直线这不能证明模型在真实考试数据上也会同样准确。测试集只有 5 条所以这个数值主要用于演示流程不能据此作现实决策。真实项目还要使用更多有代表性的数据并检查异常值、偏差和重复实验结果。初学者常见问题1. 机器学习是不是必须使用大量数学公式入门阶段可以先理解数据、训练和评估的流程。随着任务深入线性代数、概率统计和微积分会帮助你理解算法为什么有效但不必等到学完所有数学才开始实践。2. 为什么不能用全部数据训练模型需要在没有见过的数据上接受检查。如果没有测试集我们很难分辨模型是真正学到了规律还是只记住了训练数据。3. R² 很高是否说明模型一定很好不一定。指标还会受到数据规模、拆分方式、数据泄漏和数据代表性的影响。本例是刻意设计的简单模拟数据因此结果较高。现实任务必须结合业务目标和数据来源判断。4. 为什么固定随机种子随机拆分和随机生成数据可能让每次结果不同。固定种子可以让实验更容易复现和排查。固定种子不会自动保证模型正确它只是固定了随机过程。5. 预测结果可以当作真实成绩吗不能。本例只使用学习时长这一项模拟特征也没有真实学生数据。它是编程教学案例不适合评价个人、指导教学或作出实际决定。6. 运行时提示缺少sklearn怎么办先确认终端使用的是预期的 Conda 环境再在该环境中安装与项目匹配的 scikit-learn。包的安装名是scikit-learn代码中的导入名是sklearn。不要为了一个示例盲目升级整个环境。本文总结机器学习的核心不是某个神秘函数而是一套从数据中学习并用新数据检验的过程。本文区分了传统编程与机器学习认识了三类常见学习方式也明确了样本、特征、标签、模型、训练集和测试集。随后我们完成了一个可复现的线性回归案例并用 MAE 与 R² 检查预测效果。记住一个基本顺序即可明确问题准备数据拆分数据训练模型评估模型再谨慎使用预测结果。下一篇预告下一篇将介绍 Anaconda、Python 与机器学习开发环境包括如何理解 Conda 环境、选择解释器、安装依赖以及避开“包装好了却运行不了”的常见问题。