基于随机森林回归预测葡萄酒质量

基于随机森林回归预测葡萄酒质量

基于随机森林回归预测葡萄酒质量

1.作者介绍

朱亚彬, 男 ,西安工程大学电子信息学院 , 2024级研究生

研究方向:任务卸载与边缘计算

电子邮件:2292036787@qq.com

王晓睿,男,西安工程大学电子信息学院,2024级研究生,张宏伟人工智能课题组

研究方向:智能视觉检测与工业自动化技术

电子邮件:3234002295@qq.com

2.随机森林算法与数据集介绍

2.1定义

随机森林回归(Random Forest Regression)是一种基于集成学习的回归算法,通过组合多个决策树来提高预测的准确性和稳定性。

2.2核心思想

随机森林回归通过构建多棵决策树,并将它们的预测结果进行平均(或加权平均)来得到最终的回归结果。每棵决策树在训练时使用随机抽样的数据和特征,从而减少过拟合的风险。

2.3主要步骤

数据采样(Bootstrap Sampling) :从训练集中随机抽取样本(有放回抽样),形成多个子集。每个子集用于训练一棵决策树。
特征随机选择 :在每棵树的节点分裂时,随机选择一部分特征(而不是所有特征)来寻找最佳分割点。这增加了模型的多样性。
构建决策树 :对每个子集数据,构建一棵决策树。树的生长通常不进行剪枝,直到达到最大深度或节点中的样本数小于某个阈值。
集成预测 :对于回归问题,将所有树的预测结果取平均值,作为最终的预测值。

(1)随机选择一个样本子集作为该决策树的训练集。

(2)随机选择一部分特征(总特征数的平方根)作为该决策树的特征集。

(3)基于训练集和特征集构建决策树,直到达到预定的叶子节点数或无法分割为止。

(4)重复以上步骤,建立多颗决策树。

(5)对于一个新的样本,将它输入到每棵决策树中,得到多个预测结果。

(6)对多个预测结果进行平均,得到最终的预测结果。

算法公式基于决策树回归模型,每个预测树的预测函数为:

多棵决策树的预测函数可以表示为:

该部分参考链接:https://blog.csdn.net/m0_61399808/article/details/130733650

2.4数据集介绍

名称 :Wine Quality Dataset(葡萄酒质量数据集):
数据集地址https://archive.ics.uci.edu/dataset/186/wine+quality

数据集包含红葡萄酒和白葡萄酒两个子集(分别有1599和4898个样本)。每个样本有11个特征,包括固定酸度、挥发性酸度、柠檬酸、残糖、氯化物等。目标是一个回归任务,预测葡萄酒的质量评分(0到10分)。本次实验使用的是红葡萄酒数据集进行测试。

3.算法实现

基于红酒质量数据集,使用随机森林回归模型进行质量预测。主要步骤包括:数据加载与探索、数据可视化(散点图、热力图、直方图等)、数据预处理(标准化、划分训练/测试集)、模型训练与优化(随机森林回归 + 超参数搜索)、模型评估(MSE、R²、混淆矩阵、准确率)、特征重要性分析、模型保存与加载。

3.1数据加载与探索

(1)程序从指定路径加载红酒质量数据集:数据文件为 CSV 格式,分隔符为 ;使用 pandas.read_csv 读取数据,编码格式为 utf-8。

(2)数据探索。

3.2数据可视化

程序通过多个图表展示数据特征与质量之间的关系。

(1)特征与质量的散点图

(2)相关性热力图

(3)不同品质红酒的分布

(4)不同品质的酒精含量直方图

3.3数据预处理(标准化、划分训练/测试集)

(1)特征和标签划分:将数据集分为特征(X)和目标变量(y),其中 y 是红酒的质量评分。

(2)划分训练集和测试集:使用 train_test_split 将数据划分为训练集(80%)和测试集(20%)。

random_state=42 确保结果可重复,stratify=y 保持训练集和测试集中 y 的分布一致。

(3)数据标准化

