李宏毅ML作业笔记1: 预测PM2.5(kaggle预测与报告题目)

作业笔记被我手贱删了, 只能凭回忆重新总结个简洁版本的

我用的是kaggle提供的在线notebook, 代码与部分思路公开在:

https://www.kaggle.com/laugoon/homework1( 第一行注释中注明报告题目的cell, 在预测时无需运行 )

不方便用kaggle也可以在CSDN下载源码:

https://download.csdn.net/download/lagoon_lala/16721800

其他好用的在线notebook还有:

deepnote( 比colab多一些协作编程等功能 ):

http://deepnote.com

colab(需要能上谷歌), 这是台大给出的作业范例:

https://colab.research.google.com/drive/131sSqmrmWXfjFZ3jWSELl8cm0Ox5ah3C

 

目录

数据说明

kaggle要求

预测思路

相關 reference 可以參考:

报告题

1. 不同学习率收敛情况

2. 减少feature (只取后5h)

3. 减少feature (只取PM2.5)

4. 调整改进


数据说明

PM2.5预测

本次作業使用豐原站的觀測記錄

train.csv: 每個月前 20 天的完整資料。

test.csv : 從剩下的資料當中取樣出連續的 10 小時為一筆,前九小時的所有觀測數據當作 feature,第十小時的 PM2.5 當作 answer。一共取出 240 筆不重複的 test data,請根據 feature 預測這 240 筆的 PM2.5。

Data 含有 18 項觀測數據 AMB_TEMP, CH4, CO, NHMC, NO, NO2, NOx, O3, PM10, PM2.5, RAINFALL, RH, SO2, THC, WD_HR, WIND_DIREC, WIND_SPEED, WS_HR。 

kaggle要求

Link: https://www.kaggle.com/c/ml2020spring-hw1

預測 240 筆 testing data 中的 PM2.5 值,並將預測結果上傳至 Kaggle

Upload format : csv file( kaggle上会有提交样例 )

第一行必須是 id,value

第二行開始,每行分別為 id 值及預測 PM2.5 數值,以逗號隔開。

作 linear regression,方法限使用 gradient descent。

禁止使用 numpy.linalg.lstsq

预测思路

我的代码https://www.kaggle.com/laugoon/homework1

其中初次预测部分主要参考作业范例:

https://colab.research.google.com/drive/131sSqmrmWXfjFZ3jWSELl8cm0Ox5ah3C

补充一些作业范例中的思路图片:

特征提取:

原数据每18行为1个月, 放到横向

 

每10h为一笔资料( 其中前9h为输入, 第10h为输出 ), 把输入输出分别保存

线性回归实现, 梯度下降算法

 

 

对测试集的输入预处理

相關 reference 可以參考:

Adagrad:

https://youtu.be/yKKNr-QKz2Q?list=PLJV_el3uVTsPy9oCRY30oBPNLCo89yu49&t=705

对应李宏毅该系列视频的梯度下降

RMSprop :

https://www.youtube.com/watch?v=5Yt-obwvMHI

对应B站吴恩达:

https://www.bilibili.com/video/BV1V441127zE?p=21&t=1

Adam:

https://www.youtube.com/watch?v=JXQT_vxqwIs

对应B站吴恩达:

https://www.bilibili.com/video/BV1V441127zE?p=22

可以藉由調整 learning rate、iter_time (iteration 次數)、取用 features 的多寡(取幾個小時,取哪些特徵欄位),甚至是不同的 model 來超越 baseline。

Report 的問題模板請參照 :

https://docs.google.com/document/d/1s84RXs2AEgZr54WCK9IgZrfTF-6B1td-AlKR9oqYa4g/edit

报告题

備註 :

      a. 1~3題的回答中,NR 請皆設為 0,其他的數值不要做任何更動。

      b. 可以使用所有 advanced 的 gradient descent 技術(如 Adam、Adagrad)。

      c. 1~3題請用linear regression的方法進行討論作答。

1. 不同学习率收敛情况

1. (2%) 使用四種不同的 learning rate 進行 training (其他參數需一致),作圖並討論其收斂過程(橫軸為 iteration 次數,縱軸為 loss 的大小,四種 learning rate 的收斂線請以不同顏色呈現在一張圖裡做比較)。

