作業說明
數據: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.將預測值與正確值相比較,並由此判斷我們模型的優秀程度。