要客观评价一个地区的环境质量状况, 需要综合考虑各种应诉之间以影响因素与环境质量之间错综复杂的关系. 采用传统的方法存在着一定局限性和不合理性. 因此, 从学术研究的角度对环境评价的技术方法及其理论进行探讨, 寻求更全面客观的新理论方法具有重要的现实意义.
本例通过建立决策树模型, 对数据中空气中相关气体的含量值与对应的空气等级进行分析, 实现对空气质量的评价.
百度百科对于决策树的解释:
决策树是在已知各种情况发生概率的基础上, 通过构成决策树来求取净现值的期望值大于等于零的概率, 评价项目风险, 判断其可行性的决策分析方法, 是直观运用概率分析的一种图解法. 由于这种决策分支画成图形很像一棵树的枝干, 故称决策树. 机器学习中, 决策树是一个预测模型, 他代表的是对象属性与对象值之间的一种映射关系.
决策树的常见算法:
1. ID3
基于信息增益选择节点属性. 特点是方法简单, 但对噪声敏感, 且只能处理离散型的数据.
2. C4.5
基于ID3算法进行了改进, 相对ID3具有以下优点:
(1) 采用信息增益率
(2) 采用悲观剪枝
(3) 可离散化处理连续属性
(4) 可对缺失值进行处理
3. CART
英文全称 Classification and Regression Tree, 即分类回归树.
CART只支持二叉树, 既可作为分类树, 又可作为回归树.
CART算法属性选择采用的指标是基尼系数.
原始数据为某地空气指标, 利用pandas读入.xls文件并查看数据, 发现数据由SO2, NO, NO2, NOx, PM10, PM2.5的值与空气质量等级组成, 一共320条数据, 没有缺失值.
代码及输出:
# 数据加载
filepath = './data/air_data.xls'
data = pd.read_excel(filepath)
print(data.head())
print(data.info())
利用data['空气等级'].value_counts()查看空气等级分类及其数量, 发现其等级分为罗马数字I~VII级, 且第VI、VII级样本数量较少, 分别为6个和1个.
在此对两者进行了合并(合为第VI级), 同时用阿拉伯数据代替了罗马数字等级.
然后使用sklearn中的train_test_split划分训练集与测试集, 其中测试集占比20%, random_state为5. 查看测试集, 1~6级的样本都有包含到(推算出训练集各等级也包含完全), 为比较理想的划分.
相应代码:
# 数据预处理
print(data['空气等级'].value_counts())
data['空气等级'].replace(data['空气等级'].unique(), [1, 2, 3, 4, 5, 6, 6], inplace=True)
features = data.iloc[:, :-1]
labels = data['空气等级']
train_x, test_x, train_y, test_y = train_test_split(features, labels, test_size=.2, random_state=5)
print(test_y.value_counts())
sklearn 中的 tree模块提供了决策树分类器DecisionTreeClassifier, 其中criterion参数可以去两个值, 取'gini'时算法为CART算法, 取'entropy'时使用信息熵相关算法(本人查资料为ID3算法, 是否属实请指正).
由于样本数据类型为连续型变量, 故本例采用CART算法建立决策树模型, 并进行训练和预测, 最后输出模型得分为0.984375.
相应代码:
# 模型建立
model = DecisionTreeClassifier(criterion='gini')
model.fit(train_x, train_y)
pre_y = model.predict(test_x)
print('模型得分:', accuracy_score(test_y, pre_y))
为更直观的查看模型输出结果, 使用seaborn 工具绘制模型的混淆矩阵, 由图可见测试集中只有一例空气质量实为1级的样本被误判为2级, 其他样本都被正确预测, 表明模型预测效果不错.
相应代码及混淆矩阵图:
# 混淆矩阵可视化
cm = confusion_matrix(test_y, pre_y)
index = data['空气等级'].unique()
print(index)
cm_data = pd.DataFrame(cm, index=index, columns=index)
sns.heatmap(cm_data, annot=True, cmap='YlGnBu')
ax = plt.gca()
ax.xaxis.set_ticks_position('top') # 指定顶端为x轴
plt.xlabel('预测值')
plt.ylabel('实际值')
plt.show()
为了更直观的查看决策树, 代码使用了sklearn中export_graphviz工具保存了决策树.dot文件, 并使用Graphviz工具对文件进行了转换(CMD进入air.dot文件所在文件夹, 输入'dot -Tpng air.dot -o air.png'命令, 转为.png文件), 查看决策树如下图:
图中决策树分类主要由X[3]及X[0]决定, 可知对应的NOx值与SO2值为影响本地空气等级指标的主要因素.
由于本例样本较少且数据来源于一个地区、采集时段未知, 不能断定PM10等决策树中未出现指标对空气等级无影响.
完整代码及数据请点击:GitHub