夜的独白

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

导入模块

    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()
[/code]

读取数据,查看数据列表

```code
    # 读取数据
    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()
[/code]

取出某一个地区的数据

```code
    data_A3=data[data['STATIONNAME'].str.contains('A3')]
    data_A3.head()
[/code]

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

画时间与AQI的分布图

```code
    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')
[/code]

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

```code
    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()
[/code]

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

```code
    #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()
[/code]

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

```code
    #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()
[/code]

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

```code
    #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()
[/code]

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

```code
    #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()
[/code]

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

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

画相关矩阵图

```code
    co_data=data[['AQI','PM2.5','PM10','NO2','O3','CO','SO2']]
    g=sns.PairGrid(co_data)
    g.map(plt.scatter)
[/code]

画相关性热力图

```code
    #相关性热度图
    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)
[/code]

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

研究每一个地区的情况

```code
    #地点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]
[/code]

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

```code
    #采用随机森林算法建立模型来填充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)
[/code]

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

```code
    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
[/code]

对数据进行正规化

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

```code
    # 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
[/code]

地区需要进行one-hot编码

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

```code
    #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()
[/code]

```code
    # 同样,把编码后的表放入dict中
    X_cat=dummies_cat_feature.T.to_dict().values() 
    X_cat
    # 向量化特征
    X_cat_vec=vec.fit_transform(X_cat)
[/code]

```code
    X_cat_vec
    X_cat_vec.shape
[/code]

```code
    # combine cat & con features
    X_vec=np.concatenate((X_con_vec,X_cat_vec),axis=1)
    X_vec
    X_vec.shape
[/code]

预测值AQI处理

```code
    #对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
[/code]

拆分训练集和测试集

```code
    ​
    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)
    
    ​
[/code]

评估函数

```code
    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
[/code]

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

```code
    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
[/code]

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

```code
    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)
[/code]

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

```code
    from sklearn.tree import DecisionTreeRegressor
    dtr=DecisionTreeRegressor()
    model_evaluation(dtr,X_train,y_train,X_test,y_test)
[/code]

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

```code
    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)
[/code]


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210608151750993.gif)
posted on 2021-07-08 14:36  夜的独白  阅读(458)  评论(0)    收藏  举报