测试集、训练集等相关文件下载:python | 预测24笔testing data中的PM2.5值【相关文件】
(本人上传的,内含代码)
文章目录
一、题目
预测 240 笔 testing data 中的 PM2.5 值
1.Upload format: csv file
2.第一行必须是 id ,value
3.第二行开始,每行分别为 id 值及预测 PM2.5 数值,以逗号隔开。
二、完整代码
直接无脑复制即可👍🏼
想知道具体实现方式,请看第三部分 代码详解 👀
#引入库
import os
import pandas as pd
import numpy as np
import math
import csv
#读入训练集
data=pd.read_csv("./train.csv", encoding="big5")
# 数据预处理
data=data.iloc[:,3:]
data=data.replace('NR',0)
numpy_data=data.to_numpy()
# 按月分割数据
month_data={}
for month in range(12):
sample=np.empty([18,480])
for day in range(20):
sample[:, day*24:(day+1)*24]=numpy_data[18*(20*month +day): 18*(20*month +day+1),:]
month_data[month]=sample
# 分割输入x和输出y数据
x=np.empty([12*471,9*18],dtype=float) # 前9时的18个特征值做输入
y=np.empty([12*471,1],dtype=float) # 第10时的pm2.5做输出
for month in range(12):
for day in range(20):
for hour in range(24):
# 如果是最后一天,最后一组,则返回
if day==19 and hour>14:
continue
# 每个小时的18项特征数据
x[month*471+day*24+hour,:]=month_data[month][:,day*24+hour:day*24+hour+9].reshape(1,-1)
# pm2.5的值
y[month*471+day*24+hour,0]=month_data[month][9,day*24+hour+9]
#将x做归一化处理
mean_x = np.mean(x, axis = 0)
std_x = np.std(x, axis = 0)
for i in range(len(x)):
for j in range(len(x[0])):
if std_x[j] != 0:
x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]
# 训练模型并保存权重
dim = 18 * 9 + 1
w = np.zeros([dim, 1])
x = np.concatenate((np.ones([12 * 471, 1]), x), axis = 1).astype(float)
learning_rate = 1
iter_time = 1001
adagrad = np.zeros([dim, 1])
eps = 1e-7
for t in range(iter_time):
loss = np.sqrt(np.sum(np.power(np.dot(x, w) - y, 2))/471/12)
if(t%100==0):
print(str(t) + ":" + str(loss))
gradient = 2 * np.dot(x.T, np.dot(x, w) - y)
adagrad += gradient ** 2
w = w - learning_rate * gradient / np.sqrt(adagrad + eps)
np.save('weight.npy', w)
#导入训练集并预处理
test_data=pd.read_csv("./test.csv",header=None, encoding="big5")
test_data=test_data.iloc[:,2:]
test_data=test_data.replace('NR','0' )
test_data=test_data.to_numpy()
#重新排列数据
test_x=np.empty([240,18*9], dtype=float) # 240个id,18*9个特征值
for i in range(240):
test_x[i, :] = test_data[18 * i: 18* (i + 1), :].reshape(1, -1)
# 重新排列训练集数据并做归一化处理
for i in range(len(test_x)):
for j in range(len(test_x[0])):
if std_x[j] != 0:
test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]
test_x = np.concatenate((np.ones([240, 1]), test_x), axis = 1).astype(float)
# 对训练集做预测
w=np.load("weight.npy")
ans_y=np.dot(test_x,w)
# 保存为csv文件
with open("submit.csv", mode="w",newline='') as submit_file:
csv_writer=csv.writer(submit_file)
header=['id','value']
#print(header)
csv_writer.writerow(header)
for i in range(240):
row=["id_" +str (i), ans_y[i][0]]
csv_writer.writerow(row)
print(row)
三、代码详解
1.引入库
import os
import pandas as pd
import numpy as np
import math
import csv
2.读入训练集
#读入训练集
data=pd.read_csv("./train.csv", encoding="big5")
print(data)
3.数据预处理
# 数据预处理
data=data.iloc[:,3:] #截取从第四列一直到结束
data=data.replace('NR',0) #NR置0
numpy_data=data.to_numpy()
#将数据格式转换为一个NumPy数组。(4320,24)(12月*18值*20天,24小时)
4.按月份分割数据
# 按月分割数据
month_data={}
# 每月数据量
for month in range(12): #12个月
sample=np.empty([18,480]) #18特征值,20天*24小时
# 每天数据量
for day in range(20): #20天
sample[:, day*24:(day+1)*24]=numpy_data[18*(20*month +day): 18*(20*month +day+1),:]
# 每天24小时,对应这个18个*24小时个数据。一个月的数据放一起,横向排放
month_data[month]=sample
5.分割输入x和输出y数据
# 分割x和y。每9小时为一组,每个月有471组,每组有9*18特征值。
x=np.empty([12*471,9*18],dtype=float) # 前9时的18个特征值做输入
y=np.empty([12*471,1],dtype=float) # 第10时的pm2.5做输出
for month in range(12):
for day in range(20):
for hour in range(24):
if day==19 and hour>14: # 如果是最后一天,最后一组,则返回
continue
# 每个小时的18项特征数据
x[month*471+day*24+hour,:]=month_data[month][:,day*24+hour:day*24+hour+9].reshape(1,-1)
# pm2.5的值
y[month*471+day*24+hour,0]=month_data[month][9,day*24+hour+9]
6.将x做归一化处理
#对x归一化
mean_x = np.mean(x, axis = 0) #18 * 9 ,对每列求平均值
std_x = np.std(x, axis = 0) #18 * 9 ,对每列求标准差
for i in range(len(x)): #12 * 471,5652个 列数
for j in range(len(x[0])): #18 * 9 行数
if std_x[j] != 0: #分母不为零
x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]
7.训练模型并保存权重
# 训练模型并保存权重
dim = 18 * 9 + 1 # 1为常数项
w = np.zeros([dim, 1])
#生成全为1的数组,与x行向拼接,浮点型
x = np.concatenate((np.ones([12 * 471, 1]), x), axis = 1).astype(float)
learning_rate = 1 #学习效率
iter_time = 1001 #迭代次数
adagrad = np.zeros([dim, 1])
eps = 1e-7 # 防止被除数为0
for t in range(iter_time):
# 平方差
loss = np.sqrt(np.sum(np.power(np.dot(x, w) - y, 2))/471/12) #均方根误差
if(t%100==0): # 每100次输出一次
print(str(t) + ":" + str(loss))
# 梯度
gradient = 2 * np.dot(x.T, np.dot(x, w) - y) #维数是(dim,1)
adagrad += gradient ** 2
w = w - learning_rate * gradient / np.sqrt(adagrad + eps)
np.save('weight.npy', w) #存数据
8.导入训练集并预处理
#导入测试集
test_data=pd.read_csv("./test.csv",header=None, encoding="big5")
test_data=test_data.iloc[:,2:] #不要前两列
test_data=test_data.replace('NR','0' )#NR置0
test_data=test_data.to_numpy()
9.重新排列训练集数据并做归一化处理
#重新排列数据
test_x=np.empty([240,18*9], dtype=float) # 240个id,18*9个特征值
for i in range(240):
test_x[i, :] = test_data[18 * i: 18* (i + 1), :].reshape(1, -1)
# 归一化
for i in range(len(test_x)):
for j in range(len(test_x[0])):
if std_x[j] != 0:
test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]
test_x = np.concatenate((np.ones([240, 1]), test_x), axis = 1).astype(float)
10.对训练集做预测
# 对test的x进行预测,得到预测值ans_y
w=np.load("weight.npy")
ans_y=np.dot(test_x,w)
11.保存结果
# 保存为csv文件
# mode="w":打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
# newline是换行控制的参数
with open("submit.csv", mode="w",newline='') as submit_file: #"submit.csv"为输出结果的文件名
csv_writer=csv.writer(submit_file)
header=['id','value']
print(header)
csv_writer.writerow(header)
for i in range(240):
row=["id_" +str (i), ans_y[i][0]]
csv_writer.writerow(row)
print(row)
最终结果在保存在"submit.csv"文件中。