机器学习——PM2.5预测白话
本项目仅用于参考,提供思路和想法并非标准答案!请谨慎抄袭!
作业1-PM2.5预测
项目描述
- 本次作业的资料是从行政院环境环保署空气品质监测网所下载的观测资料。
- 希望大家能在本作业实现 linear regression 预测出 PM2.5 的数值。
数据集介绍
- 本次作业使用丰原站的观测记录,分成 train set 跟 test set,train set 是丰原站每个月的前 20 天所有资料。test set 则是从丰原站剩下的资料中取样出来。
- train.csv: 每个月前 20 天的完整资料。
- test.csv : 从剩下的资料当中取样出连续的 10 小时为一笔,前九小时的所有观测数据当作 feature,第十小时的 PM2.5 当作 answer。一共取出 240 笔不重複的 test data,请根据 feature 预测这 240 笔的 PM2.5。
- Data 含有 18 项观测数据 AMB_TEMP, CH4, CO, NHMC, NO, NO2, NOx, O3, PM10, PM2.5, RAINFALL, RH, SO2, THC, WD_HR, WIND_DIREC, WIND_SPEED, WS_HR。
项目要求
- 请手动实现 linear regression,方法限使用 gradient descent。
- 禁止使用 numpy.linalg.lstsq
数据准备
无
环境配置/安装
数据解读
对数据进行理解和了解后数据如图:
横向分别是24小时的数据值
竖向是12个月、每月20天、每天18种数据
!pip install --upgrade pandas
Looking in indexes: https://mirror.baidu.com/pypi/simple/
Requirement already up-to-date: pandas in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (1.2.3)
Requirement already satisfied, skipping upgrade: pytz>=2017.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pandas) (2019.3)
Requirement already satisfied, skipping upgrade: python-dateutil>=2.7.3 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pandas) (2.8.0)
Requirement already satisfied, skipping upgrade: numpy>=1.16.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from pandas) (1.20.1)
Requirement already satisfied, skipping upgrade: six>=1.5 in /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)
导入需要的包,读取训练集
import numpy as np
import pandas as pd
data = pd.read_csv('work/hw1_data/train.csv', encoding = 'big5') # 使用'big5'进行编码
print(data) # 查看数据
print(data.shape) # 查看数据大小
0 1 2 3 4 5 6 7 8 9 ... 14 \
0 14 14 14 13 12 12 12 12 15 17 ... 22
1 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 ... 1.8
2 0.51 0.41 0.39 0.37 0.35 0.3 0.37 0.47 0.78 0.74 ... 0.37
3 0.2 0.15 0.13 0.12 0.11 0.06 0.1 0.13 0.26 0.23 ... 0.1
4 0.9 0.6 0.5 1.7 1.8 1.5 1.9 2.2 6.6 7.9 ... 2.5
... ... ... ... ... ... ... ... ... ... ... ... ...
4315 1.8 1.8 1.8 1.8 1.8 1.7 1.7 1.8 1.8 1.8 ... 1.8
4316 46 13 61 44 55 68 66 70 66 85 ... 59
4317 36 55 72 327 74 52 59 83 106 105 ... 18
4318 1.9 2.4 1.9 2.8 2.3 1.9 2.1 3.7 2.8 3.8 ... 2.3
4319 0.7 0.8 1.8 1 1.9 1.7 2.1 2 2 1.7 ... 1.3
15 16 17 18 19 20 21 22 23
0 22 21 19 17 16 15 15 15 15
1 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8
2 0.37 0.47 0.69 0.56 0.45 0.38 0.35 0.36 0.32
3 0.13 0.14 0.23 0.18 0.12 0.1 0.09 0.1 0.08
4 2.2 2.5 2.3 2.1 1.9 1.5 1.6 1.8 1.5
... ... ... ... ... ... ... ... ... ...
4315 1.8 2 2.1 2 1.9 1.9 1.9 2 2
4316 308 327 21 100 109 108 114 108 109
4317 311 52 54 121 97 107 118 100 105
4318 2.6 1.3 1 1.5 1 1.7 1.5 2 2
4319 1.7 0.7 0.4 1.1 1.4 1.3 1.6 1.8 2
[4320 rows x 24 columns]
(4320, 24)
取需要的数值部分,将 ‘RAINFALL’ 栏位全部补 0。
对数据进行查看后发现有缺失的数据,对缺失数据进行处理,填补缺失值。
读取的数据中有部分解释性的内容,我们不需要,可以进行提取直接忽略
data.iloc[:,:]
该函数用于处理数据,把我们需要的部分进行切割获取
data[data == 'xxx'] = 0
把xxx的内容替换成0
data = data.iloc[:, 3:] # 从列表的第4路项开始取(不要那些没有意义的数字)
print(data) #查看数据
print(data.shape) #查看数据大小
print(type(data))
data[data == 'NR'] = 0 # 把'NR'项装换成0
raw_data = data.to_numpy() # 把数据转换成numpy数组
0 1 2 3 4 5 6 7 8 9 ... 14 \
0 14 14 14 13 12 12 12 12 15 17 ... 22
1 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 ... 1.8
2 0.51 0.41 0.39 0.37 0.35 0.3 0.37 0.47 0.78 0.74 ... 0.37
3 0.2 0.15 0.13 0.12 0.11 0.06 0.1 0.13 0.26 0.23 ... 0.1
4 0.9 0.6 0.5 1.7 1.8 1.5 1.9 2.2 6.6 7.9 ... 2.5
... ... ... ... ... ... ... ... ... ... ... ... ...
4315 1.8 1.8 1.8 1.8 1.8 1.7 1.7 1.8 1.8 1.8 ... 1.8
4316 46 13 61 44 55 68 66 70 66 85 ... 59
4317 36 55 72 327 74 52 59 83 106 105 ... 18
4318 1.9 2.4 1.9 2.8 2.3 1.9 2.1 3.7 2.8 3.8 ... 2.3
4319 0.7 0.8 1.8 1 1.9 1.7 2.1 2 2 1.7 ... 1.3
15 16 17 18 19 20 21 22 23
0 22 21 19 17 16 15 15 15 15
1 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8 1.8
2 0.37 0.47 0.69 0.56 0.45 0.38 0.35 0.36 0.32
3 0.13 0.14 0.23 0.18 0.12 0.1 0.09 0.1 0.08
4 2.2 2.5 2.3 2.1 1.9 1.5 1.6 1.8 1.5
... ... ... ... ... ... ... ... ... ...
4315 1.8 2 2.1 2 1.9 1.9 1.9 2 2
4316 308 327 21 100 109 108 114 108 109
4317 311 52 54 121 97 107 118 100 105
4318 2.6 1.3 1 1.5 1 1.7 1.5 2 2
4319 1.7 0.7 0.4 1.1 1.4 1.3 1.6 1.8 2
[4320 rows x 24 columns]
(4320, 24)
<class 'pandas.core.frame.DataFrame'>
print(raw_data.shape) # 查看数组大小
print(type(raw_data)) # 查看类型
(4320, 24)
<class 'numpy.ndarray'>
将原始 4320 * 24 的资料依照每个月分重组成 12 个 18 (features) * 480 (hours) 的资料。
从原先的24*(18*20*12)
转换成12*18*(20*24)
month_data = {
}
for month in range(12):
sample = np.empty([18, 480]) # 新建np数组大小是[18, 480]内容随机
for day in range(20):
sample[:, day * 24 : (day + 1) * 24] = raw_data[18 * (20 * month + day) : 18 * (20 * month + day + 1), :]
month_data[month] = sample
# print(len(month_data),len(month_data[0])) # 大小查看
# print(month_data) # 数据查看
print(month_data[month]