机器学习入门(四):三种学习方式 + 数据从原料到模型

机器学习入门(四):三种学习方式 + 数据从原料到模型

前情回顾:(二)讲了 f→g 的世界观------机器学习就是在噪声和特殊性的干扰下,从数据 D 里学出一个尽可能逼近真实规律 f 的近似函数 g。(三)讲了机器学习能做四类问题(分类/回归/聚类/降维),并简单提了「监督」和「无监督」两种学习方式。
这一篇做两件事:第一,把三种学习方式(监督、无监督、半监督)完整讲透------前两篇只是定性带过,这次给数学形式、给训练机制、给适用场景;第二,回到数据本身------数据从哪来、长什么样、怎么变成机器能吃的格式。整篇还是用房产中介这条故事线串起来。


一、机器学习的三种学习方式

机器学习按「训练数据有没有标签」可以划分成三类:监督、半监督、无监督。三类的差别不止是「有没有标签」这么浅------训练机制、能解决的问题、评估方法、工程代价全都不同。

1.1 监督学习(Supervised Learning)

定义

训练数据里每个样本都有对应的「正确答案」(标签),形式化地写成:

D={(x1,y1),(x2,y2),...,(xm,ym)} D = \{(x_1, y_1), (x_2, y_2), \ldots, (x_m, y_m)\} D={(x1,y1),(x2,y2),...,(xm,ym)}

其中 xi∈Rn x_i \in \mathbb{R}^n xi∈Rn 是第 ii i 个样本的特征向量, yi y_i yi 是它对应的标签。

模型要做的事,是从这堆 (x,y)(x, y) (x,y) 配对中学出一个函数 gg g:

g:X→Y,g(xi)≈yig: X \to Y, \quad g(x_i) \approx y_i g:X→Y,g(xi)≈yi

这就是(二)里讲的 f → g 的世界观------只不过这里的 g 是用带标签的数据训练出来的。

核心机制:误差反馈

监督学习的核心训练循环:

  1. 模型对 xi x_i xi 给出预测 y^i \hat{y}_i y^i

  2. 计算预测和正确答案的差距: loss=L(yi, y^i ) \text{loss} = L(y_i, \hat{y} _i) loss=L(yi,y^i)

  3. 根据 loss 反向调整模型参数

  4. 重复 1~3,直到 loss 收敛

回到房价场景:

  • 输入 xx x = 面积=120, 楼层=3, 房龄=5, 地段=1.2

  • 模型预测 y^ \hat{y} y^ = 480 万

  • 实际成交 yy y = 500 万

  • 预测误差 loss=∣500−480∣=20\text{loss} = |500 - 480| = 20 loss=∣500−480∣=20 万------这里 LL L 是损失函数(Loss) ,本例用了最简单的一种:MAE (Mean Absolute Error,平均绝对误差------直接算差的绝对值)。常见的损失函数还有 MSE (Mean Squared Error,均方误差------把差先平方再平均,对大误差惩罚更重)和交叉熵(Cross-Entropy,分类任务专用,衡量两个概率分布之间的差距)。损失函数的选择会直接影响模型怎么"学"。

  • 模型根据这 20 万的差距,反向调整自己的参数------下次同类房子的预测更靠近 500 万

🧮 数学坐标

  • 学科归属:高等数学 → 函数与最优化;机器学习 → 损失函数与梯度下降
  • 核心目标 min⁡g ∑iL(g(xi),yi) \displaystyle \min_ {g} \sum_i L(g(x_i), y_i) gmini∑L(g(xi),yi),其中 LL L 是损失函数
  • 教材级展开 :留待后续《数学番外:损失函数与梯度下降》

两大类问题

监督学习按标签 yy y 的类型分两大类:

  • 分类(Classification) yy y 是离散类别, y∈{c1,c2,...,cK} y \in \{c_1, c_2, \ldots, c_K\} y∈{c1,c2,...,cK}。例:「优质房源 / 普通房源」二分类

  • 回归(Regression) yy y 是连续数值, y∈Ry \in \mathbb{R} y∈R。例:房价具体多少万

分类和回归用的算法、评估指标都不一样。

典型算法:线性回归、逻辑回归、决策树、随机森林、SVM、神经网络......机器学习一大半经典算法都在这一类下面。

最大代价:标注成本

监督学习的硬伤就一个------获得标签的代价

回到 10 万套房源的例子:你想做「优质 / 普通」二分类,每条数据都要人工审核打标------这是真金白银的成本。这个代价直接决定了「能不能做」,也是后面促成半监督和主动学习诞生的根本原因。