使用 StandardScaler 对特征进行标准化(均值为 0,方差为 1)。在训练集上拟合并转换,在测试集上仅转换。

3.4模型训练与优化(随机森林回归 + 超参数搜索)

创建随机森林回归模型,设置 100 棵树,随机种子为 42。

使用 10 折交叉验证评估模型在训练集上的性能。

计算均方误差(MSE)和 R² 分数。neg_mean_squared_error 返回负值,故取反。

使用 GridSearchCV 搜索最佳超参数组合。

搜索的参数包括 max_features(特征选择方式)和 max_depth(树的最大深度)。

同样采用 10 折交叉验证。

重新训练模型:使用搜索到的最佳参数重新训练模型。

3.5模型评估(MSE、R²、混淆矩阵、准确率)



3.6特征重要性分析

3.7模型保存与加载

4.结果分析

(1)图表可视化

图中的横轴表示的是真实品质,纵坐标表示的是预测品质。对角线表示预测值与完全值完全一样,品质为6时准确率最高。

从混淆矩阵中可以看出,品质为6,7的时候预测的准确率最高。

(2)MSE,准确率等评估指标

MSE的值越小,模型的预测性能越好。R²的值范围在0到1之间。R²值越接近1,表示模型对目标变量的解释能力越强,模型的预测性能越好。结果表明模型在测试集上的性能超过了训练集。

图为特征重要性的排列,从图中可以看出,alochol的特征是最重要的。表明alochol的含量越高,葡萄酒的质量品质越高。

5.完整代码

python 复制代码
# 导入必要的库
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import make_pipeline
from sklearn.metrics import mean_squared_error, r2_score, confusion_matrix
from sklearn.model_selection import GridSearchCV
import joblib

# 设置中文字体
plt.rcParams["font.sans-serif"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False

# #加载数据
# dataset_url = 'wine+quality/winequality-red.csv'
# data = pd.read_csv(dataset_url)
# #查看数据的前五行
# print( data.head() )

# 加载数据
dataset_url = 'wine+quality/winequality-red.csv'
data = pd.read_csv(dataset_url, sep=';', encoding="utf-8")

# 查看数据的基本信息
print(data.head())
print(data.shape)
print(data.describe())


# 绘制特征与质量的关系图
plt.figure(figsize=(12, 5))
plt.subplot(121)
sns.scatterplot(x='volatile acidity', y='quality', data=data)
plt.title('Volatile Acidity vs Quality')
plt.subplot(122)
sns.scatterplot(x='alcohol', y='quality', data=data)
plt.title('Alcohol vs Quality')
plt.savefig("results/quality.png", dpi=300)
plt.show()

# 绘制相关性热力图
correlation = data.corr()
plt.figure(figsize=(12, 10))
sns.heatmap(correlation, annot=True)
plt.title("Correlation Matrix")
plt.savefig("results/Correlation_Matrix.png", dpi=400)
plt.show()

# 绘制不同品质的红酒分布
sns.catplot(data=data, x="quality", kind='count')
plt.title('不同品质的红酒的分布')
plt.xlabel('品质')
plt.ylabel('数量')
plt.show()

# 提取品质为 4、5、6、7 的数据
data_quality_4 = data.loc[data["quality"] == 4, :]
data_quality_5 = data.loc[data["quality"] == 5, :]
data_quality_6 = data.loc[data["quality"] == 6, :]
data_quality_7 = data.loc[data["quality"] == 7, :]

# 绘制不同品质的酒精含量直方图
plt.figure(figsize=(9, 7), dpi=80)
plt.subplot(2, 2, 1)
plt.hist(data_quality_4["alcohol"], bins=50)
plt.xlabel("酒精含量")
plt.ylabel("数量")
plt.title("品质为4的酒精度数量直方图")

plt.subplot(2, 2, 2)
plt.hist(data_quality_5["alcohol"], bins=50)
plt.xlabel("酒精含量")
plt.ylabel("数量")
plt.title("品质为5的酒精度数量直方图")

plt.subplot(2, 2, 3)
plt.hist(data_quality_6["alcohol"], bins=50)
plt.xlabel("酒精含量")
plt.ylabel("数量")
plt.title("品质为6的酒精度数量直方图")

plt.subplot(2, 2, 4)
plt.hist(data_quality_7["alcohol"], bins=50)
plt.xlabel("酒精含量")
plt.ylabel("数量")
plt.title("品质为7的酒精度数量直方图")

plt.tight_layout()
plt.savefig("results/quality_4567_vs.png", dpi=300)
plt.show()

# 特征和标签
X = data.drop('quality', axis=1)  # 特征,去除 'quality' 列
y = data['quality']  # 标签,仅保留 'quality' 列

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

# 数据标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 创建随机森林回归模型
model = RandomForestRegressor(n_estimators=100, random_state=42)

# 使用10折交叉验证评估模型在训练集上的性能
cv_mse = -cross_val_score(model, X_train_scaled, y_train, cv=10, scoring='neg_mean_squared_error').mean()
cv_r2 = cross_val_score(model, X_train_scaled, y_train, cv=10, scoring='r2').mean()
print(f'交叉验证的均方误差 (MSE): {cv_mse}')
print(f'交叉验证的R²分数: {cv_r2}')

# 超参数优化
pipeline = make_pipeline(RandomForestRegressor(random_state=42))
hyperparameters = {
    'randomforestregressor__max_features': ['sqrt', 'log2'],
    'randomforestregressor__max_depth': [None, 5, 3, 1]
}
clf = GridSearchCV(pipeline, hyperparameters, cv=10)
clf.fit(X_train_scaled, y_train)
print(f'最佳超参数: {clf.best_params_}')

# 使用最佳参数重新训练模型
best_model = clf.best_estimator_
best_model.fit(X_train_scaled, y_train)

# 评估模型在测试集上的性能
y_pred = best_model.predict(X_test_scaled)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f'测试集的均方误差 (MSE): {mse}')
print(f'测试集的R²分数: {r2}')

