思路提要:首先需要对给出的数据进行基本的数据处理(数据读取与查看、空缺值填补、异常值剔除等),接着需要筛选与PM2.5浓度变化有关的因素,该题实质是特征工程(筛选),常用的方法有方差过滤、卡方检验、相关系数、rf随机森林等方法,或者是基于机器学习训练的递归特征消除方法。一般会选择两至三种方法结合来进行特征筛选。
思路提要:根据第一问的提示,我们需要建立一个多元预测的时间序列机器学习模型,常用的就是LSTM多元多步预测模型。按照题意进行3/5/7/12步预测,并输出预测误差rmse即可。
思路提要:由于AQI是由多种污染物指标计算得到的,所以不应该直接预测AQI,应该分别预测六种基本污染物的浓度,然后利用预测值计算得到AQI的预测值。同样采用LSTM模型。
这里提一下AQI计算,需要先利用各污染物浓度算出IAQI然后才能得到AQI,参考代码:
from math import ceil #导入进位取整函数
from collections import OrderedDict #导入有序字典模块(Python3.6以下字典无序)
#定义包含污染物名称、浓度区间和IAQI区间的有序字典
mapping = OrderedDict([
('PM2.5', ((0,0),(35,50),(75,100),(115,150),(150,200),(250,300),
(350,400),(500,500))),
('PM10', ((0,0),(50,50),(150,100),(250,150),(350,200),(420,300),
(500,400),(600,500))),
('臭氧', ((0,0),(100,50),(160,100),(215,150),(265,200),(800,300),
(1000,400),(1200,500))),
('一氧化碳', ((0,0),(2,50),(4,100),(14,150),(24,200),(36,300),
(48,400),(60,500))),
('二氧化氮', ((0,0),(40,50),(80,100),(180,150),(280,200),(565,300),
(750,400),(940,500))),
('二氧化硫', ((0,0),(50,50),(150,100),(475,150),(800,200), (1600,300),
(2100,400),(2620,500)))
])
def data_validity(pollutants):
"""判断数据有效性"""
for k, v in pollutants.items():
if not v:
pollutants[k] = '0' #空白初始化为0
elif not v.isdecimal():
if k != '一氧化碳': #因CO可保留3位以下小数,需单独判断
return False
num = v.split('.') #以小数点为分割符切成两部分来判断
if len(num) != 2 or (not num[0].isdecimal()) or (not num[1].isdecimal()) or len(num[1]) > 3:
return False
if float(pollutants[k]) > mapping[k][-1][0]: #超过限值情况
return False
else: #正常循环退出
return True
def iaqi_calc(pollutants):
"""计算各污染物IAQI"""
for k, v in mapping.items(): #遍历字典,确定污染物名称
for i in range(len(v)-1): #遍历嵌套元组,确定污染物浓度所处区间
if float(pollutants[k]) <= v[i+1][0]: #利用相似三角形相似比求值
iaqi = ceil((float(pollutants[k])-v[i][0])*(v[i+1][1]-v[i][1])/(v[i+1][0]-v[i][0]))+v[i][1]
pollutants[k] = iaqi #更新污染物浓度为IAQI
break #计算完毕,需及时跳出(为什么^-^)
for k, v in pollutants.items():
print("{}-IAQI:{}".format(k, v))
def aqi_calc(pollutants):
"""计算AQI及相关信息"""
aqi = max(pollutants.values())
if aqi > 50: #首要污染物
prime_pollutants = '、'.join(k for k, v in pollutants.items() if v == aqi)
else:
prime_pollutants = '无'
if aqi > 100: #超标污染物
exceed_pollutants = '、'.join(k for k, v in pollutants.items() if v > 100)
else:
exceed_pollutants = '无'
print("AQI:{}".format(aqi))
print("首要污染物:{}".format(prime_pollutants))
print("超标污染物:{}".format(exceed_pollutants))
def main():
"""主程序"""
while True:
#定义临时存放各污染物浓度和IAQI数值的有序字典
pollutants = OrderedDict([(k, input('请输入{}浓度:'.format(k))) for k in mapping])
if data_validity(pollutants):
print("-"*50)
iaqi_calc(pollutants)
print("-"*50)
aqi_calc(pollutants)
print("-"*50)
if input("如需终止计算,请输入q后回车:").lower() == 'q':
break
print("-"*50)
else:
print("-"*50)
print("数据无效,请重新输入!")
print("-"*50)
if __name__ == '__main__':
main()