数据: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)
数据中给了有效数据(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,)
先进行公式的理解、推导。具体可以看自行看链接里面的梯度下降的推导过程。附上简略推导。
我们可以知道,Yp=a*x+b中a、b的更新方法。在此作业中,我们暂时忽略b,只需要同时算出18*9个独立a,便可以得到Yp的函数。最后将测试数据的18*9个x带入函数,就可以得到Yp预测值。
#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.将预测值与正确值相比较,并由此判断我们模型的优秀程度。