# 绘制真实值与预测值的散点图
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('True Quality')
plt.ylabel('Predicted Quality')
plt.title('Predicted vs True Quality Scores')
plt.savefig("results/Predicted_vs_True_Quality_Scores.png", dpi=400)
plt.show()

# 计算混淆矩阵
cm = confusion_matrix(y_test, np.round(y_pred))

# 绘制混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, cmap='Blues', fmt='d', xticklabels=[4, 5, 6, 7], yticklabels=[4, 5, 6, 7])
plt.xlabel('预测品质')
plt.ylabel('实际品质')
plt.title('混淆矩阵')
plt.savefig("results/混淆矩阵.png", dpi=400)
plt.show()

# 显示特征重要性
feature_names = X.columns
importances = best_model.named_steps['randomforestregressor'].feature_importances_
sorted_indices = np.argsort(importances)[::-1]

print("特征重要性(从高到低):")
for i in range(len(feature_names)):
    print(f"{feature_names[sorted_indices[i]]:<20} | {importances[sorted_indices[i]]}")

# 绘制特征重要性条形图
plt.figure(figsize=(10, 6))
sns.barplot(x=importances[sorted_indices], y=feature_names[sorted_indices])
plt.title('Feature Importances')
plt.xlabel('Importance')
plt.ylabel('Features')
plt.savefig("results/Feature Importances.png", dpi=400)
plt.show()

# 保存模型
joblib.dump(best_model, 'rf_regressor.pkl')

# 加载模型并进行预测
rf_regressor_loaded = joblib.load('rf_regressor.pkl')
y_pred_loaded = rf_regressor_loaded.predict(X_test_scaled)

# 计算预测准确率
accuracy = np.mean(np.round(y_pred_loaded) == y_test)
print("预测准确率: {:.2f}%".format(accuracy * 100))
相关推荐
江畔柳前堤4 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore5 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考7 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX7 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面8 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号8 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽8 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI8 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者10 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者10 小时前
【征程6】校准量化中HistogramObserver解析
算法