1.2 无监督学习(Unsupervised Learning)

定义

训练数据没有任何标签

D={x1,x2,...,xm} D = \{x_1, x_2, \ldots, x_m\} D={x1,x2,...,xm}

模型只能从 xx x 本身去发现数据的结构。形式化地说,无监督学习是在估计数据的分布 P(X)P(X) P(X),或者寻找数据的内在几何结构。

能做的事

回到房源场景------这次一个标签都没有。无监督学习能做四件事:

1. 聚类(Clustering)

把相似的样本归到一起。比如对 10 万条房源做聚类,可能自然分出三群:

  • 群 A:市中心 + 小户型 + 高单价

  • 群 B:郊区 + 大户型 + 低单价

  • 群 C:老城区 + 中户型 + 中单价 + 高房龄

注意------是模型自己根据相似度发现的群组,不是你告诉它有这三群。

2. 降维(Dimensionality Reduction)

把高维特征压缩到低维,保留主要信息。

比如描述房子用了 50 个特征,但其中很多是高度相关的(建筑面积和套内面积、卧室数和房间总数、地段评分和房价指数)。降维之后可能用 5 个「主成分」就能表达原始 50 维的 90% 信息------便于可视化、加快后续建模、减少过拟合。

🧮 数学坐标

  • 学科归属:线性代数 → 特征值与特征向量、矩阵的特征分解
  • 核心:PCA(主成分分析)通过协方差矩阵的特征分解,找出方差最大的几个方向
  • 教材级展开:留待后续《数学番外:特征值分解与 PCA》

3. 密度估计(Density Estimation)

估算样本在特征空间里的密度分布。

应用:异常值检测。市场上 99% 的房子都集中在某个特征区域,那种「5000 ㎡ + 单价 1 元」的房子落在密度极低的区域------大概率是数据错误或者欺诈挂牌。

4. 关联规则挖掘(Association Rule Mining)

发现特征之间隐含的共现模式。经典例子是「啤酒 + 尿布」------超市数据发现买尿布的人经常一起买啤酒。在房产场景里:买「学区房」的人经常一起搜索「教培机构」「重点小学排名」。

典型算法:K-Means、DBSCAN、GMM(聚类);PCA、t-SNE、UMAP(降维);Apriori、FP-Growth(关联规则)。

核心难点:评估

无监督学习最大的难处------没有标准答案就没法直接评估「对不对」

监督学习里你可以用测试集算准确率:90% 对就是 90% 对。但无监督------你聚出 3 群房子,是好是坏?没人能直接告诉你。

常见的折中评估:

  • 业务判断:让领域专家看聚类结果,是否符合直觉

  • 间接指标:轮廓系数(Silhouette Coefficient)、Davies-Bouldin 指数等

  • 下游任务验证:把无监督结果当作监督学习的输入特征,看下游任务的表现间接反推

1.3 半监督学习(Semi-Supervised Learning, SSL)

定义

训练集中少量样本有标签,大量样本没有标签

D= {(x1,y1),...,(xl,yl)} ⏟ 有标签 ∪ { xl+1 , xl+2 ,...,xm} ⏟ 无标签 D = \underbrace{\{(x_1, y_1), \ldots, (x_l, y_l)\}}_ {\text{有标签}} \cup \underbrace{\{x_{l+1}, x_ {l+2}, \ldots, x_m\}} _{\text{无标签}} D=有标签 {(x1,y1),...,(xl,yl)}∪无标签 {xl+1,xl+2,...,xm}

通常 l≪ml \ll m l≪m------已标注样本数远小于未标注样本数。

为什么需要这一类------标注瓶颈

回到 10 万套房源的场景。如果要做「优质 / 普通」分类,需要给每一条打标签。可是打标签很贵:

  • 人工审核:一个有经验的审核员一天最多打 200 条,10 万条要打 500 天

  • 让业主自标:他们说自己的房子都是优质的

  • 用成交结果倒推:很多房子还没卖,没有成交数据

最后你只标了 2000 条,剩下 9.8 万条只有原始数据没有标签。

这时候选监督学习------只用那 2000 条,太可惜,9.8 万条数据白白浪费。选无监督学习------完全不用那 2000 条标签信息,也浪费。半监督学习就是解决这种场景的折中方案

半监督凭什么能成立------三个核心假设

半监督不是免费午餐。要让大量无标签数据对学习产生帮助,必须假设无标签数据和有标签数据遵循同一套底层规律。具体来说,半监督学习依赖以下三个假设(实际算法常常同时依赖其中多条):

