• 【李宏毅】机器学习——作业1-PM2.5预测


    作业代码地址:点我

    1.分析数据

    训练集

    列是时间,一共24列,是每天的24小时
    行是检测的特征值,每次会检测18个特征值,故每18行是一天的数据
    一个月20天,一年12个月,所以一共18*20*12行的数据
    可以在

    测试集

    给了连续9个小时的数据,预测第十个小时的PM2.5的值
    在这里插入图片描述
    看上图可知,我们需要训练的Model的 input应该是这18个测量数据在9个小时内的所有测量值,而 output则是第10个小时的PM2.5的值

    2.数据的预处理

    首先删除无用的数据
    删除前三列数据,前三列是日期,测站,测项
    然后替换掉非数字数据
    将降雨量对应的一行NR替换成0
    最后将数据转换为numpy

    import pandas as pd
    import numpy as np
    import csv
    import math
    
    # 下载csv文件到内存
    data = pd.read_csv('./train.csv', encoding='big5')
    # 保留数据部分 删除前三列(日期,测站,测项)
    data = data.iloc[:, 3:]
    # 替换数据中的NR
    data[data=='NR'] = 0
    # 转换为numpy
    raw_data = data.to_numpy()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    打印第一行raw_data[0]:

    [‘14’ ‘14’ ‘14’ ‘13’ ‘12’ ‘12’ ‘12’ ‘12’ ‘15’ ‘17’ ‘20’ ‘22’ ‘22’ ‘22’
    ‘22’ ‘22’ ‘21’ ‘19’ ‘17’ ‘16’ ‘15’ ‘15’ ‘15’ ‘15’]

    3.提取特征

    根据测试数据来划分训练数据,测试数据的输入是9个小时的数据,每次输入18行,所以我们可以先将测试集划分为只有18行的数据,方法如下:
    想只留下18行,剩下数据就可以拼接到这18行的右侧(不区分天数,我们只关心连续的小时
    18行24列是一天的数据,一个月的20天也就是20x18行24列的数据,我们可以每个月的这20天的数据每18行都拼接到右侧,这样每个月就是20x24列,一个12个月
    如下图所示(略粗糙,最后那个是12月)
    在这里插入图片描述

    另外,因为是只有前9个小时作为输入,所以数据集还要按照每10列划分为一组(输入9,另外1列作为target),每个月是480列,按照每次移动一步来划分数据集,划分完一共是471组数据。每一组的输入都用reshape扁平化为向量。

    # 将数据分组 每10个为一组 每个月是471组 12个月 每一组都是18x9 另外一个18x1作为target
    x = np.empty((12*471, 18*9))
    y = np.empty((12*471, 1))
    
    for month in range(12):
        for hour in range(471): #每个月的471个数据
            # 每次取9个小时的数据作为一组 将数据扁平化为向量
            x[month*471+hour] = month_data[month][:, hour:hour+9].rashape(1,-1)
            y[month*471+hour] = month_data[month][:, 9, hour+9]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.归一化

    归一化,即对每个特征,求其均值和标准差。然后将每个数值都减去其均值后再除以标准差,这样特征的期望就变成了0,标准差变成1。

    # 归一化
    # axis=0表示跨行 也就是按列求 因为每一列是一个小时的所有特征值 
    # 所以我们按列求每个小时的特征值的均值和方差做归一化
    mean_x = np.mean(x, axis=0)
    std_x = np.std(x, axis=0)
    
    for i in range(18*9):
        if std_x[i] != 0:
            x[:, i] = (x[:i]-mean_x[i]) / std_x[i]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.将数据分为训练集和验证集

    #将训练集划分为训练集和验证集,共分total组,取第i组作为验证集
    def reArrangeTrainValidation(x,i=0,total=5):
        group_size = int(len(x) / total)  # 分total组
        x_train=np.concatenate((x[:group_size*i],x[group_size*(i+1):]),axis=0)
        y_train=np.concatenate((y[:group_size*i],y[group_size*(i+1):]),axis=0)
        x_validation=x[group_size*i:group_size*(i+1)]
        y_validation=y[group_size*i:group_size*(i+1)]
        return (x_train,y_train),(x_validation,y_validation)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    6.定义模型开始训练

    • 在GradientDescent的环节中采用的就是n次函数
    • GradientDescent的时候还是使用的残差平方和来计算梯度
    • 采用Adagrad优化算法
    # 定义模型 训练
    def computeY(n,x,w):#根据权重和输入计算输出
        py = np.zeros([len(x), 1])
        for e in range(1 + n):#e为当前x的次幂。e=0表示常数项,这里常数项并没有合并为一个,而是一个特征一个常数项。
            py += np.dot(x ** e, w[e])#w[e]表示ax^e中的系数a构成的向量
        return py
    
    def gradientDescent(n, x, y): # n:采用n次函数
        dim = 18*9
        w = [np.zeros([dim, 1]) for e in range(1 + n)] #权重
        adagrad = [np.zeros([dim, 1]) for e in range(1+n)] #adagrad中的梯度累计变量
        learning_rate = 100 # 学习率
        epoch = 10000 # 训练次数
        eps = 0.0000000001
        for t in range(epoch):
            py = computeY(n, x, w) # 通过输入得到预测输出
            loss = np.sqrt(np.sum(np.power(py - y, 2)) / len(x)) # 计算损失
            if(t % 100==0):
                print(str(t) + ":" + str(loss))
            for e in range(1+n): # 梯度下降和优化
                gradient = 2 * np.dot(x.transpose() ** e, py - y)
                adagrad[e] += gradient ** 2
                w[e] = w[e] - learning_rate / np.sqrt(adagrad[e] + eps) * gradient
            for e in range(1 + n): # 保存模型
                np.save(str(e) + '.weight.npy', w[e])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    7.测试数据集处理

    测试数据集和训练数据集做相同的处理

    # 对测试数据集做同样的处理
    #载入testing data,对其做相同的处理
    testdata=pd.read_csv('./test.csv',header = None,encoding='big5')#header=None说明没有头部,不写的话第一行不会读取到数据中
    test_data=testdata.iloc[:,2:]
    test_data[test_data=='NR']=0
    test_data=test_data.to_numpy()
    test_x=np.empty([240,18*9],dtype=float)
    for i in range(240):
        test_x[i]=test_data[i*18:(i+1)*18,:].reshape(1,-1)
    
    for i in range(18*9):
        if std_x[i] !=0:
            test_x[:,i]=(test_x[:,i]-mean_x[i])/std_x[i]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    8.对测试集做预测

    将上一步训练保存的模型权值直接下载下来用于训练

    #载入权重
    w=[]
    for e in range(1+n):
        w.append(np.load(str(e)+'.weight.npy'))
    
    • 1
    • 2
    • 3
    • 4

    做预测(输入x得到输出,computeY函数)

    py=computeY(n,test_x,w)
    
    • 1

    9.保存模型

    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), py[i][0]]
            csv_writer.writerow(row)
            print(row)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    参考文献
    李宏毅 2020机器学习作业1 详细解析
    李宏毅机器学习特训营-机器学习作业1-PM2.5预测

  • 相关阅读:
    linux之shell
    level=warning msg=“failed to retrieve runc version: signal: segmentation fault“
    [机器学习笔记]K-means聚类——进行广告效果分析
    【Android安全】Android中的Intent
    Python中lambda函数&eval()函数&递归的详细用法
    ElasticSearch7.3学习(三十二)----logstash三大插件(input、filter、output)及其综合示例
    Java的NIO体系
    预约上门系统软件小程序app如何搭建
    【brpc学习实践四】异步请求案例详解
    Mac电脑好用的窗口管理软件 Magnet 中文for mac
  • 原文地址:https://blog.csdn.net/m0_51474171/article/details/127739808