一个奶爸程序员的机器学习入门血泪史
上周五晚上十一点半,终于把两个娃哄睡。老婆在客厅追剧,我蹑手蹑脚地摸到书房,打开电脑——这是属于我的“黄金两小时”。最近被领导安排了个新活儿:用机器学习优化我们产品的用户推荐策略。作为一个写了十年 CRUD 的后端老码农,说实话,一开始看到“监督学习”、“特征工程”这些词,我脑子里全是问号。
但没办法啊,深圳这地方,腾讯系公司扎堆,隔壁组都开始搞大模型微调了,咱再不学点 AI 技术,怕是要被时代淘汰。更何况,听说隔壁产品经理已经画好了 PPT,说下个版本要“基于智能算法提升 DAU 30%”……唉,又来了。
起因:爬虫数据 + 产品需求 = 我的加班之夜
事情得从去年双11说起。我们做的是一个本地生活类 App,产品团队想搞个“猜你喜欢”的模块。最初他们让我直接写个规则引擎:比如用户常点奶茶,就推奶茶店。结果上线后转化率惨不忍睹——有人只是帮同事代下单,结果被系统打上“重度奶茶爱好者”标签,天天推喜茶奈雪,烦得卸载了。
产品经理找我复盘时一脸无辜:“是不是数据不够?要不你先爬点竞品的数据?”
我差点一口老血喷出来。爬虫我是会写(毕竟当年也是靠 Scrapy 拿过实习 offer 的人),但光有数据没用啊,关键是怎么用!
于是痛定思痛,决定正经学点机器学习。目标很明确:用真实用户行为数据训练一个分类模型,预测用户对某个商户的兴趣概率。
别被术语吓到:监督学习其实就是“看图识猫”
刚开始看教程,满屏的“梯度下降”、“损失函数”、“过拟合”,头都大了。后来我发现,其实核心思想特别朴素:
给机器一堆带答案的题目(训练数据),让它自己总结规律,然后去答新题(预测)。
比如我们有 10 万条用户点击日志,每条记录包含:用户年龄、性别、历史点击品类、是否点击当前商户……最后有个 label:0(没兴趣)或 1(有兴趣)。这就是典型的二分类问题,属于监督学习。
而如果只有用户行为数据,没有 label,想让机器自己分群(比如高价值用户 vs 低频用户),那就是无监督学习,比如 K-Means 聚类。
对我们这种业务场景,监督学习更实用——毕竟产品要的是可解释、可落地的结果。
动手干:从爬虫数据到训练集
第一步,搞数据。虽然产品说“爬点竞品”,但我没真去爬(法律风险太高了!)。而是用我们自己的埋点数据 + 用户画像表,拼出一个训练集。
# 简化版特征构造(实际项目中特征工程占 80% 时间!)
import pandas as pd
# 用户行为日志(来自 Kafka 消费)
logs = pd.read_csv('user_behavior.csv')
# 用户基础信息(来自用户中心 DB)
users = pd.read_csv('user_profile.csv')
# 合并
df = logs.merge(users, on='user_id')
# 构造特征
df['is_weekend'] = df['timestamp'].dt.weekday >= 5
df['click_count_7d'] = df.groupby('user_id')['click'].transform(lambda x: x.rolling(7).sum())
df['fav_category'] = df.groupby('user_id')['category'].transform(lambda x: x.mode()[0] if len(x) > 0 else 'unknown')
# 标签:如果用户点击后 24h 内下单,则 label=1
df['label'] = (df['order_within_24h'] == True).astype(int)
# 最终特征列
feature_cols = ['age', 'gender', 'click_count_7d', 'is_weekend', 'fav_category']
X = pd.get_dummies(df[feature_cols]) # 类别变量 one-hot
y = df['label']
💡 坑点提醒:类别特征别忘做 One-Hot 或 Embedding!我第一次直接把“fav_category”当字符串喂给模型,sklearn 直接报错,当时真的想砸键盘。
算法选型:别一上来就搞神经网络
很多新手(包括我)容易犯一个错误:觉得“AI = 深度学习”。其实对于结构化数据(表格数据),树模型往往更香。
我试了三种主流算法:
| 算法 | 训练速度 | 可解释性 | 对特征缩放敏感 | 适合场景 |
|---|---|---|---|---|
| Logistic Regression | 快 | 高(系数可读) | 是 | 特征少、线性关系强 |
| Random Forest | 中 | 中(feature importance) | 否 | 中小数据集、防过拟合 |
| XGBoost | 快(支持并行) | 中 | 否 | 推荐!Kaggle 常胜将军 |
实测下来,XGBoost 在我们的 50 万样本数据集上,AUC 达到了 0.87,比逻辑回归高了近 0.1。而且它自带正则化,不容易过拟合——对我们这种特征工程还不完善的小团队太友好了。
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = XGBClassifier(
n_estimators=200,
max_depth=6,
learning_rate=0.1,
subsample=0.8,
random_state=42
)
model.fit(X_train, y_train)
# 评估
from sklearn.metrics import roc_auc_score
y_pred = model.predict_proba(X_test)[:, 1]
print(f"AUC: {roc_auc_score(y_test, y_pred):.4f}") # 输出:AUC: 0.8721
产品怎么用?别让模型躺在 Jupyter 里吃灰
模型效果不错,但产品经理关心的是:“怎么上线?能提升多少 GMV?”
于是我们做了三件事:
- 封装成微服务:用 Flask 包一层,提供
/predict接口,传入用户 ID 和商户 ID,返回兴趣分。 - AB 测试:5% 流量走新模型,95% 走旧规则。监控点击率、转化率、停留时长。
- 可解释性兜底:用 SHAP 值告诉运营“为什么推这家店”,避免出现“给素食主义者推烤肉”的社死场面。
上线两周后,数据来了:推荐点击率提升 22%,下单转化率提升 15%。产品经理终于没再提“爬竞品数据”了(笑)。
给 fellow 奶爸/妈程序员的建议
- 别追求一步到位:先跑通 end-to-end 流程(数据 → 训练 → 预测 → 上线),再优化细节。
- 特征比算法重要:花 80% 时间搞特征工程,20% 调参。比如加个“用户最近 1 小时是否搜索过关键词”,可能比换模型提升更大。
- 善用 AutoML 工具:像 H2O、Auto-sklearn 能快速 baseline,省下深夜陪娃后那点可怜的学习时间。
- 和产品对齐指标:别沉迷 AUC,业务关心的是 ROI。提前定义好 success metric,避免白干。
现在每天晚上,等娃睡了,我还会继续啃《Hands-On Machine Learning》。虽然进度慢(经常看到一半被娃哭声打断),但至少不再是那个听到“embedding”就发懵的 CRUD Boy 了。
说到底,机器学习没那么玄乎。它就是一个工具,就像我们用 Redis 缓存、用 Kafka 解耦一样。关键不是算法多 fancy,而是能不能解决产品的真实问题。
下次如果产品经理再说“我们要搞 AI 驱动增长”,你可以淡定回一句:“行,先把埋点补全,再给我一周时间跑个 baseline。”
——然后默默打开电脑,继续你的深夜 coding。毕竟,深圳的夜,属于不甘心被淘汰的打工人。

评论 0