去年帮一个电商团队做用户数据分析时,老板丢给我一份300万行的订单表,问了我四个问题:哪些商品适合放一起推荐、哪些用户未来会复购、复购用户大概能贡献多少销售额、以及用户能不能分群运营。这四个问题恰好对应了数据分析里最常用的四类算法:关联规则、分类、回归、聚类。很多刚接触大数据分析的同学把这四类算法当成四个独立的知识点去学,但实际业务里它们经常出现在同一条分析链路里,结果要互相验证、互相补充。这篇文章我就用这份订单数据做例子,把关联规则、分类、回归、聚类的完整流程串起来讲一遍,包括参数怎么调、代码怎么写、结果怎么解释、坑在哪里。适合正在做数据分析项目、准备面试、或者刚入门机器学习想要落地业务场景的读者。
1. 业务问题与数据准备:一份订单表能挖出四种价值
1.1 四个业务问题对应四种算法
先把业务问题翻译成算法问题,这一步很多人会跳过,但恰恰是整个项目最关键的环节。老板问的四个问题,本质上对应的是四种不同的目标变量和学习方式。
- 哪些商品适合捆绑推荐:没有标签,纯粹从订单明细里挖掘商品之间的共现关系,这是典型的无监督关联规则问题,用Apriori或FP-Growth。
- 哪些用户未来会复购:有明确的二分类标签(复购/不复购),过去的行为特征做自变量,属于有监督分类问题,可以用逻辑回归、随机森林、XGBoost。
- 复购用户大概消费多少钱:标签是连续型金额变量,属于回归问题,可以用线性回归、岭回归、随机森林回归。
- 用户能不能分群运营:同样没有标签,基于用户行为特征做无监督聚类,最常用K-Means和层次聚类。
这四类方法不是孤立的。关联规则可以告诉你"什么商品组合值得推广",聚类可以告诉你"哪一类用户最容易接受这种组合",分类和回归可以帮你把"每个用户的复购概率和消费金额"算出来,最后形成一个从选品到人群再到预估收益的完整闭环。所以我在做项目时,从来不会只跑一个模型交差,而是把这四类方法的结果放在一起看。
1.2 数据清洗与字段工程
原始订单表字段大致包括:order_id、user_id、item_id、category、quantity、price、order_amount、order_date,以及用户维度信息user_age、user_gender、user_register_days、visit_count_last_90d、purchase_count_last_90d。
拿到数据的第一步不是建模,而是做数据清洗。我一般按这个顺序处理:
- 缺失值:user_age缺失率大概12%,我选择用中位数填充,而不是均值。因为年龄往往有偏态分布,均值会被少数高龄用户拉高,中位数更稳健。
- 异常值:把order_amount小于等于0的订单剔除,这些通常是退款、测试订单或者系统异常;quantity小于等于0的记录同理。
- 时间字段:把order_date解析成datetime类型,提取出月份、星期几、是否节假日等维度特征。电商数据的季节性很强,这些时间特征在回归模型里往往比很多用户属性更重要。
- 类别字段:中文商品类别不能直接喂给模型,要做one-hot编码或者标签编码。如果类别数量太多,就先做频次筛选,只保留TOP 50的类别。
- 金额字段:order_amount做log1p变换。这一点放在回归部分详细讲,但在数据准备阶段就要先把变换列生成好。
1.3 为什么先按不同粒度拆成多张分析表
一份订单表不能直接喂给所有算法,因为四种算法对数据粒度的要求完全不同。关联规则需要的是"订单-商品"的交易明细,通常每一行是一个用户购物篮里的一个商品;分类和回归需要的是"用户"级别的特征,每个用户一行;聚类也需要用户级别的行为特征矩阵。
所以我在数据准备阶段会拆出三张表:
- order_item_table:字段是order_id、item_id、category,用于关联规则。
- user_feature_table:字段是user_id、各种行为统计特征、人口属性、标签列,用于分类和回归。
- user_behavior_matrix:只有特征、没有标签,标准化后用于聚类。
同样一份原始数据,因为目标不同,组织方式完全不同。很多人拿到数据就急着建模,结果用订单粒度做用户分类,导致同一个用户出现多次,训练集和测试集之间信息泄漏。先拆表再建模,能规避掉一大批这类问题。
2. 关联规则实战:从购物篮里挖出"一起出现"的商品组合
2.1 支持度、置信度、提升度到底在算什么
关联规则最核心的三个指标是支持度、置信度和提升度。很多教程只是把公式列出来,我这里用一个具体例子说明它们到底在算什么。
假设有100笔订单,其中牛奶出现在40笔里,面包出现在30笔里,牛奶和面包同时出现在10笔里。
- 支持度:P(牛奶∩面包) = 10 / 100 = 0.1。支持度衡量的是"这个组合在全部订单里占多大比例",解决的是"这个规则有没有足够的样本支撑"。支持度太低,规则就是小样本噪声,没有推广价值。
- 置信度:P(面包|牛奶) = 10 / 40 = 0.25。置信度衡量的是"买了牛奶的订单里,有多少比例也买了面包",解决的是"这个规则在A发生的条件下有多大概率成立"。
- 提升度:P(面包|牛奶) / P(面包) = 0.25 / 0.3 ≈ 0.83。提升度小于1,说明买了牛奶反而降低了买面包的概率,牛奶和面包是负相关,这条规则没有用。提升度大于1才有正向关联的意义,而且越大说明关联越强。
所以看规则时不要只看置信度。置信度0.8的"牛奶→面包"可能只是因为面包本身销量极高,P(面包)就是0.8,那这条规则纯属废话。必须把提升度大于1作为硬性筛选条件。
2.2 最小支持度和置信度阈值怎么定
参数设置是关联规则最容易纠结的地方。我的经验是不要一上来就追求"最优参数",而是从小到大逐步试探。
- 最小支持度:先从0.05开始跑,如果频繁项集数量爆炸(比如上万条),就抬高到0.1;如果结果太少,就降低到0.02或0.01。具体阈值取决于数据量,300万笔订单里支持度0.01已经对应3万笔订单,完全是可靠的样本量。
- 最小置信度:通常从0.5起步。置信度太低,规则没有业务价值;太高(比如0.9)又会漏掉很多有意义的组合。
- 提升度:强制大于1是底线,实际项目中我通常只保留提升度大于1.5的规则,因为提升度接近1的规则往往经不起时间维度的验证。
另外建议对频繁项集的长度做限制,max_len=3即可。2项集和3项集最容易做业务解释,4项以上组合往往是噪音。
2.3 Apriori实现与结果解读
以Python为例,用mlxtend库可以非常简洁地实现Apriori。首先要将订单数据转换成事务列表,每一行是一个订单内购买的商品集合。
import pandas as pd from mlxtend.preprocessing import TransactionEncoder from mlxtend.frequent_patterns import apriori, association_rules # transactions: list of lists,每个子列表是一个订单的商品集合 te = TransactionEncoder() te_ary = te.fit(transactions).transform(transactions) df = pd.DataFrame(te_ary, columns=te.columns_) # 挖掘频繁项集 frequent_itemsets = apriori(df, min_support=0.02, use_colnames=True, max_len=3) # 生成关联规则,按提升度筛选 rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1.2) rules = rules.sort_values("lift", ascending=False) print(rules.head(20))结果表里每行是一条规则,关键列是antecedents、consequents、support、confidence、lift。我拿到结果后的第一件事不是看lift最高的,而是看support相对较高的那些规则。lift极高但support只有0.001的规则,往往只是极少数订单的巧合,业务上没法落地。我会在代码里加一层筛选,比如support大于0.02、confidence大于0.3、lift大于1.5,然后再人工看一遍。
结果解读举例:假设发现"手机壳→钢化膜"的提升度是2.8,支持度0.04、置信度0.42,意味着在所有订单中4%的订单同时买了这两样,买手机壳的订单里有42%也买了钢化膜。这种规则可以直接给运营做捆绑套餐参考。
2.4 关联规则的坑:商品粒度和季节干扰
我用关联规则踩过最多的坑有三个。
第一个坑是商品粒度问题。直接用item_id挖,会挖出一堆"赠品A→电池B"这种完全没有运营意义的规则。我的做法是先在category粒度上挖一轮,找到大类目之间的强关联,再从中选取重点类目下钻到子类甚至单品。这样既控制了频繁项集规模,又保证了业务可解释性。
第二个坑是季节性干扰。夏天挖出的"防晒霜→冰袖"提升度很高,看起来很漂亮,但到了秋冬季节这条规则完全不成立。解决方法是按月份或者按季节分别建模,然后对比同一规则在不同时间段的表现。如果一条规则只在某个月显著,就不能作为全年运营策略。
第三个坑是因果误读。关联规则只能说明"一起出现",不能说明"谁导致谁"。比如"婴儿纸尿裤→啤酒"这种野史级规则,即使数据上支撑也没有任何因果关系。给业务方出报告时,必须把"相关"和"因果"的边界讲清楚,否则很容易做出错误决策。
3. 分类实战:预测用户是否再次购买
3.1 先定义"复购"这个标签
分类建模的第一步是定义标签,这一步决定了整个模型的上限。我的定义是:以当前时间点为基准,用户在之前90天的行为特征做自变量,未来30天内是否下单作为标签y。
这里要特别注意时间窗口的划分,防止数据泄漏。比如用户A在1月1日到3月31日之间有活跃行为,那么在4月1日到4月30日之间是否下单,这个标签才能用。如果我把"用户是否领券并核销"这种未来信息放进特征,模型AUC会虚高得离谱,但上了线就会原形毕露。
数据里正负样本比例大约1比5,也就是大约17%的用户在观察窗口内复购。这个比例不算特别失衡,但也不能直接用准确率来评估。
3.2 逻辑回归先打底:可解释性强、上线快
做分类我几乎不会跳过逻辑回归这个基线模型。原因很简单:逻辑回归可解释性强、训练快、稳定,而且线上部署成本极低。在大数据项目里,很多时候业务方要的不是最高的AUC,而是"这个模型为什么判定这个用户会复购"。
from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import roc_auc_score, classification_report X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42, stratify=y ) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) clf = LogisticRegression(max_iter=1000, class_weight="balanced") clf.fit(X_train, y_train) y_pred_proba = clf.predict_proba(X_test)[:, 1] print("AUC:", roc_auc_score(y_test, y_pred_proba)) print(classification_report(y_test, clf.predict(X_test)))class_weight="balanced"是处理正负样本比例不均最简单的方式,相当于给少数类更高的惩罚权重。逻辑回归自带正则化,默认L2,对于特征之间存在多重共线性的情况,L2正则能压住系数方差,这也是我选择逻辑回归而不是朴素线性分类器的原因之一。
跑完逻辑回归后,我习惯去看每个特征的系数。比如visit_count_last_90d系数为正,purchase_count_last_90d系数为正,说明最近活跃度越高复购概率越大;user_age系数接近0,说明年龄对复购的线性贡献不大。这些信息可以直接用来跟业务方沟通。
3.3 随机森林和XGBoost:什么时候换复杂模型
逻辑回归AUC跑出来0.72,作为一个基线已经不错。但业务方希望再压一压,这时我才会考虑树模型。
from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier( n_estimators=200, max_depth=8, min_samples_leaf=50, class_weight="balanced", n_jobs=-1, random_state=42 ) rf.fit(X_train, y_train) y_pred_proba_rf = rf.predict_proba(X_test)[:, 1] print("Random Forest AUC:", roc_auc_score(y_test, y_pred_proba_rf))随机森林的AUC到了0.75,比逻辑回归高3个点。这3个点值得换模型吗?要看业务场景。如果复购预测是给运营发优惠券用的,每多召回一批复购用户都对应真金白银的成本,那3个点的AUC提升可能带来明显的ROI变化。如果只是做BI看板上的一个参考指标,逻辑回归完全够用。
XGBoost在样本量大、特征交互复杂的情况下往往还能再提一两个点,但代价是调参成本和过拟合风险都要上来。我用XGBoost时重点盯三个参数:learning_rate调到0.01-0.05之间防止过拟合;max_depth不要超过6;用early_stopping_rounds控制迭代次数。线性模型、随机森林、XGBoost三者要横向对比,而不是默认复杂模型一定最好。
3.4 分类评估指标:准确率在这个场景里会骗人
正负样本1比5的问题,直接看准确率会得到很有误导性的结论。假如模型把所有用户都预测成"不复购",准确率也有83%,看起来很高,但复购用户一个都没找出来,这个模型对业务毫无价值。
所以分类评估我主要看三个指标:
- AUC:不依赖阈值,衡量模型把正样本排到负样本前面的概率。0.75意味着75%的概率能把复购用户和未复购用户区分开。
- 精确率和召回率:这是一对矛盾。精确率高说明看中的用户多数真的会复购;召回率高说明大部分复购用户被找出来了。
- 业务成本决定阈值:我不直接用默认的0.5阈值,而是基于业务成本去卡。比如给预测概率Top 20%的用户发优惠券,假设优惠券成本每张5元,即使转化率只有10%,只要平均客单价利润够高就能回本,那这个成本结构下就可以在这个阈值上下手。
3.5 踩过的坑:特征泄漏和时间漂移
这一节分享两个我在分类项目里真实踩过的坑,都是那种"看AUC很漂亮,上线就翻车"的典型。
第一个是特征泄漏。早期做复购预测时,我把"是否领取优惠券并核销"放进特征矩阵,AUC直接到了0.91。后来仔细检查才发现,核销行为本身发生在标签窗口内,等于是用未来信息预测未来,当然准。这种问题在代码里极难发现,因为特征名看起来很合理。我的解决方法是建立一份特征清单,字段后面标注数据产生的日期,凡是产生时间晚于标签定义时间点的字段一律剔除。
第二个是时间漂移。用去年3月到5月的数据训练,测试集也是同期数据,AUC稳定在0.75。但用同样的模型预测今年同期数据,AUC掉到0.65。原因很简单,用户的消费习惯、平台的活动节奏都在变。对这类问题没有一劳永逸的办法,最实用的就是建立定时重训机制,每月或每季度用最新数据重新拟合一次模型,同时监控特征分布漂移。
4. 回归实战:预测用户未来90天消费金额
4.1 回归和分类的差异:标签形态不同,建模逻辑也不同
复购预测只能回答"用户会不会买",业务方接下来一定还会问"如果买,大概买多少"。这时候就要上回归模型。两者最大的区别是标签的形态:分类的y是离散的0/1,回归的y是连续值,而且消费金额这类标签往往严重右偏,少数高消费用户拖出长长的尾巴。
我见过很多人不处理这个分布,直接把原始金额丢给线性回归,结果模型预测值全部向均值附近压缩,高价值用户被严重低估。解决办法是对标签做log1p变换。
import numpy as np df["amount_log"] = np.log1p(df["order_amount_sum"])log1p就是log(1+x),好处是x等于0时结果也是0,不会出现log0的报错。训练完成后做预测,再用expm1还原成真实金额。这个技巧在消费金额、收入、房价这类长尾目标的回归任务里几乎是必备操作。
4.2 特征工程:用RFM思路构造行为特征
回归模型的特征和分类模型有重合但不能完全一样。我做消费金额预测时,会重点构造RFM体系里的特征:
- Recency:用户最后一次购买距今天数,反映新鲜度。
- Frequency:过去90天购买次数,反映活跃度。
- Monetary:过去90天消费总额、平均客单价、最大单笔金额。
- 品类广度:过去90天购买了多少个二级品类,反映用户需求宽度。
- 访问行为:过去90天访问次数、加购次数、收藏次数。
- 人口属性:注册天数、年龄、性别。
代码示意:
user_feature = df.groupby("user_id").agg( last_purchase_days=lambda x: (pd.Timestamp("2024-04-01") - x.max()).days, purchase_count=("order_id", "count"), amount_sum=("order_amount", "sum"), amount_mean=("order_amount", "mean"), category_count=("category", "nunique") ).reset_index()这些特征在做聚合时要小心,groupby之后的count、sum、mean这些统计量对缺失值非常敏感,需要在清洗阶段处理好。
4.3 岭回归和随机森林回归的对比取舍
回归模型我通常同时跑几个做对比。线性回归的一个问题是特征之间如果有多重共线性,系数估计会很不稳定。岭回归通过加L2正则化把系数往0方向压缩,牺牲一点偏差换来更小的方差,尤其在特征数量多、相关性高的时候表现稳定。
from sklearn.linear_model import Ridge from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score # 岭回归 ridge = Ridge(alpha=1.0) ridge.fit(X_train, y_train) y_pred_ridge = ridge.predict(X_test) # 随机森林回归 rfr = RandomForestRegressor( n_estimators=200, max_depth=10, min_samples_leaf=20, n_jobs=-1, random_state=42 ) rfr.fit(X_train, y_train) y_pred_rfr = rfr.predict(X_test)评估回归模型我不只看R²,还会看MAE和RMSE。MAE是每个预测值和真实值差的绝对值的平均,RMSE会放大偏差大的样本,所以RMSE大于MAE越多,说明存在少数预测偏差极大的样本。在消费金额预测里,RMSE高往往是那几个高消费用户造成的,模型学不到他们的规律,这很正常。
实际跑下来,岭回归的R²大约0.35,随机森林回归R²约0.52。如果你只看R²,会觉得模型很差,但在用户消费行为预测里R²超过0.3就已经有实用价值了,因为人的消费行为本身就包含大量随机性。重要的是看排序能力,也就是预测值能不能把高消费用户排到前面,给运营圈定Top 20%高潜人群。
4.4 回归的坑:预测值被压缩和过拟合
回归任务里我最常遇到的问题是"预测值被压缩"。原始金额经过log变换后,模型在log空间里做均方误差最小化,预测值天然会向均值回归。还原到原始金额后,高消费用户的预测值普遍偏低,低消费用户反而偏高。
如果业务需要的是精准金额,这个问题无解,只能靠更多特征和更复杂的模型去逼近。但大多数场景其实只需要排序,比如"给未来90天预计消费最高的前20%用户发高价值权益",这时候压缩不影响排序,直接按预测值从高到低截断即可。我一般会明确告诉业务方这个模型适合做排序而不是做财务预算,避免后续扯皮。
过拟合在回归里也有体现。随机森林如果不限制max_depth和min_samples_leaf,训练集R²能到0.95,测试集只有0.4。我习惯从max_depth=6、min_samples_leaf=30开始调,宁可在训练集上舍弃一点表现,也要保住测试集的稳定性。
5. 聚类实战:用户分群与标签画像
5.1 聚类前必须做的预处理:标准化和降维
聚类和前面三类方法最大的不同在于,它没有标签可以用来验证"对错",所以每一步选择都要更加谨慎。
K-Means基于欧氏距离计算样本相似度,如果特征量纲不一致,比如visit_count的数值是几百、user_age是几十、amount是几千,距离计算会被量纲大的特征主导。所以聚类前必须做标准化。我习惯用StandardScaler,把每个特征转成均值为0、方差为1的分布。
标准化之后还有一个问题:如果特征维度太多,比如做了one-hot编码后维度到了200以上,K-Means在高维空间里距离区分度会下降,这就是常说的维度灾难。我的做法是先做PCA降维到20-50个主成分,保留90%以上的方差,再去做K-Means。PCA降维不光是减少计算量,更重要的是把噪声特征过滤掉,让聚类结果更稳定。
5.2 K-Means的K值选择:肘部法则加轮廓系数
K-Means最让人头疼的是K怎么选。我用的方法有两种,结合起来判断。
第一种是肘部法则。对不同的K值分别计算SSE(簇内平方误差和),然后画折线图。随着K增大,SSE必然下降,但下降速率会越来越慢。找到那个"拐点",也就是下降速度突然变得平缓的K值,就是合理的聚类数。
第二种是轮廓系数。轮廓系数衡量样本与自己簇内样本的相似度以及与其他簇样本的差异度,取值在-1到1之间,越大说明聚类效果越好。轮廓系数不会只跟着K单调变化,更适合做参考。
from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score sse = [] silhouette_scores = [] K_range = range(2, 11) for k in K_range: km = KMeans(n_clusters=k, random_state=42, n_init=10) labels = km.fit_predict(X_pca) sse.append(km.inertia_) silhouette_scores.append(silhouette_score(X_pca, labels))从我的项目经验看,业务场景下K取3到5个簇最合适。K太大,每个簇的人群特征趋于碎片化,运营没法为每个簇单独设计策略;K太小,簇内差异太大,画像标签做出来没有区分度。最终我选了K=4。
5.3 层次聚类Python实现:树状图辅助定K
K-Means依赖初始质心的选择,同一份数据跑几次结果可能有波动。如果对K值拿不准,我会用层次聚类辅助判断。层次聚类不要求预先指定K,而是生成一棵树状图,你可以在任意高度"切一刀"得到对应数量的聚类。
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster from scipy.spatial.distance import pdist import matplotlib.pyplot as plt # 先计算距离矩阵,再用Ward方法做层次聚类 Z = linkage(X_pca, method="ward") # 画树状图 dendrogram(Z, truncate_mode="level", p=5) plt.show() # 在树状图上按距离阈值切分成4个簇 labels = fcluster(Z, t=4, criterion="maxclust")层次聚类的时间复杂度比较高,样本量几万以内还能接受,到了百万级就很吃力。所以我的用法是:在随机抽样的2万条数据上跑层次聚类,用树状图确定K,然后用K-Means在全量数据上跑。这样既利用了层次聚类直观的优点,又避开了它的性能瓶颈。
5.4 聚类结果解读:给每个簇起个能听懂的名字
聚类做完必须回到业务解释,否则就是一堆没有意义的编号。我会对每个簇的标准化中心向量做还原,统计每个簇在各特征上的均值,然后给它们起名字。
在这个项目里,四个簇的特征非常清晰:
- 簇0:购买次数多、金额高、访问频繁、注册时间长,命名为"高活跃高价值用户",占比约12%。
- 簇1:购买次数中等、客单价中低、品类数较多、注册时间短,命名为"成长型新客",占比约35%。
- 簇2:购买次数少、最近购买距今很久、访问次数少,命名为"沉睡用户",占比约28%。
- 簇3:购买频次低但单笔金额高、品类窄、复购不稳定,命名为"高客单低频用户",占比约25%。
这四类用户对应的运营策略完全不同,高活跃高价值用户要维护忠诚度、给专属权益;成长型新客要做品类交叉推荐;沉睡用户要靠优惠券唤醒;高客单低频用户要提升复购频次。
聚类结果还可以反过来帮前面的模型做特征工程,比如把"所属簇"作为一个特征喂给分类和回归模型。簇标签相当于把无监督学习的结果变成了有监督模型的输入变量,实践中通常能带来一到两个点的AUC提升。
6. 全流程串联:从数据到业务的最后一公里
6.1 三种算法结果如何互相印证
分开跑完四种算法只是第一步,真正的价值在于让它们互相验证。我在最终交付报告时是这样组织的:
关联规则挖出了"高端手机+保护壳+快充头"的高提升度组合。通过聚类发现这种组合主要集中在簇3"高客单低频用户"里,那么运营策略就不是面向全量用户推送,而是精准针对簇3用户设计套餐。分类模型筛选出复购概率Top 20%的用户,回归模型在这些人里再叠加一个"未来90天消费金额排序",最终选出来的用户群从业务上和簇0"高活跃高价值用户"高度重合,说明两类模型从不同角度捕捉到了同一批高价值人群。
这就是全流程联动的意义。单看关联规则,你只知道商品组合;单看聚类,你只知道人群差异;单看分类和回归,你知道谁会买、买多少,但不知道怎么去推广。四者联合起来,才能在正确的时间、用正确的商品、触达正确的人。
6.2 工程化落地的几点经验
代码层面,数据分析和建模如果用Jupyter Notebook一张张跑,到了交付阶段会很痛苦。我现在的习惯是把数据清洗、特征工程、模型训练分别封装成Python函数,用统一的配置文件管理参数。模型训练完用joblib保存,每个模型附带一份特征列表和当时的评估指标,方便回溯。
import joblib # 保存模型 joblib.dump(rfr, "models/amount_rfr.pkl") joblib.dump(scaler, "models/scaler.pkl") joblib.dump(pca, "models/pca.pkl")参数实验一定要留记录。我在项目里用了一个简单的CSV文件记录每次实验的模型名称、特征版本、参数组合、AUC或R²,这样过两周回来还能知道"这个结果是怎么跑出来的"。这个习惯帮我避免过很多次重复调参。
6.3 最后再分享两句大实话
这套流程做完,我最深的体会是:算法不是越复杂越好,业务解释比精确数字重要。逻辑回归AUC比XGBoost低两个点,但业务方拿着系数表能自己讲清楚"活跃度影响最大",这就是好模型。回归R²只有0.4,但只要能把高价值用户排到前面,业务目标就能达成。
另外一定要盯着上线后的数据。模型不是交完报告就结束的,用户行为会漂移,同一套规则过半年可能完全失效。定期监控特征分布、模型效果,该重训就重训,这是一套完整流程里真正能长期产生价值的环节。