基于随机森林的颜色与物质浓度辨识实战——2017年高教社杯数学建模C题Python实现

1次阅读
没有评论

共计 2334 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

一、问题背景与挑战

颜色与物质浓度辨识在环境监测、工业生产等领域有广泛应用。例如通过溶液颜色变化判断污染物浓度,或制药过程中反应液浓度监测。2017 年数学建模 C 题要求建立颜色读数(RGB 值)与物质浓度的映射关系,核心难点在于:

基于随机森林的颜色与物质浓度辨识实战——2017 年高教社杯数学建模 C 题 Python 实现

  • 非线性关系 :颜色通道值与浓度往往不是简单线性相关
  • 噪声干扰 :光照条件、传感器误差会导致数据波动
  • 小样本问题 :实验数据通常有限(题目仅提供 100 组样本)

二、技术选型:为什么选择随机森林?

对比常见算法在小数据集上的表现:

  • SVM:对参数敏感,核函数选择困难
  • 神经网络 :需要大量数据,容易过拟合
  • 随机森林
  • 天然处理非线性关系
  • 内置特征重要性评估
  • 对异常值鲁棒性强
  • 超参数较少易于调优

三、完整实现流程

3.1 数据预处理

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler

def load_data(filepath):
    """
    加载并预处理数据
    :param filepath: 数据文件路径
    :return: 标准化后的特征和标签
    """
    data = pd.read_csv(filepath)

    # 异常值处理(IQR 法则)Q1 = data.quantile(0.25)
    Q3 = data.quantile(0.75)
    IQR = Q3 - Q1
    data = data[~((data < (Q1 - 1.5*IQR)) | (data > (Q3 + 1.5*IQR))).any(axis=1)]

    # 转换到 HSV 颜色空间(更符合人眼感知)rgb = data[['R','G','B']].values
    hsv = rgb_to_hsv(rgb)  # 自定义转换函数

    # 特征标准化
    scaler = StandardScaler()
    features = scaler.fit_transform(hsv)
    labels = data['Concentration'].values

    return features, labels

3.2 随机森林建模

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score

def train_model(X, y):
    """
    训练随机森林模型
    :param X: 特征矩阵
    :param y: 浓度标签
    :return: 训练好的模型
    """
    model = RandomForestRegressor(
        n_estimators=100,  # 树的数量
        max_depth=5,       # 控制过拟合
        min_samples_split=3,
        random_state=42    # 固定随机种子
    )

    # 交叉验证评估
    scores = cross_val_score(model, X, y, cv=5, scoring='r2')
    print(f"交叉验证 R2 分数: {np.mean(scores):.3f}±{np.std(scores):.3f}")

    model.fit(X, y)
    return model

3.3 结果可视化

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def plot_results(true, pred):
    """
    三维散点图对比真实值与预测值
    :param true: 真实浓度
    :param pred: 预测浓度
    """
    fig = plt.figure(figsize=(10, 7))
    ax = fig.add_subplot(111, projection='3d')

    ax.scatter(true, pred, c='r', marker='o', depthshade=False)
    ax.plot([true.min(), true.max()], [true.min(), true.max()], 'k--')

    ax.set_xlabel('True Concentration')
    ax.set_ylabel('Predicted Concentration')
    ax.set_title('Concentration Prediction Results')
    plt.show()

四、性能优化技巧

4.1 特征重要性分析

# 获取特征重要性
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]

# 打印特征排名
print("Feature ranking:")
for i, idx in enumerate(indices):
    print(f"{i+1}. feature {idx} ({importances[idx]:.3f})")

4.2 关键参数调优

  • n_estimators:增加树的数量可降低方差,但超过 200 后收益递减
  • max_depth:通过网格搜索寻找最佳值(通常 3 - 8 之间)
  • min_samples_leaf:建议设置为 3 - 5 防止过拟合

五、避坑指南

  1. 颜色校准
  2. 拍摄时使用标准色卡
  3. 同一光照条件下采集数据

  4. 样本不平衡

  5. 过采样少数浓度样本
  6. 调整 class_weight 参数

  7. 随机性控制

  8. 固定 random_state 保证结果可复现
  9. 多次运行取平均结果

六、扩展思考

当处理多物质混合溶液时,可以考虑:

  1. 建立多输出回归模型
  2. 使用光谱数据代替 RGB 值
  3. 引入物理化学先验知识约束模型

完整代码已开源在 GitHub(虚构链接):github.com/example/color-concentration

通过这个项目,我们实现了从颜色读数到物质浓度的准确预测。随机森林在这个小样本问题上展现出优秀性能,其可解释性也帮助我们理解了颜色特征的重要性排序。这种思路可以推广到类似的实际检测场景中。

正文完
 0
评论(没有评论)