python 大气污染物模型_Python AQI空气污染指数数据分析与机器学习

导入模块

import numpy as np

import pandas as pd

import datetime

import matplotlib as mpl

import matplotlib.pyplot as plt

import matplotlib.pylab as pylab

import seaborn as sns

%matplotlib inline

# Configure visualisations

sns.set_style()

读取数据,查看数据列表

# 读取数据

data=pd.read_csv('train.csv')

# 查看数据列名称

data.columns

# 查看数据头与尾

data.head()

data.tail()

# 查看数据基本统计信息

data.describe()

# 查看数据存储类型

data.info()

由于数据也是个时间序列,所以我们可以先大致看一下AQI在不同时间尺度下的趋势。字段中date和time在一起,我们首先要把他们拆分开来看。

temp=pd.DatetimeIndex(data['datetime'])

# 增加一列数据

data['date']=temp.date

data['time']=temp.time

data.head()

data.tail()

data['month']=temp.month

data['day']=temp.day

data['hour']=temp.hour

data['week']=temp.weekofyear

data.head()

取出某一个地区的数据

data_A3=data[data['STATIONNAME'].str.contains('A3')]

data_A3.head()

首先,我们看一下2015年前8个月的变化趋势,从图上看,没有什么太多惊喜,好像是第一季度AQI值高的比较多,和我们平时的感觉是一样的,冬天污染却是要严重一下。

画时间与AQI的分布图

plt.figure(figsize=(16,8))

plt.plot(data_A3['date'],data_A3['AQI'])

plt.title('Trend of AQI')

plt.ylabel('AQI')

plt.legend(loc='best')

画每一个月份与AQI的分布图

plt.figure(figsize=(12,8))

# 画箱线图

sns.boxplot(x='month', y='AQI', data=data_A3)

plt.ylabel('AQI', fontsize=12)

plt.xlabel('month', fontsize=12)

plt.title('Median distribution by month')

plt.show()

画一个月中每一天AQI的分布图

#month

plt.figure(figsize=(12,8))

sns.pointplot(x='day', y='AQI', data=data_A3)

plt.ylabel('AQI', fontsize=12)

plt.xlabel('date of month', fontsize=12)

plt.title('By month')

plt.show()

画一年中所有周的AQI的分布图

#week

plt.figure(figsize=(12,8))

sns.pointplot(x="week", y="AQI", data=data_A3)

plt.ylabel('AQI', fontsize=12)

plt.xlabel('week of year', fontsize=12)

plt.title('By week')

plt.show()

画一天中24小时的AQI的分布图

#one day

plt.figure(figsize=(12,8))

sns.pointplot(x="hour", y="AQI", data=data_A3)

plt.ylabel('AQI', fontsize=12)

plt.xlabel('24 hours', fontsize=12)

plt.title('By hour')

plt.show()

画出一天中24小时的AQI的分布图的散点图表示

#one day---another way

plt.figure(figsize=(12,8))

sns.stripplot(x="hour", y="AQI", data=data_A3)

plt.ylabel('AQI', fontsize=12)

plt.xlabel('24 hours', fontsize=12)

plt.title('By hour')

plt.show()

从上面对AQI在时间尺度上的可视化结果,可以看出,AQI的变化趋势有时间上的周期性影响,因此,在之后的特征选择上需要考虑到时间因素。

下面,我们来分析一下AQI和6个指标的相关关系。首先我们不分地点计算相关性,然后再以A3为例进行可视化展示。

画相关矩阵图

co_data=data[['AQI','PM2.5','PM10','NO2','O3','CO','SO2']]

g=sns.PairGrid(co_data)

g.map(plt.scatter)

画相关性热力图

#相关性热度图

def plot_corr_map(df):

corr=df.corr()

_,ax=plt.subplots(figsize=(12,10))

cmap=sns.diverging_palette(220,10,as_cmap=True)

_=sns.heatmap(

corr,

cmap=cmap,

square=True,

cbar_kws={'shrink':0.9},

ax=ax,

annot=True,

annot_kws={'fontsize':12})

plot_corr_map(co_data)

seaborn做出来的图还是很漂亮的,从上面的相关关系矩阵可以发现O3与AQI的相关性最低,基本没有相关性,原因估计也比较复杂,需要专业人士去解读。我按照自己的理解认为:(1)AQI计算时,O3 权重较小,NOx 权重较大,PM2.5 权重最大,O3与它们都是负相关;(2)按AQI计算规则,臭氧1小时浓度值不用于计算每天的AQI指数,仅用来反映小时健康影响程度,提示直接接触臭氧污染的人羣应采取防护措施,而日均AQI指数计算采用臭氧8小时滑动平均值。

研究每一个地区的情况

#地点A3的情况

co_data_A3=data_A3[['AQI','PM2.5','PM10','NO2','O3','CO','SO2']]

g=sns.PairGrid(co_data_A3)

g.map(plt.scatter)

通过上面对数据的挖掘和理解,可以发现,时间对AQI的影响相当重要,因此,在需要把Month、Week、Day、Hour等不同的时间尺度作为特征加入到数据去训练模型;另外,O3与AQI基本不存在相关性,因此,可以把O3从数据中删除,减少对训练模型的影响。

data.head()

#remove old data features

data_new=data.drop(['datetime','O3','date','time'],axis=1)

data_new.head()

data_new.shape

查看数据空值情况,并用中位数,平均数,填充空缺值

nans=pd.isnull(data_new).sum()

nans[nans>0]

#对AQI、PM2.5、NO2、03、CO和SO2采用均值填充

data_new['AQI']=data_new['AQI'].fillna(data_new['AQI'].mean())

