📘 第2课:藏宝图——理解机器学习项目的工作流程

"没有食谱就不要开始烹饪。没有计划就不要构建模型。"


⏱️ 本课预计时长: 60-75分钟


🧭 为什么这节课如此重要?

许多初学者都会犯同样的错误:他们想直接跳到模型

"我想现在就训练一个像ChatGPT一样的AI!"

但这就像想要建造一架飞机却不知道螺丝是什么一样。

在本课中,你不仅会学习ML项目的步骤……你还会学习每个步骤存在的原因如果你跳过它会发生什么,以及如何从第一分钟开始像数据科学家一样思考

最后,你会有一个清晰的心智地图,可以应用到任何项目中:垃圾邮件分类、价格预测、欺诈检测、医学诊断,任何项目!


🗺️ 藏宝图:ML项目的5个黄金步骤

想象你是一个寻找埋藏宝藏的海盗。你不能随便开始挖掘。你需要:

  1. 一张地图 → 定义问题。
  2. 寻找线索 → 获取和探索数据。
  3. 准备工具 → 清理和转换数据。
  4. 在正确的地方挖掘 → 训练模型。
  5. 验证是否是真金 → 评估模型。

这正是我们在ML中要做的事情!

让我们详细分解每个步骤,包含真实例子、常见错误和专家提示。


🧩 步骤1:定义问题——你想预测什么?为谁?为什么?

"定义良好的问题已经解决了一半。"

在接触代码之前,在寻找数据之前……停下来思考

🔍 你应该问自己的关键问题:

  • 我想预测什么?

    • 一个类别?→ 分类(垃圾邮件/正常邮件、猫/狗、通过/不通过)。
    • 一个数字?→ 回归(房价、温度、月销售额)。
    • 一个序列?→ 生成(文本、音乐、代码)。
  • 谁会使用这个预测?

    • 医生?→ 你需要高精度、可解释性。
    • 应用用户?→ 你需要速度、简单性。
    • CEO?→ 你需要清晰的业务指标。
  • 为什么解决这个问题很重要?

    • 能省钱吗?能救命吗?能改善用户体验吗?
    • 如果你无法回答这个问题……也许不值得做。

🎯 例子1:垃圾邮件分类器

  • 什么: 预测消息是"垃圾邮件"还是"正常邮件"(非垃圾邮件)。
  • 谁: 电子邮件或短信用户(他们想要更少的垃圾邮件)。
  • 为什么: 减少浪费的时间、防止欺诈、提高生产力。

🎯 例子2:房价预测器

  • 什么: 根据房屋特征预测房价(数字)。
  • 谁: 买家、卖家、房地产经纪人。
  • 为什么: 帮助设定公平价格、加快销售、减少不确定性。

❌ 常见错误#1:跳过这一步

"我要使用这个泰坦尼克号数据集,因为它很酷。"

不!数据集不是目标。问题是目标。 数据集只是解决问题的工具。


📦 步骤2:获取和探索数据——金矿(或煤矿)

"数据是新石油……但有时它满是泥土。"

一旦问题被定义,你需要数据。没有数据,就没有ML。

🔍 在哪里获取数据?

  • 公共数据集: Kaggle、Hugging Face、UCI机器学习仓库、Google数据集搜索。
  • 你自己的数据: 调查、应用日志、销售历史等。
  • API: Twitter、Reddit、Google趋势等。
  • 网页抓取(小心且符合道德): BeautifulSoup、Scrapy。

🎯 例子:SMS垃圾邮件数据集

我们将在本课程中使用这个。它在Kaggle上,小而干净,非常适合入门。

import pandas as pd

url = "https://raw.githubusercontent.com/justmarkham/DAT8/master/data/sms.tsv  "
data = pd.read_csv(url, sep='\t', names=['label', 'message'])

🔍 初始探索:了解你的数据!

永远不要假设数据是干净的。总是先探索它。

问自己这些问题:

  • 它有多少行和列?
