iT邦幫忙

0

Arima 預測空氣品質

  • 分享至 

  • xImage

目前利用Arima方法預測李宏毅的作業一
我已經把資料分割了

https://ithelp.ithome.com.tw/upload/images/20200216/20122463gHExYd7JaW.png
行的名稱0~8代表時間0點~8點
列是pm2.5所在的位置
格式是dataframe

然後我現在卡在我是要把資料轉成一行好幾列
還是可以就以這樣格式去計算後續的差分?

我使用直接用這格式計算會出現錯誤
https://ithelp.ithome.com.tw/upload/images/20200216/20122463FpRjjgNUYa.png
https://ithelp.ithome.com.tw/upload/images/20200216/20122463yKD574JH7V.png
temx是上面顯示的格式

想問有沒有比較好的方法?
因為網路上介紹的方式都是選一行其中的資料然後有好幾列代表不同天的格式
剛學習Arima所以不太懂

我是參考时间序列预测任务 4 4 股票预测案例的方法來去做預測

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2020-02-16 23:42:27 檢舉
你錯誤訊息是跳str和str不能相減...
把所有data都轉成int再說吧。

另外矩陣有個運算叫轉置(transpose)...

學大數據之前先把每天要用的工具python、numpy、pandas、和線性代數好好惡補一下吧。
fillano iT邦超人 1 級 ‧ 2020-02-17 06:15:48 檢舉
資料沒整理過你是要怎麼使用啦,你先把pm2.5挑出,然後把日期欄加上時間,最後資料只會有兩欄,就是時間跟pm2.5,存成csv,然後再給pandas讀。

如果不是處理每小時,而是每日,可以用excel加一欄算平均值,然後過濾pm2.5,最後只把日期跟平均挑出來,存成你要的資料,這樣可能簡單一點。
fillano iT邦超人 1 級 ‧ 2020-02-17 10:14:15 檢舉
看起來你要直接處理test.csv?但是這個並不能用來建立模型,你要用train.csv。
lingwu iT邦新手 5 級 ‧ 2020-02-17 14:10:11 檢舉
上面的數字是pm2.5
我是用train.csv裡的資料作擷取的
fillano iT邦超人 1 級 ‧ 2020-02-18 16:59:45 檢舉
然後?他train.csv的資料有間斷,test.csv也一樣,假設他沒間斷也不是不能跑就是了。

我是把所有PM2.5讀成list,然後用test.csv的每一筆PM2.5來iterate(有九個資料、那個作業是要求預測第十個),然後跟ans.csv作比較。過程中會把test.csv跟ans.csv資料加回到list,所以每次iterate都跑一次自動選order、建model、fit還有predict。這樣會跑很久就是了。不這樣跑,會出現序列不平穩的錯誤。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
fillano
iT邦超人 1 級 ‧ 2020-02-19 09:52:59

用討論裡面的方法,因為自動選擇order會跑太久,所以改用(1,0,1)來跑:

https://ithelp.ithome.com.tw/upload/images/20200219/20000108xoXhT7UVZg.png

expect是ans.csv提供的正確答案,predict是跑出來的預測

2020-02-19 13:54 補充

myorder = sm.tsa.arma_order_select_ic(v, max_ar=5, max_ma=4, ic='aic')
lag_ar = myorder.aic_min_order[0]
lag_ma = myorder.aic_min_order[1]
lmodel = tsa.arima_model.ARIMA(v, order=(lag_ar, 0, lag_ma))

跑,實在花太多時間,而且沒改進多少:

https://ithelp.ithome.com.tw/upload/images/20200219/20000108ohwTdVFchi.png

看更多先前的回應...收起先前的回應...
lingwu iT邦新手 5 級 ‧ 2020-02-19 21:24:21 檢舉

所以你沒有使用train.csv裡面資料做選出model嗎?

fillano iT邦超人 1 級 ‧ 2020-02-20 09:30:04 檢舉

是用train.csv,但是加上walk forward optimization,所以每預測一筆test.csv的第十小時,都會把test.csv跟ans.csv加入train.csv重新跑。

我只用了arma_order_select_ic來決定(p, q),不過看起來用(1,1)就夠好了。

lingwu iT邦新手 5 級 ‧ 2020-02-20 14:21:01 檢舉

請問你怎麼預測第十小時的資料的?
https://ithelp.ithome.com.tw/upload/images/20200220/20122463PFNcjvviFk.png
上面是我存的資料,格式是dataframe

pred = result.predict(start=str('9'),end=str('9'),dynamic=False)

這是我打要預測第十筆資料
只是會顯示下列錯誤
https://ithelp.ithome.com.tw/upload/images/20200220/20122463TaG5LkkWfi.png

fillano iT邦超人 1 級 ‧ 2020-02-21 09:28:17 檢舉

用9不行嗎?str是要給時間用的。

lingwu iT邦新手 5 級 ‧ 2020-02-23 15:03:35 檢舉

可以了!謝謝

lingwu iT邦新手 5 級 ‧ 2020-02-24 16:04:28 檢舉

請問可以問你完整的程式碼怎麼打的嗎?
我自己跑出來是長下面那樣
https://ithelp.ithome.com.tw/upload/images/20200224/201224639oWLYZAkvM.png

我order也是選(1,0,1)
感覺你的預測結果誤差比較小

fillano iT邦超人 1 級 ‧ 2020-02-24 17:17:08 檢舉
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import statsmodels.tsa as tsa
import numpy as np
import statsmodels.graphics.tsaplots as ts
from sklearn.utils.testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning
from sklearn.metrics import mean_squared_error


@ignore_warnings(category=ConvergenceWarning)
def resolve(data, test25, ans):
    result_predict = list()
    result_answer = list()
    for i in range(len(test25.values)):
        for j in range(9):
            data.append(float(test25.values[i][j + 2]))
        v = np.array(data)
        #myorder = sm.tsa.arma_order_select_ic(v, max_ar=5, max_ma=4, ic='aic')
        #lag_ar = myorder.aic_min_order[0]
        #lag_ma = myorder.aic_min_order[1]
        lag_ar = 1
        lag_ma = 1
        lmodel = tsa.arima_model.ARIMA(v, order=(lag_ar, 0, lag_ma))
        lfitted = lmodel.fit(display=-1)
        pre = lfitted.predict(len(v) + 1, len(v) + 1)
        answer = float(ans[i][0])
        print('iter: %d, predict: %.3f, answer: %.3f' % (i, pre[0], answer))
        data.append(answer)
        result_predict.append(pre[0])
        result_answer.append(answer)
    return result_predict, result_answer


df = pd.read_csv('hw1/train.csv')

pm25 = df[df['測項'].str.contains('PM2.5')]

data = list()
for x in pm25.values:
    for y in range(24):
        data.append(float(x[y + 3]))

test = pd.read_csv('hw1/test.csv', header=None)
test.columns = ['id', 'type', '0', '1', '2', '3', '4', '5', '6', '7', '8']
test25 = test[test['type'].str.contains('PM2.5')]

ans = pd.read_csv('hw1/ans.csv')
ans.columns = ['id', 'val']
ans.set_index('id', inplace=True)

predict, expect = resolve(data, test25, ans.values)

mse = mean_squared_error(expect, predict)
print('mean square error: %.3f' % mse)

final = pd.DataFrame()

final['original'] = expect
final['predict'] = predict
final.plot(figsize=(20, 10))
plt.show()

這樣mse是53.683,不過得跑好幾分鐘。

lingwu iT邦新手 5 級 ‧ 2020-02-25 21:40:25 檢舉

好的,我研究看看 謝謝!

我要發表回答

立即登入回答