备婚程序员的AI初体验:用Python从零搭建机器学习流水线
上周五晚上十一点,我一边盯着婚礼策划师发来的第17版PPT,一边在VS Code里调一个莫名其妙的ValueError: Input contains NaN。成都最近的天气闷得像锅盖,而我的心情也差不多——毕竟距离婚期只剩42天,团队又刚接了个“用AI预测用户复购”的需求,deadline压到下个月初。
作为一名在成都某中型电商公司做后端开发的程序媛,平时主要和Kafka、Redis、Spring Cloud打交道,分布式事务和CAP理论聊得比奶茶配方还熟。但这次产品经理一句“隔壁组都上推荐系统了,我们连个基础模型都没有?”直接把我和另一位前端同事推到了AI前线。
更离谱的是,他居然暗示:“你们不是会写代码吗?搞个AI应该不难吧?”(内心OS:你当我是Tony老师,剪头发顺便给你烫个卷?)
不过吐槽归吐槽,跳槽简历上要是能加一行“主导完成用户行为预测模型落地”,那可比“优化了3个微服务接口”亮眼多了。于是,我决定利用周末+下班后两小时,从零开始啃Python机器学习——毕竟,实战经验才是求职市场的硬通货。
为啥选Python?JavaScript不行吗?
有朋友问:“你现在不是天天写Node.js吗?能不能用TensorFlow.js搞?”
理论上可以,但现实很骨感。
首先,我们的训练数据来自数仓,是典型的结构化表格(用户ID、浏览时长、加购次数、历史订单等),大小约50万行。这类任务,Python生态简直碾压JS:
pandas处理百万级数据行云流水scikit-learn提供了开箱即用的分类/回归/聚类算法- Jupyter Notebook 调参可视化方便到哭
- 模型导出后还能用
Flask或FastAPI快速包装成API
而JS这边,虽然tfjs很酷,但缺乏成熟的特征工程库,调试起来像在黑暗中摸电线——哪根是火线全靠运气。更别说团队没人会JS ML,上线后运维大哥看到.js模型文件估计要报警。
所以结论很明确:生产环境的结构化数据预测,Python仍是首选工具。
我的“三步走”实战流水线
第一步:数据清洗 —— 90%的时间都在和脏数据搏斗
拿到原始数据那一刻我就知道大事不妙。字段命名全是中文拼音缩写,比如yhlx(用户类型)、gmsj(购买时间),还有NaN、空字符串、甚至"null"字符串混在一起。
import pandas as pd
import numpy as np
df = pd.read_csv("user_behavior.csv", encoding='gbk')
# 先统一处理缺失值
df.replace(['', 'null', 'NULL'], np.nan, inplace=True)
# 对数值型特征填充中位数(避免异常值影响)
num_cols = ['browse_time', 'cart_count', 'order_freq']
df[num_cols] = df[num_cols].fillna(df[num_cols].median())
# 类别型特征用众数填充
cat_cols = ['user_type', 'device']
df[cat_cols] = df[cat_cols].fillna(df[cat_cols].mode().iloc[0])
这里有个坑:千万别直接用fillna(0)!我一开始图快全填0,结果模型以为“没下单=下单0次”,但实际可能是“数据丢失”。后来改用中位数/众数,AUC提升了0.08。
小贴士:用
df.info()和df.isnull().sum()快速定位缺失情况,比肉眼扫描快10倍。
第二步:特征工程 —— 算法再牛,不如特征好
产品经理说“就预测用户会不会在30天内复购”,标签很简单:is_return=1/0。
但原始特征太粗糙。于是我做了几件事:
- 时间特征拆解:把
last_order_date转成“距离今天多少天”、“是否周末下单” - 行为聚合:计算过去7/30天的平均浏览深度、加购转化率
- 交叉特征:
device * user_type组合(发现iOS高端用户复购率明显高)
from datetime import datetime
# 假设 today 是参考日期
today = datetime(2024, 6, 1)
df['days_since_last'] = (today - pd.to_datetime(df['last_order_date'])).dt.days
# 行为比率特征
df['cart_to_browse_ratio'] = df['cart_count'] / (df['browse_time'] + 1) # +1防除零
这一步让我深刻体会到:机器学习不是调包大赛,而是特征的艺术。同样的Random Forest,加了交叉特征后F1-score从0.62飙到0.75。
第三步:模型选择与调优 —— 别一上来就上XGBoost
很多人一听说“机器学习”就冲向XGBoost/LightGBM,但作为新手,我建议从简单模型开始:
| 模型 | 训练速度 | 可解释性 | 默认效果 | 适合场景 |
|---|---|---|---|---|
| Logistic Regression | ⚡️极快 | 🔍极高 | 中等 | 基线、快速验证 |
| Random Forest | 🕒中等 | 📊中等 | 好 | 特征重要性分析 |
| XGBoost | 🐢较慢 | ❌低 | 极好 | 竞赛/追求精度 |
我先用Logistic Regression跑通全流程,确认数据管道没问题;再用Random Forest看哪些特征真有用(发现days_since_last权重最高);最后才上XGBoost冲指标。
调参也没用网格搜索(太慢),而是用Optuna做贝叶斯优化:
import optuna
from sklearn.metrics import f1_score
from xgboost import XGBClassifier
def objective(trial):
params = {
'n_estimators': trial.suggest_int('n_estimators', 100, 500),
'max_depth': trial.suggest_int('max_depth', 3, 10),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3),
'subsample': trial.suggest_float('subsample', 0.6, 1.0),
}
model = XGBClassifier(**params, random_state=42)
model.fit(X_train, y_train)
preds = model.predict(X_val)
return f1_score(y_val, preds)
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50)
50次试验后,F1达到0.79,比默认参数高了4个点。关键是——整个过程只用了2小时,不用熬夜(毕竟第二天还要试婚纱啊!)。
部署上线:从Notebook到生产API
模型效果达标后,下一步是让后端能调用。这里我踩了个大坑:别在Jupyter里直接pickle.dump()!
原因有二:
- Notebook里的变量可能包含不可序列化的对象
- 生产环境Python版本/依赖可能不同
正确做法:用joblib保存,并写独立的推理脚本。
# train.py
from joblib import dump
dump(model, 'return_predictor_v1.joblib')
# api.py
from joblib import load
from fastapi import FastAPI
app = FastAPI()
model = load('return_predictor_v1.joblib')
@app.post("/predict")
def predict(features: dict):
# 注意:这里要和训练时的特征顺序/名称完全一致!
X = pd.DataFrame([features])[FEATURE_COLS]
prob = model.predict_proba(X)[0][1]
return {"return_probability": float(prob)}
部署时用Docker打包,确保环境隔离。运维大哥看到Dockerfile里只有pip install -r requirements.txt,终于没再翻白眼。
给同样想入门AI的程序员几点建议
- 别被数学吓退:初期理解“模型输入什么、输出什么、怎么评估”比推导公式重要得多。
- 从小数据集开始:用
sklearn.datasets里的make_classification生成假数据练手,避免一上来就被TB级数据劝退。 - 工具链要趁手:我用VS Code + Python插件 + Jupyter扩展,写代码+可视化一气呵成。
- 求职时突出“解决问题”能力:面试官不关心你会不会写XGBoost,而关心你如何用AI提升业务指标。
对了,上周我们模型上线后,运营用预测高概率复购的用户做定向发券,ROI提升了22%。产品经理终于不再问“AI什么时候能替代程序员”了(笑)。
最后:技术人的浪漫
写这篇文章时,窗外成都的雨淅淅沥沥。明天要去拍婚纱照,后天要review模型监控告警规则。生活和代码一样,都是不断debug的过程——有时是NaN,有时是花艺师把捧花颜色弄错,但只要pipeline跑通,总会输出想要的结果。
如果你也在备婚、加班、学AI的路上,别焦虑。记住:每一个import sklearn的背后,都是一个不想被时代抛下的打工人。
共勉。

评论 0