print(data.shape)  # (5572, 2) → 5572条消息,2列
  • 前几行是什么样子?
print(data.head())
  label                                            message
0   ham  Go until jurong point, crazy.. Available only ...
1   ham                      Ok lar... Joking wif u oni...
2  spam  Free entry in 2 a wkly comp to win FA Cup fina...
3   ham  U dun say so early hor... U c already then say...
4   ham  Nah I don't think he goes to usf, he lives aro...
  • 标签中有多少唯一值?
print(data['label'].value_counts())
ham     4825
spam     747
Name: label, dtype: int64

→ 我们有更多的"正常邮件"而不是"垃圾邮件"!这很重要(我们会在评估中看到)。

  • 有空值吗?
print(data.isnull().sum())

→ 在这种情况下,没有。但在现实生活中,几乎总是有!

  • 消息长度是如何分布的?
data['length'] = data['message'].apply(len)
print(data['length'].describe())
count    5572.000000
mean       80.489052
std        59.942492
min         2.000000
25%        36.000000
50%        61.000000
75%       111.000000
max       910.000000

→ 有消息长达910个字符!它们会是垃圾邮件吗?会是正常的吗?

import matplotlib.pyplot as plt
import seaborn as sns

sns.histplot(data=data, x='length', hue='label', bins=50)
plt.title("按类型的消息长度分布")
plt.show()

→ 你会看到垃圾邮件消息往往更长。这是一个有价值的线索!


🧹 步骤3:准备数据——清理、转换、分割

"垃圾进,垃圾出。" — 垃圾进垃圾出(GIGO)法则

ML模型就像F1赛车引擎:非常强大,但对燃料质量非常敏感

🔧 常见的准备任务:

1. 处理空值

# 如果有空值,你可以:
# data = data.dropna()  # 删除有空值的行
# 或
# data['column'] = data['column'].fillna(data['column'].mean())  # 用均值填充

2. 标签编码(如果是分类)

# 将'ham'/'spam'转换为0/1
data['label'] = data['label'].map({'ham': 0, 'spam': 1})

3. 分割为训练和测试

永远不要用相同的数据训练和评估!

from sklearn.model_selection import train_test_split

X = data['message']  # 特征
y = data['label']    # 标签

X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2,   # 20%用于测试
    random_state=42  # 为了可重现的结果
)

print(f"训练: {len(X_train)} 条消息")
print(f"测试: {len(X_test)} 条消息")

4. 向量化(将文本转换为数字)

模型不理解文本。它们理解数字。

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer()
X_train_vec = vectorizer.fit_transform(X_train)  # 学习词汇表+转换
X_test_vec = vectorizer.transform(X_test)        # 仅转换(不学习!)

print(f"词汇表: {len(vectorizer.vocabulary_)} 个唯一单词")
print(f"X_train_vec形状: {X_train_vec.shape}")  # (4457, 7358) → 4457条消息,7358个单词

📌 CountVectorizer做什么?

  • 创建一个包含X_train中所有唯一单词的词汇表。
  • 对于每条消息,计算每个单词出现的次数。
  • 将每条消息转换为数字向量(频率)。

例子:

消息: "free money now"
词汇表: ['free', 'money', 'now', 'click', 'here', ...]

向量: [1, 1, 1, 0, 0, ...] → "free"出现1次,"money"出现1次,等等。

🤖 步骤4:训练模型——魔法(但不是真的魔法)

"这是计算机学习的地方……但你给它工具。"

现在,是训练的时候了!

🔧 选择算法

对于文本分类,一个好的起点是多项式朴素贝叶斯

为什么?

  • 它简单、快速,并且在文本上表现得惊人地好。
  • 它不需要太多算力。
  • 它对不平衡数据具有鲁棒性(就像我们的数据集,有更多的"正常邮件"而不是"垃圾邮件")。
from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB()
model.fit(X_train_vec, y_train)  # 训练模型!