1. 平滑假设(Smoothness Assumption)

如果两个样本 x1,x2 x_1, x_2 x1,x2 在特征空间里离得很近,那它们的标签 y1,y2 y_1, y_2 y1,y2 也应该接近。

房价例子:两套房子都在西湖区文一西路、都是 90 ㎡、都是 5 年房龄------它们的「是否优质」标签大概率一致。其中一套已知是优质房源,另一套大概率也是。

2. 聚类假设(Cluster Assumption)

如果一群样本能自然聚成一团(cluster),那同一团里的样本大概率属于同一类------等价说法是:决策边界倾向于穿过低密度区域。

房价例子:所有「市中心 + 学区 + 小户型」的房子在特征空间里挤成一团,这一团里只要有几条被标为「优质」,整团基本都可以推断为「优质」。

3. 流形假设(Manifold Assumption)

高维特征空间里,真实数据其实分布在一个低维的「流形」上。沿着这个流形走,标签是连续变化的。

🧮 数学坐标

  • 学科归属:拓扑学 → 流形(Manifold)
  • 直觉:高维数据的「骨架」通常是低维的。地球表面是二维的,但塞进三维空间里------这个二维曲面就是「流形」
  • 教材级展开:留待后续番外

这三个假设彼此相关、但不互为严格的包含关系------平滑假设强调函数光滑性、聚类假设强调决策边界在低密度区、流形假设强调数据的几何结构。实际算法里它们经常同时起作用,不同方法侧重不同假设。

半监督的四类任务

按要做的事划分:

  • 半监督分类:少量标签 + 大量无标签,学一个分类器

  • 半监督回归:同上,但输出是连续值

  • 半监督聚类:聚类时利用少量「必须同类 / 必须异类」的约束信息

  • 半监督降维:降维时利用少量标签,让结果更可分

两面性:传统场景里冷门,但正是 LLM 时代的根基

在「传统结构化数据 + 经典机器学习」的工业场景里,半监督使用得并不主流,原因主要是:

  1. 抗干扰能力弱:无标签数据里只要混入少量错标或异常样本,整个学习方向就会被带偏

  2. 强依赖假设是否成立:三个假设都是假设。如果数据其实分成不连贯的子群体,平滑假设就不成立,SSL 甚至会比纯监督更差

  3. 工程上常被「主动学习」替代:与其费劲让模型用无标签数据,不如让模型自己挑出「最不确定的几百条」让人工去标------这叫主动学习(Active Learning),代价更低、收益更高

所以在传统结构化场景,工业上常见的是这一套组合拳:先标少量种子数据 + 主动学习扩充 + 监督学习训练

但深度学习时代彻底改变了半监督的地位------BERT、GPT 这类大模型的训练范式(海量无标签语料预训练 + 少量标注微调)本质上就是半监督/自监督的工业级实践,是现代 LLM 体系的根基。所以「半监督工业上没人用」是个过时的判断,更准确的说法是:在传统结构化数据上不主流,但在文本、图像、语音等非结构化数据 + 深度模型的组合下,它就是当下的事实标准。

1.4 三种学习方式对比

把三种学习方式拼成一张表:

| 类型 | 标签情况 | 数据形式 | 典型任务 | 难点 | 类比 |

|------|---------|---------|---------|------|------|

| 监督学习 | ✅ 全有 | {(x,y)}\{(x, y)\} {(x,y)} | 分类、回归 | 标注成本高 | 做有答案的练习题 |

| 半监督学习 | 🟡 少量有 | {(x,y)}\{(x, y)\} {(x,y)} + {x}\{x\} {x} | 上面四类的「半」版本 | 假设是否成立 | 老师给了几道答案,剩下自己悟 |

| 无监督学习 | ❌ 全没 | {x}\{x\} {x} | 聚类、降维、密度、关联 | 难以评估好坏 | 自己整理资料找规律 |

1.5 还有第四类:强化学习

为了完整性提一下------还有第四种学习方式叫强化学习(Reinforcement Learning, RL)

它和上面三种的根本区别是:训练数据不是事先准备好的固定集合,而是模型和环境交互产生的。模型每做一个动作,环境给一个「奖励信号」(正向或负向),模型根据长期累计奖励调整策略。

AlphaGo、自动驾驶、机器人控制都是强化学习的典型场景;近年用得最广的 RLHF(基于人类反馈的强化学习) 也属于这一类------大模型对齐的关键一环。