关于matplotlib, 太久没用, 重点补了一下这次用到的, 可以看博客旁边一篇"作图笔记"

全部数据直接生成出来, 第一次长这样

观察数据之后, 发现是前几个点太大了, 导致后面看起来像长尾, 考虑缩小y轴显示范围. 最终显示结果:

在其他参数不变的情况下, 学习率为2左右收敛情况最好, 学习率小于1后 收敛速度反而显著变慢

2. 减少feature (只取后5h)

2. (1%) 比較取前 5 hrs 和前 9 hrs 的資料(5*18 + 1 v.s 9*18 + 1)在 validation set 上預測的結果,並說明造成的可能原因(1. 因為 testing set 預測結果要上傳 Kaggle 後才能得知,所以在報告中並不要求同學們呈現 testing set 的結果,至於什麼是 validation set 請參考:https://youtu.be/D_S6y0Jm6dQ?t=1949 2. 9hr:取前9小時預測第10小時的PM2.5;5hr:在前面的那些features中,以5~9hr預測第10小時的PM2.5。這樣兩者在相同的validation set比例下,會有一樣筆數的資料)。

预测时原本用的是全部训练集, 本题要求使用划分训练/验证集后的数据.

划分后训练时, 拼接常数项参数的矩阵形状, 标准差计算时的总个数都要改变.

此外, 还要提取后5小时的属性作为训练, 测试集的输入. 要进行提取, 首先要明白处理后的x形状.

x [12 * 471, 18 * 9], y [12 * 471, 1]

行数的含义为一年12mon*每月471笔数据

列数的含义为每笔数据含10h, 其中9h在x, 1h在y.

np多维数组分片时不用加iloc, dataframe需要.

在训练出验证集的y后需要考虑如何衡量预测结果, 看到老师在上课时用的是平均误差, 所以决定用这个. ( 也看过一些同学用loss )

最后平均误差结果: 9h的3.5+ 5h的3.4+

可能的原因为. 前4h对第10h的PM2.5影响不大,甚至有点过拟合.

3. 减少feature (只取PM2.5)

3. (1%) 比較只取前 9 hrs 的 PM2.5 和取所有前 9 hrs 的 features(9*1 + 1 vs. 9*18 + 1)在 validation set上預測的結果,並說明造成的可能原因。

9*18 + 1的部分仍可用上题预测出的结果

9*1 + 1

需要找到PM2.5的那部分

开始看原始数据读入时每把表头算入, 而且从0开始计, 所以是第9行.

只取第9行会报错

all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)

单独一行, 外面没套那一层, 所以退化成一维数组了

然后想起来训练数据集是处理过的, 已经不是这个形状了

x [12 * 471, 18 * 9], y [12 * 471, 1]

每笔数据的PM2.5应该在第9列, 18+9列…以此类推

循环提取, 整列赋值参考:

https://blog.csdn.net/PJCKR/article/details/95453642

赋值是没问题的, 最后找到问题在于定义数组形状的时候没*0.8(这是划分训练集, 验证集后的大小)

碰到这样的报错:

shapes (4521,11) and (10,1) not aligned: 11 (dim 1) != 10 (dim 0)

那一般是加常数参数项的单元格被多次执行了, 9*1+1变成了9*1+2

最后得到平均误差结果:

所有属性: 4.63735404055456

只看PM2.5: 12.194386766277699

可能原因: 其他属性中有些对PM2.5的起关键作用.

4. 调整改进

4. (2%) 請說明你超越 baseline 的 model(最後選擇在Kaggle上提交的) 是如何實作的(例如:怎麼進行 feature selection, 有沒有做 pre-processing、learning rate 的調整、advanced gradient descent 技術、不同的 model 等等)。

根据验证集预测的结果, learning rate=2, 取后5h的效果比较好, 其他属性中有重要的, 但是要去除不重要属性还是需要分析. 属性太多画图是不方便了, 一会看看哪个w比较大.

w依次对应x的一行(一笔数据), x[12 * 471, 18 * 5]

x的每一行是h5的18个属性, … h9的18个属性

5h训练得到的w:

AMB_TEMP

-1.61E-01