📌 fit()做什么?

  • 学习概率:
    • 哪些单词在垃圾邮件中出现得更多?
    • 哪些单词在正常邮件中出现得更多?
  • 在内部保存这些概率。

就是这样!你的模型现在"知道"如何区分垃圾邮件和正常邮件。


📈 步骤5:评估模型——它有效……还是只是认为它有效?

"不要相信你的模型。测试它。"

训练很容易。评估得好是区分业余爱好者和专业人士的关键。

🔍 在测试集上预测

y_pred = model.predict(X_test_vec)

📊 计算指标

准确率(总体精度)

from sklearn.metrics import accuracy_score

acc = accuracy_score(y_test, y_pred)
print(f"准确率: {acc:.4f}")  # 例如: 0.9825 → 98.25%正确

→ 看起来很棒!但够吗?

混淆矩阵

from sklearn.metrics import confusion_matrix
import seaborn as sns

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['正常邮件', '垃圾邮件'], 
            yticklabels=['正常邮件', '垃圾邮件'])
plt.title("混淆矩阵")
plt.ylabel("真实")
plt.xlabel("预测")
plt.show()

→ 它会显示类似这样的内容:

          预测
          正常邮件  垃圾邮件
真实
正常邮件     950    5
垃圾邮件      10   150

→ 这是什么意思?

  • 真负例(TN): 950条正常邮件正确分类。
  • 假正例(FP): 5条正常邮件分类为垃圾邮件(严重错误!)。
  • 假负例(FN): 10条垃圾邮件分类为正常邮件(严重错误!)。
  • 真正例(TP): 150条垃圾邮件正确分类。

分类报告

from sklearn.metrics import classification_report

print(classification_report(y_test, y_pred, target_names=['正常邮件', '垃圾邮件']))
              precision    recall  f1-score   support

         正常邮件    0.99      0.99      0.99       955
        垃圾邮件    0.97      0.94      0.95       160

    accuracy                           0.98      1115
   macro avg       0.98      0.97      0.97      1115
weighted avg       0.98      0.98      0.98      1115

📌 这些指标是什么意思?

  • 精确率: 在所有我说是垃圾邮件的中,有多少真的是?
    → 垃圾邮件: 0.97 → 97%标记为垃圾邮件的消息确实是垃圾邮件。很好!

  • 召回率(敏感性): 在所有存在的垃圾邮件中,我检测到了多少?
    → 垃圾邮件: 0.94 → 我检测到了94%的垃圾邮件。非常好!

  • F1分数: 精确率和召回率的调和平均值。适用于不平衡数据。


🔄 改进循环:这里从未结束

不要停留在第一个版本!

现在你有了基础,你可以:

  • 尝试另一个向量化器(TfidfVectorizer)。
  • 尝试另一个模型(LogisticRegressionSVM)。
  • 添加更多数据。
  • 改进文本清理(删除停用词、词形还原)。
  • 调整超参数。

数据科学是迭代的。 永远没有"最终版本"。总是有改进的空间。


❌ 此步骤中的常见错误(避免它们!)

  1. 在训练数据上评估 → 给你虚假的成功感。
  2. 不分割训练/测试 → 你不知道你的模型是否泛化。
  3. 在不平衡数据上仅使用准确率 → 可能隐藏严重错误。
  4. 不先探索数据 → 你错过模式、错误、机会。
  5. 不记录你做了什么 → 明天你不会记得为什么这样做。

✅ 本课检查清单——你现在应该理解什么?

☐ ML项目的5个步骤以及为什么每个步骤都很关键。
☐ 如何探索数据集并在使用它之前。
☐ 为什么分割训练/测试是强制性的。
☐ 如何将文本转换为数字(向量化)。
☐ 如何使用fit()训练模型。
☐ 如何用准确率、混淆矩阵和分类报告评估它。
☐ 第一个模型从来不是最后一个……总是可以改进的!


🎯 要记住的话:

"在ML中,最重要的不是模型……而是过程。"


Course Info

Course: AI-course0

Language: ZH

Lesson: 2 ml workflow