强化学习的数学框架(马尔可夫决策过程 MDP)和监督/无监督完全不同,这一系列暂不展开。


二、回到数据本身:模型的「食材」从哪来

学习方式讲完,接下来回到这个系列的主线------数据。一个机器学习项目从启动到上线,真正写算法的时间不超过 20%,剩下 80% 都在跟数据打交道。

2.1 数据的三个来源

| 来源 | 含义 | 房产中介场景的例子 |

|------|------|---------------------|

| 用户访问行为 | 用户在产品里做了什么 | 用户在 APP 里看了哪些房源、停留多久、收藏几次、画了几次圈选区域 |

| 业务数据 | 业务系统沉淀的记录 | 成交记录、签约时间、价格、看房次数、中介带看记录 |

| 外部第三方 | 别家提供的数据 | 地图 API 的周边设施、政府公开的房价指数、运营商的人流数据 |

不同来源的「干净度」差异很大:业务数据通常最干净(来自结构化数据库),用户行为数据次之(埋点容易缺失),第三方数据最复杂(格式各异、可能要花钱、可能不准)。

2.2 数据存储的角色分工

机器学习项目里常见的数据存储工具不止一种------MySQL、HDFS、HBase、Solr、Elasticsearch、Kafka、Redis 都可能同时出现在一个项目里。新手看一眼容易犯懵,其实它们各司其职:

| 存储 | 适合场景 | 房产中介场景的例子 |

|------|---------|---------------------|

| MySQL | 强结构化、需要事务、量不大 | 成交记录、用户账号 |

| HDFS | 海量原始日志,便宜,批处理 | 三年的点击日志归档 |

| HBase | 海量、稀疏、需随机读写 | 用户行为时间线(每个用户几千条行为 × 10 亿用户) |

| Elasticsearch / Solr | 全文检索、模糊查询 | 「西湖区 三居 朝南」这种关键词搜房 |

| Kafka | 流式数据缓冲,生产消费解耦 | 实时点击事件 → 推荐系统 |

| Redis | 内存缓存,毫秒级响应 | 首页热门房源列表 |

Flume + Kafka 通常组合使用:Flume 从各个业务服务器收集日志、推送到 Kafka 队列,下游消费者按需消费------这是大数据采集的事实标准架构。

2.3 没业务数据时去哪找公开数据集

学习阶段最常用的几个:

💡 入门阶段建议从 UCI 起手------数据干净、文档完善、规模小,跑起来快、不用等。


三、数据清洗:把脏原料洗干净

收到的数据基本不能直接用。常见操作分五类。

3.1 缺失值处理

房产数据里,「地段评分」可能 5% 的房源是 NULL(系统没采集到)。三种常见处理:

| 方法 | 做法 | 优缺点 |

|------|------|--------|

| 删除 | 直接扔掉有缺失的行 | 简单,但损失数据 |

| 填充 | 用均值 / 中位数 / 众数填 | 通用,但抹平真实分布 |

| 预测填充 | 用其他特征建小模型预测 | 精细,但成本高 |

工程上还有第四种:把缺失本身当作信号 ------多加一列 is_missing,把「这条数据缺了某个字段」这件事告诉模型。有时候「缺失」本身就有意义(比如「房主电话」缺失的房源往往是公盘房)。

3.2 异常值处理

(二)讲过的房子 C:100 ㎡ 市中心,成交价 50 万(少打了个 0)。怎么自动发现?

3-σ 原则 :假设数据近似正态分布,超过均值 ±3 个标准差的视为可疑值。判断条件是:若 ∣x−μ∣>3σ|x - \mu| > 3\sigma ∣x−μ∣>3σ,则 xx x 被视为异常候选。

IQR 法 :用四分位距。设 Q1 Q_1 Q1 是第 25 百分位、 Q3 Q_3 Q3 是第 75 百分位, IQR=Q3−Q1 \text{IQR} = Q_3 - Q_1 IQR=Q3−Q1,则异常值是落在以下区间外的点:

Q1−1.5×IQR,Q3+1.5×IQR Q_1 - 1.5 \\times \\text{IQR}, \\quad Q_3 + 1.5 \\times \\text{IQR} Q1−1.5×IQR,Q3+1.5×IQR

🧮 数学坐标

  • 学科归属:概率论与数理统计 → 正态分布、四分位数
  • 核心 :在数据近似正态时,±3σ 区间会覆盖约 99.7% 的真实样本 ,也就是说仅有约 0.3% 的真实样本会落在该区间之外 。所以 3-σ 原则是一种工程启发式:把超出范围的点当作"可疑值"做人工或规则复查,而不是直接断定"这条数据不真实"------真要做"是否真实"的概率判定,需要结合业务先验做贝叶斯反向推断。
  • 教材级展开:参见后续《数学番外:正态分布与异常值检测》