data_new['PM2.5']=data_new['PM2.5'].fillna(data_new['PM2.5'].mean())

data_new['NO2']=data_new['NO2'].fillna(data_new['NO2'].mean())

data_new['CO']=data_new['CO'].fillna(data_new['CO'].mean())

data_new['SO2']=data_new['SO2'].fillna(data_new['SO2'].mean())

nans=pd.isnull(data_new).sum()

nans[nans>0]

对于PM10来说,缺失值小于1/3,但也缺失较多,考虑到其随机性因素,不能用均值等方法填充,这里采用随机森林建立模型的方法。

#采用随机森林算法建立模型来填充PM10的缺失值,即利用数据表中某些没有缺失的特征属性来预测某特征属性的缺失值

def fill_missing_PM10(df):

from sklearn.ensemble import RandomForestRegressor

temp=df[['PM10','AQI','PM2.5','NO2','CO','SO2']]

#分成已知该特征和未知该特征两个部分

known=temp[temp.PM10.notnull()].as_matrix()

unknown=temp[temp.PM10.isnull()].as_matrix()

#X为特征属性值

X=known[:,1:]

#y为结果标签值

y=known[:,0]

#fit to a RandomForestRegressor model

rfr=RandomForestRegressor(n_estimators=2000,n_jobs=-1)

rfr.fit(X,y)

#利用得到的model进行未知特征值预测

predicted=rfr.predict(unknown[:,1:])

#将预测结果fill the missing values

df.loc[df.PM10.isnull(),'PM10']=predicted

return df,rfr

#调用函数进行PM10缺失值填充

data_new,rfr=fill_missing_PM10(data_new)

接下来使用整个表的数据,进行模型训练,

from sklearn.feature_extraction import DictVectorizer

# 我们把连续值的特征放入一个dict中

feature_con=['PM2.5','PM10','NO2','CO','SO2','month','day','week','hour']

data_feature_con=data_new[feature_con]

X_con=data_feature_con.T.to_dict().values()

# 向量化特征

vec=DictVectorizer(sparse=False)

X_con_vec=vec.fit_transform(X_con)

data_feature_con.head()

X_con_vec

对数据进行正规化

对数型值属性做一些处理,把其值缩减至0-1之间,这样的数据放到模型里,对模型训练的收敛和模型的准确性都有好处。这里采用MinMaxScaler方法。

# normalize the con features

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))

X_con_vec=scaler.fit_transform(X_con_vec)

X_con_vec

地区需要进行one-hot编码

对于类别特征,通过one_hot编码进行处理,采用pandas的get_dummies函数。

#one-hot encoding

dummies_cat_feature=pd.get_dummies(data_new['STATIONNAME'])

dummies_cat_feature=dummies_cat_feature.rename(columns=lambda x: "STATIONNAME_"+str(x))

dummies_cat_feature.head()

# 同样,把编码后的表放入dict中

X_cat=dummies_cat_feature.T.to_dict().values()

X_cat

# 向量化特征

X_cat_vec=vec.fit_transform(X_cat)

X_cat_vec

X_cat_vec.shape

# combine cat & con features

X_vec=np.concatenate((X_con_vec,X_cat_vec),axis=1)

X_vec

X_vec.shape

预测值AQI处理

#对AQI向量化

Y_vec=data_new['AQI'].values.astype(float)

#对AQI最大最小化

# Y_vec=scaler.fit_transform(Y_vec)

# Y_vec=scaler.fit_transform(Y_vec)

Y_vec

拆分训练集和测试集

from sklearn import cross_validation

X_train,X_test,y_train,y_test=cross_validation.train_test_split(X_vec,Y_vec,test_size=0.3,random_state=0)

print(X_train.shape)

print(X_test.shape)

print(y_train.shape)

print(y_test.shape)

评估函数

def model_evaluation(model,X_tr,y_tr,X_te,y_te):

from sklearn import metrics

from sklearn.cross_validation import cross_val_score

#建立模型

model.fit(X_tr,y_tr)

#预测

y_pr=model.predict(X_te)

#打印结果

print ("Correlation Coefficient:",np.corrcoef(y_te,y_pr))

print ("---------------------------")

print ("RMSE:",np.sqrt(metrics.mean_squared_error(y_te, y_pr)))

print ("---------------------------")

print ("Determination Coefficient(R2):train score",model.score(X_tr,y_tr),"test score",model.score(X_te,y_te))

print ("---------------------------")

scores=cross_val_score(model,X_tr,y_tr)

print ("Cross-validation score:",scores.mean())

return model,y_pr

第一种模型采用最简单的线性回归进行学习预测。

from sklearn.linear_model import LinearRegression

lr=LinearRegression()

m,y_predict_linear=model_evaluation(lr,X_train,y_train,X_test,y_test)

y_predict_linear

第二种使用单层神经网络模型

from sklearn.neural_network import MLPRegressor

mlpr=MLPRegressor(hidden_layer_sizes=(1000,),activation='relu',max_iter=500)

model_evaluation(mlpr,X_train,y_train,X_test,y_test)

第三种使用决策树回归模型

from sklearn.tree import DecisionTreeRegressor

dtr=DecisionTreeRegressor()

model_evaluation(dtr,X_train,y_train,X_test,y_test)

第三种极端随机森林

Extra_Tree是一种bagging方法,是基于极端随机树的迭代算法,与随机森林相比,模型会进一步减少方差。

from sklearn.ensemble import ExtraTreesRegressor

params = {'n_estimators': 50, 'random_state': np.random.RandomState(1)}

etr= ExtraTreesRegressor(**params)

model_evaluation(etr,X_train,y_train,X_test,y_test)

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值