ML2016-PM2.5 Prediction

本文介绍了一种利用线性回归预测PM2.5浓度的方法。通过对气象数据进行预处理,提取连续时段内的PM2.5值作为特征与目标变量,并使用Weka及sklearn进行模型训练与验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

根据气象局网站下载的真实观测数据,使用线性回归或者其它方法预测PM2.5的数值。

数据

数据分为train.csv和test_X.csv:

  • train.csv:下面是原始数据
    这里写图片描述
# 注:我把原始数据的列标签换成了英文,显示如下
import pandas as pd
train = pd.read_csv("train.csv")

print train.head(1)
'''
    Date Location  Observation  0   1   2   3   4   5   6 ...  14  15  16  17  18  19  20  21  22  23  

   0  2014/1/1  豐原  AMB_TEMP  14  14  14  13  12  12  12 ...  22  22  21  19  17  16  15  15  15  15  
'''
  • test_X.csv:下面是原始数据
    这里写图片描述
# 注:我给原始数据添加了列标签,显示如下
test = pd.read_csv("test_X.csv")

print test.head(1)
'''
    Date  Observation   0   1   2   3   4   5   6   7   8
0   id_0     AMB_TEMP  15  14  14  13  13  13  13  13  12
'''

需要解释下数据集:关于训练数据,列标签显示的日期,地点,指标,以及24个小时该指标的测量值;横标签标示的是指标的名称,总共有18个指标,所以一天的数据就是18行;关于测试集,列标签显示的是日期,指标,以及9个小时该指标的测量值;横标签同训练集,总共有18个指标,所以一天的数据也是18行。
训练数据总共有12个月*20天*18条 = 4320条
测试数据是从每个月剩余的10天中随机抽取的不重复的240条连续九个小时的每个指标的观测数据。那么就是240*18 = 4320行。

数据处理

题目要求,用前九个小时的测量值,预测第十个小时的PM2.5的值。最简单的尝试就是,先提取出训练数据中所有的连续十个小时内的PM2.5的值将其作为训练集输入到模型中。

  • 去掉无关的两列:Date Location
train = train.drop(['Date','Location'], 1)
print train.head(1)
'''
    Observation   0   1   2   3   4   5   6   7   8 ...  14  15  16  17  18  19    20  21  22  23  

0    AMB_TEMP    14  14  14  13  12  12  12  12  15 ...  22  22  21  19  17  16   15  15  15  15 
'''
  • 首先提取出所有的PM2.5的数据
pm25 = train[train['Observation']=='PM2.5']
# 删除Observation列标签,便于后面提取数据
pm25.drop('Observation',1,inplace=True)
print pm25.head(3)
'''
      0   1   2   3   4   ...  14  15  16  17  18  22  23  
9    26  39  36  35  31  ...  36  45  42  49  45  24  13 
27   21  23  30  30  22  ...  53  43  43  45  46   22  26  
45   19  25  27  20  16  ...  32  36  34  45  40   23  37  
'''  
  • 由于测试数据给的是连续九个小时的PM2.5的观测数据,因此需要从训练数据中同样提取出连续十个小时的观测数据,最后一个小时的PM2.5作为该条数据的类标签,而前九个小时的PM2.5值作为特征。一天24个小时,一天内总共有24-10+1 =15条记录。
dfList = []
for i in range(15):
    df = pm25.iloc[:,i:i+10]
    df.columns = np.array(range(10))
    dfList.append(df)

pm25 = pd.concat(dfList)
print pm25.head(3)
'''
     0   1   2   3   4   5   6   7   8   9
9   26  39  36  35  31  28  25  20  19  30
27  21  23  30  30  22  18  13  13  11  22
45  19  25  27  20  16  14  15   8   4   9
'''
print pm25.shape
'''
(3600, 10)
'''
# 保存数据
pm25.to_csv("pm25.csv")
  • 同样先提取出测试数据中的PM2.5的数据
# 先提取出所有的PM2.5相关的数据集
pm25Test = test[test['Observation']=='PM2.5']
# 删除掉多余的属性
pm25Test.drop(['Date','Observation'],1,inplace=True)
print pm25Test .head(3)
'''
     0   1   2   3   4   5   6   7   8
9   27  13  24  29  41  30  29  27  28
27  46  47  57  78  84  76  59  61  61
45  10  10  25  34  40  39  36  25  22
'''
print pm25Test.shape
'''
(240, 9)
'''
# 保存数据
pm25Test.to_csv("pm25Test.csv")

预测

  • 现在我们的训练集大小为3600,前九个是特征,最后一个是类标签;
    测试数据集的大小是240,只有九个特征,类标签待预测;