3.3 错误值处理

不是「异常」,是格式错误。例如:

  • 「房龄」列出现负数

  • 「城市」列里「杭州」和「Hangzhou」两种写法并存

  • 「面积」是字符串 "120平米" 而不是数字 120

这些只能人工写规则修。

3.4 多数据源合并

业务库的「房源 ID」和第三方地图 API 的「地址字符串」对不上------需要先做关键字匹配或地理编码,把两边的同一个房子合并到一行。

3.5 数据汇总

原始数据可能太细。用户每次点击都有一条记录,做模型时需要汇总成「每个用户过去 30 天点击次数」。这是从「事件粒度」到「用户粒度」的转换------也叫****聚合(aggregation)** **。


四、特征转换:从「人话」到「模型话」

数据洗干净了,下一步是把它变成模型能吃的格式------数值向量

4.1 总原则:模型只认数字

绝大多数机器学习模型(神经网络、SVM、逻辑回归、线性模型......)只能接受一种输入: Rn\mathbb{R}^n Rn 空间里的向量。一行特征 = 一个 n 维数字向量。

一个常见的例外是部分树模型实现 (LightGBM、CatBoost,以及 sklearn 较新版本的 HistGradientBoosting*)------它们可以原生支持类别特征,内部走专门的分裂逻辑,不必先 one-hot。但即使在这些场景里,纯数值向量仍然是绝大多数算法的统一输入格式,所以「转成数值」依然是特征工程的基本功。

🧮 数学坐标

  • 学科归属 :线性代数 → 向量空间 Rn\mathbb{R}^n Rn
  • 教材级展开:参见《数学番外 01》Part 2

这就有了一个根本问题:现实数据里大量是非数字------「西湖区」是字符串、「南向 三居 学区」是文本、户型示意图是图像。要喂给模型,必须先转换。

4.2 七种常见转换

| 原始数据形态 | 转换方法 | 转换后形态 |

|-------------|---------|-----------|

| 类别(如朝向) | 1-of-k 哑编码 | 多个 0/1 列 |

| 文本(如描述) | 词袋 / TF-IDF / 词嵌入 | 词频或权重向量 |

| 图像 | 像素矩阵 / 卷积特征 | 高维数值向量 |

| 音频 | 傅里叶变换 → 频谱 | 频域数值向量 |

| 数值范围差异大 | 标准化 / 归一化 | 同量级数值 |

| 连续数值 | 分箱 | 离散类别 |

| 单个特征不够 | 特征组合 | 衍生新特征 |

下面挑两个最常用、需要展开的:哑编码 (处理类别)、TF-IDF(处理文本)。


五、深入:1-of-k 哑编码(One-Hot Encoding)

5.1 问题:为什么不能直接编成 1/2/3

房屋朝向有 4 种:南、北、东、西。最朴素的想法是编成数字:

| 原始 | 朴素编码 |

|------|---------|

| 南 | 1 |

| 北 | 2 |

| 东 | 3 |

| 西 | 4 |

但这会出大问题 ------模型会把 1/2/3/4 当作有大小、有距离的数值:在线性模型里"西−南"的差距(4−1=3)会被当作真实的数量级关系;在距离类算法(kNN、K-Means)里"西"和"东"被认为差 1、"西"和"南"差 3。但朝向只是类别,根本没有"大小"或"距离"的概念。

⚠️ 这个坑非常常见。直接用整数编码非有序类别,模型会被骗,输出毫无意义。

5.2 解法:每个类别一个独立维度

1-of-k 编码(也叫 One-Hot)的思路:给 k 个类别分配 k 个独立的维度,每个样本在自己所属的那个维度上是 1,其他维度是 0。

| 原始 | 南 | 北 | 东 | 西 |

|------|----|----|----|----|

| 南 | 1 | 0 | 0 | 0 |

| 北 | 0 | 1 | 0 | 0 |

| 东 | 0 | 0 | 1 | 0 |

| 西 | 0 | 0 | 0 | 1 |

四个类别在向量空间里两两正交(彼此垂直),地位平等,没有任何「谁大谁小」的歧义。

