4.2 核心算法库巡礼:四类负载的执行形态


4.2 核心算法库巡礼:四类负载的执行形态

本节摘要:MLlib 的算法按执行形态分四类——逐样本预测的线性模型、按特征分裂的树集成、迭代靠近中心的聚类、按用户物品分组的协同过滤。本节各取代表算法做最小可跑示例,从引擎视角讲它们的 Shuffle 形态与并行特征,给出选型对照。

分类回归:宽一行,窄一片

线性模型每轮迭代对每个分区独立算梯度局部和,再一次 Shuffle 归约——梯度向量不大,Shuffle 成本可控。执行形态:迭代次数 × 每轮一次窄依赖流水 + 一次小 Shuffle。

from pyspark.ml.classification import RandomForestClassifier rf = RandomForestClassifier(numTrees=50, maxDepth=8, labelCol="label") model = rf.fit(train_df) pred = model.transform(test_df) # 逐样本打分:纯窄依赖,无 Shuffle,可无限并行

树集成是"宽一行"的反例:单棵树逐层分裂、层内要找最优切分点,涉及按特征分箱统计的聚合。好在各棵树之间彼此独立——引擎把树间并行吃满,单树内的层间同步由库内部处理。

聚类:迭代里的 Shuffle 主角

KMeans 每轮把每个点归到最近中心(窄依赖),再把各分区的类内求和归约(一次 Shuffle)算新中心。中心数多、特征维数高时,这个 Shuffle 是性能瓶颈所在。

from pyspark.ml.clustering import KMeans km = KMeans(k=8, seed=7, featuresCol="features") centers = km.fit(vec_df).clusterCenters() # 每轮迭代中心点向真实位置收敛一步

协同过滤:分组即 Shuffle

ALS 把评分表按用户列和物品列交替求解最小二乘,每轮交替各触发一次按用户、按物品的分组聚合——两次 Shuffle。评分数据倾斜(热门物品、重度用户)时,按第 2 章的倾斜手法处理。

from pyspark.ml.recommendation import ALS als = ALS(userCol="user", itemCol="item", ratingCol="rating", rank=16, coldStartStrategy="drop") rec_model = als.fit(ratings) user_top = rec_model.recommendForAllUsers(10) # 每用户取前 10 推荐

四类算法的执行速查

类别 代表 每轮 Shuffle 并行主体 调优焦点
分类回归 逻辑回归、随机森林 小向量归约 样本级 迭代数、正则
聚类 KMeans 中心聚合 点级 k 值、初始中心
协同过滤 ALS 用户与物品两次分组 用户物品对 秩、倾斜
频繁模式 FP-Growth 事务聚合 事务级 支持度阈值

💡 关键直觉:选算法先看数据形态再看精度。亿级样本逐条打分选线性模型或树集成(预测路径零 Shuffle);交互数据选 ALS;无标签探索选聚类。分布式场景下,"每条记录的执行代价"比单机基准分数更能预测线上体验。

巡检案例:一个推荐场景的两轮算法换型

背景:内容平台要做"千人千面"首页推荐,评分行为两亿条,团队最初选 KMeans 先给内容聚成 40 簇再按簇推送。操作一:KMeans 跑在 400 万条内容向量上,k=40、维 128。结果:每轮中心聚合的 Shuffle 量等于"分区内每簇向量和"的 128 维 × 40 簇 × 分区数,迭代 20 轮耗时 48 分钟;更糟的是业务效果——同簇推送同质化,点击率一周内下滑。操作二:换 ALS 直接吃用户—内容交互。结果:训练 35 分钟(两次分组 Shuffle 交替,配合对热门内容按第 2 章倾斜手法加盐),离线召回命中率提升两成。解读:换型的真正依据不是精度榜单而是数据形态——有显式或隐式交互就该让模型直接学交互结构,聚类只在"冷内容无行为"时补位。变式:内容侧新入库无行为的条目,用 KMeans 按内容向量聚簇找相似邻居做冷启动兜底,两套模型各就其位——执行形态知识在这里直接变成了架构决策。

# 冷启动兜底:无行为内容按向量近邻找相似内容借推荐 from pyspark.ml.feature import VectorAssembler from pyspark.sql import functions as F nearest = (spark.sql(""" SELECT c.content_id, s.sim_id, s.cosine AS sim FROM content_vec c JOIN LATERAL ( SELECT content_id AS sim_id, sum(x*y) AS cosine -- 向量点积近似近邻 FROM content_vec ) s ON true ORDER BY sim DESC LIMIT 20""")) # ALS 主链路 + 近邻兜底,两段在调度上互不干扰

FAQ 两问

KMeans 的 k 怎么选,shuffle 成本能预估吗

k 的选法本节只给工程判据:先用采样数据跑肘部法粗定区间,再拿线上真实分布验证稳定性。Shuffle 成本可以按公式心算——每轮每分区传出 k 个"簇内和向量",总量约等于分区数 × k × 维数 × 8 字节,迭代前先算这一笔,超预算就先降维或减 k,别等作业跑一半才 OOM。

随机森林 50 棵树会不会太慢

树的成本主要在深度而不是棵数——各棵树互不依赖,引擎会把树间并行吃满,50 棵浅树的训练常常比 1 棵深树还快,预测路径更是零 Shuffle 的窄依赖。真正的慢点通常在特征分箱统计的聚合上,减 maxBins 比减树数见效更快。

本节要点回顾

  • 预测窄、训练宽:transform 多为窄依赖可水平扩展,fit 的 Shuffle 集中在梯度或分组归约
  • 树间天然并行:集成的各棵树互不依赖,是引擎最容易吃满的负载
  • ALS 双分组:用户与物品交替各付一次 Shuffle,倾斜按第 2 章手法治理
  • 选型看执行形态:按"每条记录的执行代价"选算法,比看榜单分数务实
  • 组合拳常态化:主模型吃交互、聚类补冷启动,两套负载可在同一作业各就各位

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U