15-Adaboost-红葡萄酒品质分类预测
1. 需求分析
用Adaboost算法对葡萄酒品质进行分类
2. 数据说明
葡萄牙北部绿酒(Vinho Verde)理化检测 + 人工感官评分数据集,2009 年 Cortez 发布于 UCI 机器学习库,同时支持回归(预测分数)、分类(划分品质等级)两大任务。
- 红葡萄酒:
winequality-red.csv,1599 行,11 特征 + 1 标签 - 白葡萄酒:
winequality-white.csv,4898 行,11 特征 + 1 标签
特征列:
| 英文名称 | 中文释义 | 业务意义 |
|---|---|---|
| fixed acidity | 固定酸度 | 酒石酸、苹果酸等不易挥发有机酸,决定基础酸度 |
| volatile acidity | 挥发性酸度 | 乙酸,过高会出现醋味,大幅降低品质 |
| citric acid | 柠檬酸 | 提升果香,少量可柔化口感 |
| residual sugar | 残糖 | 甜味来源,干型 / 甜型酒区分核心指标 |
| chlorides | 氯化物 | 含盐量,过高带来咸味、劣质口感 |
| free sulfur dioxide | 游离二氧化硫 | 抑菌抗氧化,过量产生刺鼻硫磺味 |
| total sulfur dioxide | 总二氧化硫 | 游离 + 结合 SO₂,食品安全限制指标 |
| density | 密度 | 与酒精度、含糖量强相关 |
| pH | 酸碱度 | 酸度平衡,影响稳定性与风味 |
| sulphates | 硫酸盐 | 提升葡萄酒香气 |
| alcohol | 酒精度 | 高度数通常对应更高品质评分 |
标签列:quality
人工感官打分,区间 3~8 分(无 1/2/9/10),类别极度不均衡:
- 红酒主流:5、6 分;少量 3、4、7、8
- 白酒主流:5、6 分;极少 3、4、8
分类任务常用标签转换方案
原始 quality 是有序多分类,工程上三种主流处理:
方案 1:二分类
- 好酒:quality ≥ 6 → label=1
- 差酒:quality ≤ 5 → label=0 适用:逻辑回归、SVM、二分类树、AUC/KS 评估
方案 2:三分类
- 低档:3,4
- 中档:5,6
- 高档:7,8 适用:有序分类模型(Ordinal Logistic、XGBoost 序分类)
方案 3:原始多分类(6 类:3,4,5,6,7,8)
直接以分数为 6 分类标签,样本分布极不均衡,适合类别不平衡建模(加权损失、过采样)
3. 建模
# 包 import pandas as pd from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import classification_report, roc_curve, auc from sklearn.ensemble import AdaBoostClassifier import matplotlib.pyplot as plt import joblib3.1 加载数据
# 1. 导入数据 data = pd.read_csv("./data/winequality-red.csv", sep=';') # data.info() print(data['quality'].value_counts()) # 查看标签列分布3.2 数据预处理
# 2. 数据预处理 # 2.1 提取特征和标签 x = data.iloc[:, :-1].copy() y = data['quality'].copy() # 2.2 缺失值、异常值处理(无) # 2.3 标签列转换 """ 标签列含多分类,需要转换成两类 规则:quality>5 --> good - 0; else --> bad - 1 """ y = y.map(lambda cls : 0 if cls>5 else 1) # 2.4 划分数据集 x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.2,random_state=1234)3.3 特征工程(不用)
3.4 模型训练
3.4.1 场景1:单一cart决策树
# 4. 模型训练、预测、评估 # 4.1 场景1: 单一cart决策树 estimator1 = DecisionTreeClassifier(random_state=1234) estimator1.fit(x_train, y_train) y_pre1 = estimator1.predict(x_test) print('单一决策树模型效果:\n', classification_report(y_test, y_pre1))3.4.2 场景2:Adaboost(默认参数)
# 4.2 场景2: Adaboost(默认参数) estimator2 = AdaBoostClassifier(random_state=1234) estimator2.fit(x_train, y_train) y_pre2 = estimator2.predict(x_test) print('Adaboost(默认参数)模型效果:\n', classification_report(y_test, y_pre2))3.4.3 场景3:Adaboost(网格搜索+交叉验证)
# 4.3 场景3: Adaboost(网格搜索+交叉验证) estimator3 = AdaBoostClassifier(random_state=1234) param_grid = { 'n_estimators': [50,100,150,200], 'learning_rate': [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1] } gs_estimator = GridSearchCV(estimator3, param_grid=param_grid, cv=5) gs_estimator.fit(x_train, y_train) y_pre3 = gs_estimator.predict(x_test) print('Adaboost(网格搜素+交叉验证)模型效果:\n', classification_report(y_test, y_pre2)) print('最佳参数: ', gs_estimator.best_params_) print('最佳准确率', gs_estimator.best_score_)3.5 模型预测、评估
# 用最佳参数再进行训练 estimator4 = AdaBoostClassifier(n_estimators=200, learning_rate=1, random_state=1234) estimator4.fit(x_train, y_train) y_pre4 = estimator4.predict(x_test) print('Adaboost(最佳参数)模型效果:', classification_report(y_test, y_pre4))3.6 画图
# 5. 绘图 fpr, tpr, thresholds = roc_curve(y_test, estimator4.predict_proba(x_test)[:,1]) auc_value = auc(fpr, tpr) plt.figure(figsize=(3,3)) plt.plot(fpr, tpr, label='AUC = %.2f' % auc_value) plt.plot([0,1], [0,1], 'r--') plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.legend() plt.show()3.7 模型保存
# 6. 保存模型 joblib.dump(estimator4, './model/adaboost_wine_red_model.pkl') print('模型保存成功') # 7. 模型加载 # estimator = joblib.load('./model/adaboost_wine_red_model.pkl') # x_new = # 新的数据集df # y_pre = estimator.predict(x_new) # 预测