🧮 数学坐标

  • 学科归属:线性代数 → 向量空间、基向量、正交性
  • 核心 :one-hot 向量就是 Rk\mathbb{R}^k Rk 空间的标准基向量 e⃗1 , e⃗2 ,..., e⃗k \vec{e}_1, \vec{e} _2, \ldots, \vec{e}_k e 1,e 2,...,e k,两两正交(点积为 0)
  • 教材级展开:参见《数学番外 01》Part 2.4

5.3 用房价数据走一遍完整例子

原始数据(截取前 5 条):

| 房源 ID | 面积 | 朝向 | 楼层类型 | 单价(万/㎡) |

|--------|-----|------|---------|--------------|

| H001 | 120 | 南 | 中楼层 | 5.5 |

| H002 | 90 | 东 | 低楼层 | 4.2 |

| H003 | 150 | 南 | 高楼层 | 6.8 |

| H004 | 80 | 北 | 低楼层 | 3.5 |

| H005 | 110 | 西 | 中楼层 | 4.8 |

「朝向」4 类,「楼层类型」3 类。哑编码后:

| ID | 面积 | 南 | 北 | 东 | 西 | 低 | 中 | 高 | 单价 |

|----|-----|----|----|----|----|----|----|----|------|

| H001 | 120 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 5.5 |

| H002 | 90 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 4.2 |

| H003 | 150 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 6.8 |

| H004 | 80 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 3.5 |

| H005 | 110 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 4.8 |

原本 4 列(不算 ID)变成 9 列。维度膨胀了,但每一列含义都干净。

5.4 哑编码的两个工程坑

坑 1:维度爆炸

如果有一个「城市」特征,包含全国 300 个城市,one-hot 后就是 300 维。再加「区」(每个城市 10 个区,共 3000 个),又是 3000 维。维度高了之后:

  • 内存吃紧

  • 训练变慢

  • 容易过拟合(参考(二)讲的过拟合根源------维度高 = 更容易学到伪规律)

应对 :高基数(high cardinality)类别用更紧凑的编码方式,不直接 one-hot------常见两种:target encoding (目标编码,用该类别对应的目标变量平均值代替类别本身,例如用每个城市的平均房价代替城市名)和 embedding(嵌入,把每个类别学成一个低维稠密向量,相似类别的向量在空间里距离也近------是深度学习处理类别特征的标配做法)。

坑 2:共线性

严格说,在"每个样本必有且仅有一个类别"的前提下 ,k 个类别只需要 k-1 个维度------四个朝向只要知道是不是南、北、东,剩下不是这三个就是西。这种"k 个 one-hot 列加起来恒为 1"的关系叫完全共线性

但要注意一个边界:如果允许「未知」或「缺失」朝向,则需要保留 k 列 + 一列 is_missing 标记。

完全共线性对不同模型的影响也不同:

  • 无正则化的线性模型 (普通最小二乘线性回归、不带正则化的逻辑回归):参数估不准、协方差矩阵不可逆,需要用 drop_first=True 删一列

  • 带正则化的线性模型 (Ridge、L2-LR,也就是 sklearn LogisticRegression 的默认行为):正则项让解唯一、对共线性的鲁棒性强很多,保留全部 k 列影响有限

  • 树模型(决策树、随机森林、GBDT):完全不受共线性影响,保留全部 k 列即可


六、深入:词袋 + TF-IDF

6.1 问题:怎么把「南向 三居 学区 装修」变成向量

房源描述是一段自然语言文本。要让模型用,必须变成数值向量。

最简单的做法叫词袋法(Bag of Words, BoW)

  1. 把所有房源描述里出现过的词,整理成一个「词表」

  2. 每条描述用一个向量表示,向量长度 = 词表大小

  3. 向量的每个位置存这个词在当前描述里出现的次数

举例,假设我们有 3 条房源描述:

  • D1:「南向 三居 学区 装修」

  • D2:「南向 两居 地铁 装修」

  • D3:「北向 三居 学区 老破小」

词表 = {南向, 北向, 两居, 三居, 学区, 地铁, 装修, 老破小},共 8 个词。

词袋向量:

| | 南向 | 北向 | 两居 | 三居 | 学区 | 地铁 | 装修 | 老破小 |

|--|----|----|----|----|----|----|----|------|

| D1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |

| D2 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 |

| D3 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |

这就是词袋------简单粗暴,但有用。

6.2 词袋的两个缺点

缺点 1:忽略词序

「装修 不好」和「不好 装修」在词袋下完全一样,但语义相反。

缺点 2:所有词权重一样

「南向」和「装修」在房产语料里到处都是------几乎每条描述都有。这种词没什么区分度,但在词袋里和「老破小」这种稀有词权重一样。

