預測PM2.5----李宏毅機器學習作業HW1

作業說明

數據:train.csv 訓練集,包含1年*12個月*20天*24小時*18種污染物的測試值

           test.csv 測試集, 包含240個例子*18種污染物*9小時的測試值

           ans.csv 結果集, 是測試集內容應該有的結果,即標準值,包含240個數字

題目簡述:給出訓練集,要求使用梯度下降的方法,建立一個模型,輸入數據是空氣污染物連續九個小時含量,輸出數據是連續九小時之後的第十個小時的PM2.5的含量(如輸入是1-9小時,則輸出第10小時,輸入2-10小時,輸出第11小時)。使用我們訓練的模型,對測試集進行處理,得出我們的預測值。我們可以用結果集對比我們的預測值,看我們的模型的優秀程度。

學習資料:李宏毅作業及作業數據來源

                  線性迴歸預測PM2.5----臺大李宏毅機器學習作業1(HW1)

解題步驟

1.數據處理

數據中給了有效數據(12個月*20天*18個污染物)行、(24小時)列。我們以連續10個小時訓練,前9個是訓練數據,第10個是標準答案。


數據處理的代碼片段

# 讀取訓練數據
print('下載訓練數據')
train = pd.read_csv('F:/machine/HW1/data/train.csv',  usecols=range(3,27), encoding='big5')
train = train.replace(['NR'], [0.0])
array = np.array(train).astype(float)

x_list, y_list = [], []
for i in range(0, 4320, 18):
    for j in range(24-9):
        mat = array[i:i+18, j:j+9].flatten()
        label = array[i+9, j+9]
        x_list.append(mat)
        y_list.append(label)
train_x = np.array(x_list)  # 訓練數據 (3600, 18*9) 3600=15*240
train_y = np.array(y_list)  # 訓練數據的答案值(3600,)

2.SDG模型的建立

先進行公式的理解、推導。具體可以看自行看鏈接裏面的梯度下降的推導過程。附上簡略推導。

我們可以知道,Yp=a*x+b中a、b的更新方法。在此作業中,我們暫時忽略b,只需要同時算出18*9個獨立a,便可以得到Yp的函數。最後將測試數據的18*9個x帶入函數,就可以得到Yp預測值。

SGD的代碼片段

#Stochasitc Gradient Desent
print('訓練SDG')
def SGD(X, Y, w, eta=0.0001, iteration=20000, lambdaL2=0):
    list_cost = []
    for i in range(iteration):
        hypo = np.dot(X, w)
        loss = hypo - Y
        cost = np.sum(loss**2)/len(X)
        list_cost.append(cost)

        rand = np.random.randint(0, len(X))
        grad = loss[rand]*X[rand]/len(X)
        w = w - eta*grad
    return  w, list_cost

完整代碼

import csv, os
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import inv
import random
import math
import sys
import pandas as pd

# 讀取訓練數據
print('下載訓練數據')
train = pd.read_csv('F:/machine/HW1/data/train.csv',  usecols=range(3,27), encoding='big5')
train = train.replace(['NR'], [0.0])
array = np.array(train).astype(float)

x_list, y_list = [], []
for i in range(0, 4320, 18):
    for j in range(24-9):
        mat = array[i:i+18, j:j+9].flatten()
        label = array[i+9, j+9]
        x_list.append(mat)
        y_list.append(label)
train_x = np.array(x_list)  # (3600, 18*9) 3600=15*240
train_y = np.array(y_list)  # (3600,)


#Stochasitc Gradient Desent
print('訓練SDG')
def SGD(X, Y, w, eta=0.0001, iteration=20000, lambdaL2=0):
    list_cost = []
    for i in range(iteration):
        hypo = np.dot(X, w)
        loss = hypo - Y
        cost = np.sum(loss**2)/len(X)
        list_cost.append(cost)

        rand = np.random.randint(0, len(X))
        grad = loss[rand]*X[rand]/len(X)
        w = w - eta*grad
    return  w, list_cost

# train data
w = np.zeros(train_x.shape[1])  # (162,)
w_sdg, _ = SGD(train_x, train_y, w)
print('權重的值:', w_sdg.shape, w_sdg)

# load test data
print('下載測試數據')
test = pd.read_csv('F:/machine/HW1/data/test.csv',  usecols=range(2,11), header=None, encoding='big5')
test = test.replace(['NR'], [0.0])
test_array = np.array(test).astype(float)  # (4320, 9)
test_data = []
for i in range(0, 4320, 18):
    mat = test_array[i:i+18, 0:9].flatten()
    test_data.append(mat)
test_data = np.array(test_data)  # (240, 162)

# 預測值, 並保存
print ('開始預測')
my_ans = np.dot(test_data, w_sdg)
my_ans = my_ans.astype(int)
np.savetxt('F:/machine/HW1/data/my_ans.csv', my_ans)

# 分析誤差
print('下載答案,分析誤差')
ans = pd.read_csv('F:/machine/HW1/data/ans.csv',  usecols=[1], encoding='big5')
ans = np.array(ans).astype(int).flatten()
loss = ans-my_ans
print('ans', ans.shape, ans)
print('my_ans', my_ans.shape, my_ans)
print('loss', loss.shape, loss)
loss = np.sum(loss)/ len(ans)
print('結果誤差loss是', loss)


代碼成果

可以接受。平均誤差較小,也有較符合的部分。仍然有部分差異很大。

總結

我們其實就是:1.將訓練數據安排好,2.訓練出一個模型,3.將測試數據放入模型,4.得到預測值。5.將預測值與正確值相比較,並由此判斷我們模型的優秀程度。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章