数据分析做到挖掘建模这一步才算真正从“看数据”跨到了“用数据”。前面几篇我们一路把数据清洗、特征处理、可视化探索都过了一遍当你拿到一份干净、结构化的数据之后接下来要做的就是用算法从里面挖出规律这就是数据分析的第四阶段挖掘建模。这个环节里监督学习中的分类模型和回归模型对付的是“有标准答案”的问题——比如判断用户会不会流失、预测明年的销售额无监督学习对付的是“没有标准答案”的问题——比如把用户自动分成几类、找出经常一起购买的商品组合。两条路线各有各的适用场景也各有各的坑。这篇文章我按自己做项目的实际顺序来写从建模前准备讲到模型评估和算法选型全程带着可复现的代码和参数说明适合正在系统学习数据分析、或者工作中第一次独立建模的读者照着走一遍。1. 挖掘建模在数据分析流程中的定位1.1 数据分析的完整链路建模到底处于哪一环很多人学数据分析一开始就被各种算法名字吓住觉得建模是最难的一步。其实放到完整流程里看建模只是中间一环而且前面每一步做得好不好直接决定建模的成败。我习惯把整个项目分成四步数据获取、数据预处理、探索性分析、挖掘建模。数据获取解决“有没有数据”的问题预处理解决“数据能不能用”的问题探索性分析解决“数据长什么样”的问题挖掘建模才轮到“数据能告诉我们什么规律”的问题。这一步之所以叫“挖掘”是因为它和前面的描述性分析有本质区别。探索性分析是在描述过去——这个月销量涨了、那个渠道转化率低挖掘建模是在预测和归纳——根据历史行为判断一个用户未来会不会流失、把特征相似的客户归成一类。可以说建模是把前面所有准备工作兑现成业务价值的关键一步。但反过来也要记住没有前面三步打底再牛的算法也救不回来脏数据。我接过不少项目数据里重复值、缺失值、异常值一大堆业务方要求直接建模结果模型效果差到没法看回头老老实实补预处理效果立刻就不一样了。这个环节还有一个很隐蔽的心态误区觉得建模必须要用高大上的算法逻辑回归不够看。实际上在我做过的项目里逻辑回归和决策树这类经典算法至少能解决五成以上的业务问题而且交付给业务方之后他们看得懂、愿意用这本身就是巨大优势。先跑通一个简单可靠的基线模型再逐步升级这个顺序远比你一上来就调XGBoost的三十个参数要高效。1.2 建模前必做的三件事少一件都容易翻车第一件事是检查数据划分。建模之前必须把数据切成训练集和测试集这是老生常谈但实际操作里很多人会犯一个错误先做特征工程或者数据标准化再切分数据。正确的顺序是先切分、再对训练集做拟合类的变换最后把同一套变换应用到测试集上。否则测试集的信息会通过均值和方差偷偷“泄露”给模型评估结果虚高模型上线就崩。这个细节业内叫“数据泄露”后面我会专门展开讲。第二件事是确认样本量和特征数量的关系。数据量远小于特征数的时候很多复杂模型会直接过拟合。我有个朴素的经验法则样本量至少要是特征数量的十倍左右再少就要考虑降维或者简化模型。去年接的一个项目特征工程做了两百多个特征样本只有五百多条用随机森林跑出来训练集准确率百分百、测试集只有六成典型的过拟合。后来用PCA压到二十个特征再配合正则化效果才稳下来。第三件事是明确这次建模的目标是解释还是预测。如果业务方只是想知道“哪些因素影响销量”那优先选可解释性强的模型比如线性回归、决策树如果是要做精准推荐或者风控评分预测精度优先那可以上随机森林、梯度提升这类集成模型。目标不同模型选型和评估标准完全不同。想清楚这一点后面能省下大量瞎折腾的时间。2. 监督学习之分类模型2.1 分类问题怎么选算法优缺点一次说清分类问题是监督学习的重头戏目标是让模型学会把样本分到预设的类别里。最典型的是二分类——是或否、流失或不流失、欺诈或正常多分类也很常见比如把客户分成高、中、低三个价值等级。初学者最容易犯的错是一上来就追新算法其实经典算法把原理吃透足够解决大部分业务问题。逻辑回归虽然名字带“回归”实际是标准分类算法。它本质是线性回归加了一个sigmoid函数把输出压到0到1之间变成概率。优点是训练快、可解释性强每个特征的系数可以直接告诉业务方“这个指标每提高一档风险是提高还是降低”缺点是擅长线性边界特征和类别关系比较复杂的时候效果一般。决策树则是按特征做一系列“是/否”判断像玩猜谜游戏一样把样本分到叶节点。它的优点是完全可解释能画出一棵直观的树给非技术同事看缺点是单棵树容易过拟合数据稍微变一点结构就大变样。随机森林是很多棵决策树投票的结果每棵树用随机抽样的数据和随机选的特征训练最后取多数票。它大幅缓解了单棵树的过拟合问题是我在分类任务里的默认选项。XGBoost这类梯度提升树则是另一种集成思路每棵新树都在拟合前面所有树的残差精度通常更高但参数多、调参复杂、训练时间也长。我做表格类的分类任务时默认流程是先用随机森林拿一个基线结果如果效果不够再上XGBoost这个策略既稳又省时间。2.2 分类模型评估别只盯准确率四张牌要一起看分类模型的评估是最容易踩坑的地方尤其是正负样本不均衡的时候。拿欺诈检测举例一万笔交易里可能只有十笔是欺诈模型只要把所有交易都预测成正常准确率就有99.9%看起来效果好得吓人实际上一点用都没有。所以准确率不能单独看要配合精确率、召回率和F1一起看。这四个指标的关系用一张混淆矩阵就能说清楚预测方向实际正类实际负类预测正类TP真正例FP假正例预测负类FN假负例TN真负例精确率 TP / (TP FP)回答的是“模型说是欺诈的里面真的有几分之几是欺诈”召回率 TP / (TP FN)回答的是“所有真欺诈里模型抓到了几分之几”F1是精确率和召回率的调和平均适合两者都重要时用一个数概括整体表现。实际业务里精确率和召回率往往是跷跷板。风控场景宁可误杀也不能漏就偏向提高召回率营销场景预算有限宁可少推荐也不想打扰用户就偏向提高精确率。还有一个常用指标是AUC它衡量的是模型把正样本排在负样本前面的概率不受分类阈值影响适合看模型整体的排序能力。我每次跑完分类模型习惯把所有指标一次性打出来只看单一数字翻车的概率实在太高。2.3 实操跑通一个分类模型的全流程直接上一段能跑通的代码用模拟的二分类数据演示完整流程。数据量一千条、特征二十个模拟的是非常常见的表格分类任务。from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score X, y make_classification( n_samples1000, n_features20, n_informative10, n_redundant5, random_state42 ) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42 ) model LogisticRegression(max_iter1000) model.fit(X_train, y_train) y_pred model.predict(X_test) print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred)) print(AUC:, roc_auc_score(y_test, model.predict_proba(X_test)[:, 1]))这里有几个参数值得说。make_classification里的n_informative是有实际预测能力的特征数量n_redundant是能由其他特征推导出来的冗余特征这样构造的数据更贴近真实场景。test_size0.3表示测试集占三成random_state固定随机种子保证每次跑出来的结果一致方便复现。逻辑回归的max_iter设为1000是因为sklearn默认的迭代次数在特征多时可能不收敛调大一点能避免警告。跑完后先看混淆矩阵再读classification_report里的精确率、召回率和F1。AUC这里用的是predict_proba取正类概率而不是直接用预测标签原因在于AUC计算的是排序分数而不是离散类别。整个过程跑下来不到一分钟但已经把分类建模的标准流程完整走了一遍。实际项目里把模拟数据换成真实业务表代码结构几乎不用改。3. 监督学习之回归模型3.1 回归和分类到底差在哪回归模型解决的是预测连续数值的问题比如销售额、房价、温度、库存量。和分类最大的区别在于输出类型分类输出离散标签回归输出连续数值对应的评估方式也完全不同分类看准确率、F1这类“分对没有”的指标回归看预测值和真实值之间的误差大小。另一个关键区别是损失函数。分类模型常用交叉熵惩罚的是“分错”回归模型常用均方误差MSE惩罚的是“偏多远”。均方误差把误差平方之后大误差会被成倍放大所以回归模型对极端值特别敏感。我说一个亲身经历之前做个销量预测历史数据里有一条因为促销活动销量暴增十倍模型为了拟合这条记录把整体预测都拉高了删掉这个异常点之后误差立刻降下来。所以做回归建模先看一眼目标变量的分布、处理掉极端离群点比纠结选什么算法重要得多。常用算法里线性回归是最基础的假设特征和目标之间是线性关系参数含义就是“某个特征每变化一个单位目标平均变化多少”解释性极强。岭回归和Lasso都是在线性回归基础上加了正则化惩罚用来抑制过拟合。岭回归用L2惩罚让系数整体变小Lasso用L1惩罚可以顺便把不重要的特征系数压成零起到特征选择的作用。再往上就是决策树回归、随机森林回归和梯度提升回归它们能捕捉非线性关系精度通常更高但可解释性差一些。3.2 回归模型怎么评估光看R方可不够回归评估有一套固定的指标组合。MSE是预测值和真实值差的平方的平均RMSE是MSE开根号单位回到原始量纲解释起来更直观MAE是绝对误差的平均对极端值没那么敏感R方又叫决定系数衡量模型解释了目标变量多少比例的方差范围一般在0到1之间越接近1说明拟合越好。实际看指标的时候我有个习惯RMSE和MAE一定要一起看。如果RMSE明显大于MAE说明数据里有不小的极端误差模型对某些样本预测得很离谱。R方单看也容易误导样本量很小的时候R方很容易虚高等新数据进来马上现原形。还有一点同一份数据用不同量纲的目标变量RMSE的绝对值没有可比性比如预测销售额用元做单位RMSE几百很正常换成千元做单位就变成零点几。所以跨项目比较模型优先用R方或者归一化之后的误差。3.3 实操回归模型训练与过拟合处理下面用模拟回归数据演示一遍特征十五个、样本一千条、加了适量噪声让问题更真实。from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split from sklearn.linear_model import Ridge from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score import numpy as np X, y make_regression( n_samples1000, n_features15, noise20, random_state42 ) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42 ) model Ridge(alpha1.0) model.fit(X_train, y_train) y_pred model.predict(X_test) rmse np.sqrt(mean_squared_error(y_test, y_pred)) print(RMSE:, rmse) print(MAE:, mean_absolute_error(y_test, y_pred)) print(R2:, r2_score(y_test, y_pred))make_regression里的noise参数是模型加入的噪声强度模拟真实数据的随机波动。Ridge的alpha是正则化强度alpha越大系数被压得越小模型越简单。alpha1.0是常用起点实际调参时可以从小到大试几组观察测试集误差变化找到误差最低的位置。我做调参很少追求极致的网格搜索一般先粗跑几组alpha值0.01、0.1、1、10、100画出测试集RMSE随alpha变化的曲线然后选曲线最低点附近的值性价比最高。过拟合在回归里最常见的症状是训练集误差远小于测试集误差。处理手段无非几条增加训练数据、减少特征、增大正则化强度、换更简单的模型。我通常先试增大alpha因为代价最小不行就用Lasso做特征选择砍掉不重要的特征再不行才换模型从线性族换到树模型。这里特别提醒一句千万不要一上来就堆特征特征越多模型越容易学到噪声里的巧合规律这也是过拟合最常见的来源。4. 无监督学习4.1 聚类分析K-Means原理与K值选择无监督学习处理的是没有标签的数据核心思路是让算法自己发现结构。聚类是其中重头戏目标是让同一类内的样本尽可能相似、不同类之间的样本尽可能不同。最常用的K-Means算法思路很朴素先随机选K个中心点把每个样本分到最近的中心点然后更新中心点为该类的均值重复这两步直到中心点不再变化。这里有两个必须说清楚的要点。第一K-Means对特征尺度非常敏感量纲差异大的特征会主导距离计算。举个例子年龄是两位数、收入是五位数计算欧氏距离时收入会完全压过年龄的影响力。所以聚类之前一定要做标准化很多新手跳过这一步结果聚类出来的类别实际上只跟收入一个特征相关其他特征全成了摆设。第二K-Means默认假设每个簇近似球形如果真实类别是弯月形、环形这种复杂形状K-Means效果会大打折扣这种情况要考虑DBSCAN这类基于密度的算法。K值怎么选是另一个高频问题。最常用的方法是肘部法则把不同K值对应的簇内误差平方和画出来随着K增大误差会一直下降但下降速度会在某一点突然变缓像手臂的肘部这个点就是推荐K值。业务场景里还要结合可解释性判断我以前做客户分群肘部法则说分五类但业务方反馈五类太细、没法分别制定运营策略最后合并成三类模型更简单、业务也能用这是典型的算法结果和业务需求互相妥协。下面是K-Means的标准操作流程包含了标准化的关键步骤from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.metrics import silhouette_score scaler StandardScaler() X_scaled scaler.fit_transform(X) # X假设是已经准备好的特征矩阵 inertias [] for k in range(2, 9): km KMeans(n_clustersk, n_init10, random_state42) km.fit(X_scaled) inertias.append(km.inertia_) # 画出inertia随K变化的折线观察肘部位置 km KMeans(n_clusters3, n_init10, random_state42) labels km.fit_predict(X_scaled) print(轮廓系数:, silhouette_score(X_scaled, labels))n_init10表示用十个不同的初始中心点各跑一遍取最优结果这是降低K-Means随机性的有效手段建议保持默认不要调太小。4.2 关联规则与降维两个无监督场景一次讲透关联规则最经典的场景是购物篮分析回答“买了A的顾客还经常买什么”。Apriori算法的核心是支持度和置信度支持度是某个项集在所有交易中出现的比例置信度是在买了A的条件下同时买B的比例。实际操作里要先设定最小支持度阈值把频繁项集挖出来再按置信度生成关联规则。这里面有一个必须提醒的坑支持度阈值设得太低会挖出大量无意义的组合比如“买洗衣液的人也会买牛奶”这种相关性完全没有业务价值设得太高又什么都挖不出来。我一般先用历史数据试几个阈值看候选规则数量控制在几十条以内再往下分析。降维也是无监督学习的重要组成部分最常用的是PCA主成分分析。它的思路是把原始特征线性组合成一批新特征这些新特征互不相关并且按方差从大到小排列前面几个主成分就能保留大部分信息。PCA不仅能解决特征过多导致的过拟合还能用来做数据可视化——高维数据压缩成两三个主成分之后可以画散点图直接观察样本分布这在探索性分析阶段相当好用。我之前做过一个客户画像项目原始特征八十多个、高度相关直接用聚类结果全是噪声。先用PCA把维度压到能解释百分之九十五方差的主成分数量再去做聚类类别结构一下子清晰了很多。但PCA也有代价新特征失去了原始含义业务方问“这个主成分是什么意思”的时候很难解释。所以如果业务要求可解释性降维要慎重或者改用Lasso做特征选择保留原始特征虽然效果可能差一点但至少每个特征都能说清楚来龙去脉。4.3 无监督学习怎么评估没有标签也能判断好坏无监督学习没有标签评估是老大难问题。聚类常用的内部指标是轮廓系数它同时衡量样本与自身簇的紧密度和与其他簇的分离度取值范围在-1到1之间越接近1说明聚类效果越好。但轮廓系数只是数学上的“整洁度”指标只能作为参考不同K值跑出来的轮廓系数可能非常接近单看数字很难做决策。更可靠的方式是业务验证。聚类出来的每一类都要回到业务场景里看是否合理。比如某公司做人货场分析聚类把用户分成四类一类是高频高客单价的忠诚用户一类是低频低价的价格敏感用户这几类一眼就能看出特征差异说明聚类方向和业务常识一致这个结果才敢拿去用。反过来如果聚类结果跟业务认知完全对不上不一定是算法错了有可能是特征选择没做好或者业务本身就没有明显的类别结构。无监督学习的结果本质上是一个探索性产出不能像监督学习那样用一个AUC就拍板要多角度交叉验证尤其是要让懂业务的人参与判断。5. 模型选型与实战排坑5.1 算法选型速查表按业务问题直接圈定范围建模做多了我总结了一张选型速查表按几个维度快速圈定算法范围整理成表格方便大家收藏。业务问题数据规模可解释性要求推荐算法二分类/多分类千到万级高逻辑回归、决策树二分类/多分类万级以上低随机森林、XGBoost回归预测中等规模高线性回归、岭回归回归预测大规模低随机森林回归、梯度提升回归分组聚类任意规模中K-Means先标准化复杂形状聚类中等规模中DBSCAN高维特征降维高维稀疏中PCA购物篮分析交易记录高Apriori这张表只能当起点。真实项目里算法选型还要综合考虑训练时间、线上推理延迟、团队对新算法的熟悉程度。我现在的默认做法是先跑一个最简单、最可解释的模型做基线拿到一个“下限”然后用更复杂的模型尝试去突破这个下限。如果复杂模型突破不了说明问题很可能不在模型复杂度而在特征工程和数据质量这时候继续在算法上使劲纯属浪费时间。5.2 高频问题和排查思路照着这张表排错把我在项目里踩过、也帮别人排查过的坑集中整理一下。问题现象可能原因解决方向训练误差低、测试误差高过拟合或数据泄露增强正则化检查数据切分顺序训练误差和测试误差都高欠拟合或特征不足增加特征换更复杂的模型准确率很高但业务不买单样本不平衡改用精确率、召回率、AUC评估聚类结果与业务认知对不上特征未标准化、特征选择不当标准化后降维重新聚类RMSE远大于MAE存在极端离群值检查并处理目标变量的异常点第一个要细说的是数据泄露。最常见的形式是做标准化、缺失值填充、特征选择时用了全量数据的统计量然后才切分训练测试集。这样测试集的信息已经进入模型训练过程评估指标虚高上线后立刻被打回原形。解决方法是把所有需要拟合的变换都放在训练集上执行fit再对测试集只做transformsklearn的Pipeline可以把这套流程规范化地串起来建议从一开始就这么写。第二个过拟合和欠拟合的判断。看训练集和测试集的误差差距训练误差低、测试误差高是过拟合两者都高是欠拟合。过拟合的处理上面说过欠拟合则方向相反需要增加特征、降低正则化、换更复杂的模型。很多新手一上来就疯狂调参其实先定位问题是过拟合还是欠拟合方向对了才有效。第三个类别不平衡。欺诈检测、异常识别里正样本占比极低。策略分三层第一层是换评估指标用精确率、召回率、AUC代替准确率第二层是做重采样欠采样多数类或者过采样少数类过采样可以用SMOTE生成合成样本第三层是调分类阈值默认阈值是0.5但正样本极少时把阈值调低到0.3左右能显著提高召回率。具体调到多少必须结合业务能接受的误报率来定这是一个业务决策不是纯技术决策。第四个特征尺度混乱。树模型对尺度不敏感线性模型和K-Means对尺度非常敏感。如果一套代码里既有线性模型又有树模型最稳妥的做法是统一做标准化反正标准化对树模型没有负面影响却能保证线性模型和聚类模型不出幺蛾子。做挖掘建模做了这么久我最深的体会是算法模型只是工具业务理解才是真正的方向盘。同一个分类问题在风控、营销、运营场景里的评估标准完全不同脱离业务谈模型没有任何意义。我第一次独立带项目的时候也干过拿一堆算法挨个试、天天调参的事后来才明白先把数据的来龙去脉搞清楚把评估标准跟业务对齐比盲目追求AUC高零点零几重要得多。最后分享一个小技巧每次建模把数据集描述、特征列表、模型参数、评估指标、最终结论记在一个固定的本子里几个月后回看你会发现这些记录是你进步最快的教材。下一篇我会继续聊模型上线后的监控和迭代这套东西跟建模本身同样重要。
阅读完成 · 觉得有帮助?