TF-IDF 解决的是第二个缺点。

6.3 TF-IDF:给词加权重

直觉是这样的:

  • 一个词在当前文档里出现得多 → 这个词对当前文档重要

  • 一个词在所有文档里到处都是 → 这个词没区分度,权重该低

把这两点变成数学:

TF(Term Frequency,词频)

TF(t,d)= nt,d Nd \text{TF}(t, d) = \frac{n_{t,d}}{N_d} TF(t,d)=Ndnt,d

其中 nt,d n_{t,d} nt,d 是词 tt t 在文档 dd d 中出现的次数, Nd N_d Nd 是文档 dd d 的总词数。

为什么要除以总词数?归一化------让长文档和短文档可比。一篇 100 词的文档里「南向」出现 3 次,和一篇 1000 词的文档里「南向」出现 3 次,重要性不一样。本质上这是把原始词频向量按 L1 范数归一化(因为词频之和 = 总词数 = L1 范数)。

🧮 数学坐标

  • 学科归属:线性代数 → L1 范数与归一化
  • 教材级展开:参见《数学番外 01》Part 3

IDF(Inverse Document Frequency,逆文档频率)

IDF(t)=log⁡ Ndf(t) \text{IDF}(t) = \log\frac{N}{\text{df}(t)} IDF(t)=logdf(t)N

其中 NN N 是文档总数, df(t)\text{df}(t) df(t) 是包含词 tt t 的文档数。

为什么是 log?

🧮 数学坐标

  • 学科归属:高等数学 → 函数 → 对数函数
  • 核心:log 把指数差距压成线性差距
  • 教材级展开:参见《数学番外 01》Part 1

如果不套 log,假设语料库有 10000 篇:

  • 「南向」在 9000 篇出现 → 原始比值 = 10000/9000 ≈ 1.11

  • 「老破小」在 100 篇出现 → 原始比值 = 10000/100 = 100

  • 「凶宅」在 1 篇出现 → 原始比值 = 10000/1 = 10000

差距是 1 : 100 : 10000------稀有词的权重会压倒一切,模型一看见「凶宅」就直接定调,其他词全失效。

套上 log(取自然对数)后:

  • ln⁡(10000/9000)≈0.105\ln(10000/9000) \approx 0.105 ln(10000/9000)≈0.105

  • ln⁡(10000/100)≈4.6\ln(10000/100) \approx 4.6 ln(10000/100)≈4.6

  • ln⁡(10000/1)≈9.2\ln(10000/1) \approx 9.2 ln(10000/1)≈9.2

差距压成 0.1 : 4.6 : 9.2,稀有词仍然权重更高,但不再独霸天下。这是 log 在所有「量级跨数量级」场景的核心作用。

TF-IDF

TF-IDF(t,d)=TF(t,d)×IDF(t)\text{TF-IDF}(t, d) = \text{TF}(t, d) \times \text{IDF}(t) TF-IDF(t,d)=TF(t,d)×IDF(t)

一个词既在当前文档里频繁出现,又在所有文档里相对稀有时,TF-IDF 才高------这正是「对当前文档有强代表性」的词。

6.4 完整算一遍:3 条房源描述

接前面 3 条 + 8 词的例子, N=3N=3 N=3。

Step 1:算 TF

每条描述都是 4 个词、每个词出现 1 次,所以 TF = 1/4 = 0.25。

| | 南向 | 北向 | 两居 | 三居 | 学区 | 地铁 | 装修 | 老破小 |

|--|------|------|------|------|------|------|------|--------|

| D1 | 0.25 | 0 | 0 | 0.25 | 0.25 | 0 | 0.25 | 0 |

| D2 | 0.25 | 0 | 0.25 | 0 | 0 | 0.25 | 0.25 | 0 |

| D3 | 0 | 0.25 | 0 | 0.25 | 0.25 | 0 | 0 | 0.25 |

Step 2:算 IDF(用自然对数 ln)

| 词 | df | IDF = ln(3/df) |

|----|----|----------------|

| 南向 | 2 | ln(1.5) ≈ 0.405 |

| 北向 | 1 | ln(3) ≈ 1.099 |

| 两居 | 1 | ln(3) ≈ 1.099 |

| 三居 | 2 | ln(1.5) ≈ 0.405 |

| 学区 | 2 | ln(1.5) ≈ 0.405 |

| 地铁 | 1 | ln(3) ≈ 1.099 |

| 装修 | 2 | ln(1.5) ≈ 0.405 |