为了更快的得到结果,我是用了weka这个数据挖掘工具,个人认为,学习数据挖掘,不要拘泥于线性代数、微积分以及各种算法编码细节,首先就是用你所掌握得知识来快速解决实际问题。首先这个问题是一个回归问题,那么我首先考虑的是简单线性回归,然后不必从头开始写线性回归算法,而是用现有的工具。如果效果可以,那么可以自己再去编码优化这个线性回归,或者拓展为其它的回归算法,至此,你可以去详细阅读有关回归的各种算法,这个时候,你会更愿意去学习线性代数和微积分等算法细节,因为你的问题急需得到解决,那么你也更有动力;

  • 使用weka训练模型:

这里写图片描述
这里写图片描述

  • 使用训练集得到的回归模型如下:
Linear Regression Model

9 =

     -0.0399 * 1 +
      0.201  * 2 +
     -0.2082 * 3 +
     -0.0484 * 4 +
      0.467  * 5 +
     -0.5366 * 6 +
      1.0853 * 8 +
      2.1619
  • 预测

Classify->Supplied test set->pm25Test.csv->Result list->右键刚训练的模型->Re-evaluate model on current test set
需要注意的时,由于我们测试数据是没有类标签这一列的,但是weka中测试数据集的特征数要与训练集相同,那么我们添加一个class列,使其值为0,最后会生成一个预测的class列。

这里写图片描述
至此,预测的值已经得出,提交到kaggle(总共有240多个排名):

这里写图片描述


使用sklearn进行预测

Ordinary Least Squares : LinearRegression

  • 最后得到的预测精度为5.88309
from sklearn import linear_model

reg = linear_model.LinearRegression()
reg.fit (train_data,train_label)

print reg.coef_
'''
array([[ 0.00729085, -0.04603342,  0.1994169 , -0.20757678, -0.0438468 ,
         0.46235542, -0.54329308,  0.01552321,  1.07716736]])
'''

test_data = pd.read_csv("pm25Test.csv").values
pre = reg.predict(test_data)
np.savetxt('pre.csv', pre, delimiter = ',')

Ridge Regression : Ridge

  • 使用这个得到的结果是5.88309
from sklearn import linear_model

reg = linear_model.Ridge (alpha = .4) # linear_model.Lasso(alpha = 0.1)得到的结果一样
reg.fit (train_data,train_label)
print reg.coef_
'''
[[ 0.00729112 -0.04603173  0.19941234 -0.20757313 -0.04384462  0.46234831
  -0.54328797  0.01552537  1.07716375]]
'''

test_data = pd.read_csv("pm25Test.csv").values
pre = reg.predict(test_data)
np.savetxt('pre.csv', pre, delimiter = ',')
### CNN-LSTM PM2.5 Prediction Model Code For implementing a CNN-LSTM model to predict PM2.5 levels, the architecture combines Convolutional Neural Networks (CNNs) for spatial feature extraction from input data and Long Short-Term Memory networks (LSTMs) for temporal sequence modeling[^1]. Below is an example of how such a model might be implemented using Python with TensorFlow/Keras. #### Data Preprocessing Before building the model, preprocessing steps are necessary to prepare the dataset suitable for training. This includes normalizing features, reshaping inputs into sequences that LSTM expects, and splitting datasets into training/testing sets. ```python import numpy as np from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Dropout, LSTM, TimeDistributed, Conv1D, MaxPooling1D, Flatten def preprocess_data(data, look_back=10): scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(data) X, y = [], [] for i in range(len(scaled_data)-look_back-1): X.append(scaled_data[i:(i+look_back), :]) y.append(scaled_data[i + look_back, 0]) # Assuming first column represents PM2.5 values return np.array(X), np.array(y), scaler ``` #### Building the CNN-LSTM Model The following function constructs a sequential model where convolution layers precede recurrent ones. A `TimeDistributed` wrapper allows applying the same layer at every time step within each sample batch during forward propagation through network layers. ```python def build_cnn_lstm_model(input_shape): model = Sequential() # Adding CNN Layers model.add(TimeDistributed(Conv1D(filters=64, kernel_size=3, activation='relu'), input_shape=input_shape)) model.add(TimeDistributed(MaxPooling1D(pool_size=2))) model.add(TimeDistributed(Flatten())) # Adding LSTM Layer model.add(LSTM(50, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(50)) model.add(Dense(1)) model.compile(optimizer='adam', loss='mean_squared_error') return model ``` #### Training Process Example After preparing the data and defining the structure of the neural net, compile it by specifying optimizer algorithms along with evaluation metrics before fitting on historical records over multiple epochs until convergence occurs or early stopping criteria met. ```python X_train, y_train, _ = preprocess_data(training_set.values, look_back=10) model = build_cnn_lstm_model((X_train.shape[1], X_train.shape[2])) history = model.fit( X_train, y_train, epochs=50, batch_size=72, validation_split=0.2, verbose=2, shuffle=False ) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值