🧪 Kaggle 农业挑战赛项目复盘:如何预测最优肥料搭配?——基于 LightGBM 的多分类模型实践
👨🌾 项目关键词:农业智能化|多分类预测|LightGBM|特征工程|MAP@3|Kaggle Playground S5E6
🧭 项目背景:为什么要做“肥料推荐”?
在现代农业中,精准施肥可以直接影响作物产量和品质,而传统的经验判断往往不够稳定。本项目基于 Kaggle 提供的结构化农业数据,目标是预测每一块地在当前条件下最合适的三种肥料(Top-3 推荐),支持农户实现更高效的投入产出比。
🧰 数据理解与特征拆解
数据概览
原始数据包含 750,000 条训练样本,字段结构如下:
字段名 | 含义 |
---|---|
Temparature | 温度(单位未知) |
Humidity | 湿度(单位未知) |
Moisture | 土壤含水量 |
Soil Type | 土壤类型(5 类) |
Crop Type | 作物类型(11 类) |
Nitrogen | 氮含量 |
Potassium | 钾含量 |
Phosphorous | 磷含量 |
Fertilizer Name | 目标变量,7 类 |
📌 特点:数据质量较好,无缺失值,类别变量数量适中,适合直接建模。
数据分布
从分布图中可以看出,7种肥料分布相对均衡,没有极端不平衡的情况:
- 14-35-14: 15.26%
- 10-26-26: 15.18%
- 17-17-17: 14.99%
- 28-28: 14.82%
- 20-20: 14.79%
- DAP: 12.65%
- Urea: 12.31%
🔍 特征工程与预处理
类别特征编码
为了让模型更好地理解非数值特征,我们对类别变量做了编码处理:
- Soil Type / Crop Type:使用
LabelEncoder
- Fertilizer Name(目标变量):使用
LabelEncoder
,方便后续进行 MAP@3 排名评估 - 尝试开发了 “智能作物编码”(Smart Crop Encoding) 方法,综合考虑作物对环境参数和营养元素的偏好
def smart_crop_encoding(feature_matrix, weights=None):
"""自定义作物编码方法"""
if weights is None:
weights = np.array([0.20,0.15,0.15,0.10,0.10,0.12,0.10,0.08])
weights /= weights.sum()
encoding_dict = {}
for crop, features in feature_matrix.items():
crop_data = features[:8]
if len(crop_data) == len(weights):
score = np.dot(crop_data, weights)
encoding_dict[crop] = score
return encoding_dict, weights
聚类特征
使用K-Means聚类算法将样本分为5类,作为额外特征:
kmeans = KMeans(n_clusters=5, random_state=42)
cluster_labels = kmeans.fit_predict(scaled_clustering_data)
clustering_df['cluster'] = cluster_labels
数值特征在EDA分析中呈现出比较均匀的分布,未做标准化处理。
我们还绘制了不同肥料与各数值特征之间的 Boxplot,用于初步判断肥料选择与土壤养分间是否存在差异,帮助模型学习更清晰的边界。
🤖 模型构建与评估:使用 LightGBM 做多分类 + Top-3 推荐
模型选型时,我选择了 LightGBM,原因是它:
- 训练速度快,支持多分类
- 默认处理缺失值,支持类别特征
- 支持
predict_proba
输出,用于 MAP@3 计算
lgb_model = LGBMClassifier(
objective='multiclass',
num_class=7,
random_state=42,
n_estimators=200,
learning_rate=0.1
)
📊 评估指标:MAP@3
传统的 accuracy 无法评估推荐类问题的 Top-k 质量,因此我采用了 MAP@3(Mean Average Precision at 3):
- 模拟现实应用场景,返回最可能的三个肥料选项
- 如果正确答案出现在 top-3 中,得分 > 0
- 正确答案越靠前,得分越高
最终结果:
MAP@3 = 0.32413
✅ 对于 7 类肥料预测任务,这个结果相对合理,意味着我们平均能在推荐的 Top-3 中找到正确答案。
🔄 模型预测与提交
在测试集上,我们同样对 Soil 和 Crop 类型进行编码,然后通过模型输出每个样本的 Top-3 概率最大标签:
# 获取 top3 预测标签
top3_preds = np.argsort(y_proba, axis=1)[:, -3:][:, ::-1]
# 转换为标签字符串
top3_labels = le_fert.inverse_transform(top3_preds.flatten()).reshape(top3_preds.shape)
# 生成提交文件
submission = pd.DataFrame({
'id': test['id'],
'Fertilizer Name': [' '.join(row) for row in top3_labels]
})
提交格式符合官方要求,每个 id 对应三个空格分隔的肥料名称,形成最终推荐列表。
✅ 项目总结:一次结构清晰、指标友好的多分类建模实践
本项目通过系统的数据分析和特征工程,构建了一个基于LightGBM的肥料推荐系统。虽然取得了不错的效果,但在实际农业应用中仍有提升空间。未来的工作可以集中在更精细的特征工程和模型优化上,以提高推荐的准确性。
模块 | 核心收获 |
---|---|
特征工程 | 类别变量编码与分布可视化对后续模型影响巨大 |
模型构建 | LightGBM 是高效稳定的 baseline,多分类任务中表现可靠 |
评估策略 | MAP@3 比传统准确率更贴合推荐型问题的场景 |
提交策略 | 输出 Top-3 推荐在农业应用场景中更具有实用性 |
🔍 后续提升方向可能包括:
- 添加交叉特征,如 Soil+Crop 的组合特征
- 探索更复杂的模型结构(如 TabNet 或深度森林)
- 使用 SHAP 分析模型的重要特征,提升解释性