共计 2334 个字符,预计需要花费 6 分钟才能阅读完成。
一、问题背景与挑战
颜色与物质浓度辨识在环境监测、工业生产等领域有广泛应用。例如通过溶液颜色变化判断污染物浓度,或制药过程中反应液浓度监测。2017 年数学建模 C 题要求建立颜色读数(RGB 值)与物质浓度的映射关系,核心难点在于:

- 非线性关系 :颜色通道值与浓度往往不是简单线性相关
- 噪声干扰 :光照条件、传感器误差会导致数据波动
- 小样本问题 :实验数据通常有限(题目仅提供 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 防止过拟合
五、避坑指南
- 颜色校准 :
- 拍摄时使用标准色卡
-
同一光照条件下采集数据
-
样本不平衡 :
- 过采样少数浓度样本
-
调整 class_weight 参数
-
随机性控制 :
- 固定 random_state 保证结果可复现
- 多次运行取平均结果
六、扩展思考
当处理多物质混合溶液时,可以考虑:
- 建立多输出回归模型
- 使用光谱数据代替 RGB 值
- 引入物理化学先验知识约束模型
完整代码已开源在 GitHub(虚构链接):github.com/example/color-concentration
通过这个项目,我们实现了从颜色读数到物质浓度的准确预测。随机森林在这个小样本问题上展现出优秀性能,其可解释性也帮助我们理解了颜色特征的重要性排序。这种思路可以推广到类似的实际检测场景中。
正文完
发表至: 未分类
近三天内