| 老破小 | 1 | ln(3) ≈ 1.099 |

Step 3:TF × IDF

| | 南向 | 北向 | 两居 | 三居 | 学区 | 地铁 | 装修 | 老破小 |

|--|------|------|------|------|------|------|------|--------|

| D1 | 0.101 | 0 | 0 | 0.101 | 0.101 | 0 | 0.101 | 0 |

| D2 | 0.101 | 0 | 0.275 | 0 | 0 | 0.275 | 0.101 | 0 |

| D3 | 0 | 0.275 | 0 | 0.101 | 0.101 | 0 | 0 | 0.275 |

观察 D3:稀有词「北向」「老破小」权重 0.275,常见词「三居」「学区」只有 0.101------稀有词权重明显更高,达到了我们想要的效果。

6.5 工程实现的三个坑

坑 1:sklearn 公式和教科书不完全一样

sklearn 用的是平滑版本:

IDFsklearn(t)=log⁡ 1+N1+df(t) +1 \text{IDF}_{\text{sklearn}}(t) = \log\frac{1+N}{1+\text{df}(t)} + 1 IDFsklearn(t)=log1+df(t)1+N+1

  • 分子分母都 +1:相当于"虚拟添加一个所有词都至少出现一次的文档",避免除零、做拉普拉斯平滑

  • 最后 +1:让出现在所有文档的词 IDF 也不为 0(避免被完全消除)

跑代码时你的手算结果和 sklearn 输出对不上,多半是这个原因。

坑 2:log 的底数

教科书有的用 ln(自然对数),有的用 log₁₀,有的用 log₂。不影响相对排序,只影响数值大小------同一份代码内部统一即可。

坑 3:稀疏存储

实际语料库词表往往是几万到几十万维,一篇文档只用到几百个词。直接存稠密矩阵会爆内存。sklearn 默认返回稀疏矩阵scipy.sparse),只存非零位置。

python 复制代码
from sklearn.feature_extraction.text import TfidfVectorizer

  


docs = [

    "南向 三居 学区 装修",

    "南向 两居 地铁 装修",

    "北向 三居 学区 老破小",

]

  


vectorizer = TfidfVectorizer(token_pattern=r"\S+")  # 默认按空格切词

X = vectorizer.fit_transform(docs)

  


print(vectorizer.get_feature_names_out())

print(X.toarray())   # 转成稠密矩阵看一眼

跑出来的数值会和我们手算的略有差异------正是因为 sklearn 用了 1+N1+df +1 \frac{1+N}{1+\text{df}}+1 1+df1+N+1 平滑公式,并且默认对 TF-IDF 向量做了 L2 归一化(每行变成单位向量)。


总结

把这一篇串起来:

text 复制代码
三种学习方式(监督 / 半监督 / 无监督)------ 按标签情况划分

        ↓

数据从哪来(业务 / 行为 / 第三方)

        ↓

存储分工(MySQL / HDFS / HBase / Kafka...)

        ↓

数据清洗(缺失 / 异常 / 错误 / 合并 / 汇总)

        ↓

特征转换(让模型能吃)

   ├── 哑编码  →  类别 → 0/1 正交向量

   └── TF-IDF →  文本 → 权重向量

        ↓

[准备好喂给模型的干净数据]

数据准备完了,下一步就是把它喂给算法、训练出模型------以及更关键的一件事:评估模型考得好不好

相关推荐
独自归家的兔6 小时前
AI界的 GitHub?Hugging Face 全面解析
人工智能·github
一次旅行6 小时前
全场景AI智能体工作台WorkBuddy实战操作详解
人工智能
逻辑君6 小时前
Foresight研究报告【20260009】
人工智能
tjsoft6 小时前
第四封信:谈人工智能时代的教育
人工智能
guslegend6 小时前
第4讲:应用架构与代码组织
数据结构·人工智能·架构
@我们的天空6 小时前
Claude Code + GLM-5 深度赋能测试:开发 8 大 Skill 构建 AI 测试助手集群
人工智能·python·测试工具·自动化·ai编程
联通权斌6 小时前
23个咨询单,关于运营商、智算和AI
人工智能
摄影图6 小时前
[图片素材]国产芯片半导体 满足科技创作多场景需求
人工智能·科技·aigc·贴图·插画
音视频牛哥6 小时前
具身智能进入深水区:特斯拉闭环、国产机器人突围与场景价值重构
人工智能·agi·机器视觉·具身智能·特斯拉和宇树科技·特斯拉optimus·具身智能发展困境