2.81E-02

-5.09E-01

-3.30E-02

-2.09E-01

CH4

2.09E-01

-8.12E-03

4.11E-01

3.04E-01

-1.52E-01

CO

9.15E-02

-1.23E-01

-5.95E-02

-4.90E-02

2.51E-01

NMHC

1.07E-01

1.56E-03

-1.74E-01

2.48E-01

9.93E-02

NO

-4.19E-01

-8.53E-02

3.30E-02

7.38E-02

-1.68E-01

NO2

8.84E-02

1.16E-01

1.31E-01

1.48E-01

-1.62E-01

NOx

1.32E-01

7.35E-02

-3.92E-01

-2.42E-01

-5.54E-02

O3

-4.32E-01

-1.05E-02

1.53E-01

1.33E-01

-1.02E-01

PM10

1.82E+00

-1.27E-01

7.70E-01

4.35E-02

-1.21E-02

PM2.5

-2.68E-01

1.73E-02

-2.25E-04

-1.95E-01

-6.87E-02

RAINFALL

4.22E-01

3.12E-01

-1.59E-01

-1.16E-01

2.97E-01

RH

1.41E+00

1.29E-01

2.94E-02

2.69E-02

-1.51E-01

SO2

-2.19E+00

-9.66E-02

-2.72E-01

-2.54E-01

-3.07E-01

THC

4.15E-01

-1.69E-01

1.62E-01

4.98E-02

-5.67E-02

WD_HR

5.29E+00

6.34E-01

6.48E-02

2.88E-02

3.79E-01

WIND_DIREC

-7.38E+00

-8.56E-01

-3.10E-02

-2.59E-03

-1.94E-02

WIND_SPEED

7.51E-01

4.28E-02

-6.34E-02

-1.90E-01

-2.53E-01

WS_HR

1.52E+01

-5.54E-01

7.75E-01

1.03E-01

9.33E-02

常数

2.14E+01

    

绝对值, 每h分别排序, w最小的feature分别为

第一次

第二次

第三次

第四次

第五次

NMHC(2)

O3

WIND_DIREC(3)

WD_HR

NOx

CO

CH4

RH(2)

RH

WIND_DIREC

NO2

NMHC

PM2.5

WIND_DIREC

PM10

有点奇怪. w由时间前到后越来越小, 但最后一笔数据最靠近预测日期, 应该影响更大啊.

而且没有固定的某个属性对PM2.5影响很小, 决定不对属性动手了

用后5h的数据训练, 虽然验证集误差稍小, 但测试集得分很低

比较下loss, 是5.861416265758481, 相差不大, 比原来好些, 原来loss收敛到貌似7+

loss没有问题, 但输出就是很离谱, 可能测试集的输入处理有问题

#测试集输入数据标准化结果有问题

for i in range(len(test_x_5h)):

    for j in range(len(test_x_5h[0])):

        if std_x[j] != 0:

            test_x_5h[i][j] = (test_x_5h[i][j] - mean_x[j]) / std_x[j]

test_x_5h = np.concatenate((np.ones([240, 1]), test_x_5h), axis = 1).astype(float)

此处输出不太对, 考虑是std, mean不合适. 训练集是先标准化再取后5h

训练集标准化时用的是:

mean_x = np.mean(x, axis = 0) #18 * 9

std_x = np.std(x, axis = 0) #18 * 9 标准差

重新标准化后得分好很多, 没那么离谱了: 9.24833

说明重新标准化是有必要的, 但很奇怪之前作业范例中, 测试集的标准差和均值用的是训练集生成的.

试了试完整数据集预测时重新标准化, 效果不如5h( 和5h相似, 9.5 ), 也不如第一次.

担心是其他环节影响了数据, 控制变量, 只把std, mean换回来. 还真的没问题.

说明使用完整训练集预测时, 在测试集中, 输入数据的标准化时, 使用训练集的期望标准差, 结果好很多. 使用9h而非5h的训练集结果好很多.

就只剩下修改学习率了, 学习率根据第一问的最佳结果改成了1, 居然分数迅速变好, 5.57977

真是哭笑不得, 太菜了用了那么多馊主意改模型, 最后还不如调参数.

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值