李宏毅Machine Learning HW1(利用线性回归预测PM2.5的数值)

一、概述
本次任务的目的是利用Liner Regression去预测丰原市PM2.5的数值。对丰原市一年的观测记录分为了train set和test set,其中train set 是丰原市每个月前20天的所有记录。test set则是从丰原市剩下的记录取样出来。train set和test set都是以csv格式的文件进行保存的。
train.csv:每个月前20天的完整资料
test.csv:从剩下的资料当中取样出连续的10小时为一组,前九个小时的所有观测数据当中feature,第十个小时的PM2.5当中answer。一共取出240组不重复的test data,然后根据feature去预测出第十小时的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。
Training Data展示:
在这里插入图片描述
Testing Data展示:
在这里插入图片描述
二、模型选择
本次任务的模型选择为:
在这里插入图片描述
i从0到8是因为选取前九个小时作为输入,每个输入都有一个w与之相乘,然后加上一个偏置b,通过这个模型去预测第十个小时的PM2.5的值。
这里可以将运算转换成向量运算,具体如下:
在这里插入图片描述
选择的Loss Function为:
在这里插入图片描述
在Loss当中,加入了Regularization选项,都乘以1/2是为了对Loss求导后能够把2约掉。
Loss对wj求偏导为:
在这里插入图片描述
Loss对b求偏导为:

在这里插入图片描述
参数更新:
在这里插入图片描述
在这里插入图片描述
这里可以将wj的更新转换成向量运算,具体如下:
在这里插入图片描述
Optimizer的选择:
本次任务主要选择Adagrad来优化模型,在Adagrad中,不同参数更新所使用的学习率在不停的变化。Adagrad的更新参数的方式如下:
在这里插入图片描述
其中,gt为wt的梯度值,而
在这里插入图片描述
在这里插入图片描述
所以得到:
在这里插入图片描述
三、数据预处理
train.csv当中保存的是丰原市一年当中每个月前20天的观测数据,由于每次输入的数据为前9个小时的PM2.5的数值,第10个小时的数值用来做label,所以一天当中的PM2.5的观测数据可以分为15组(15=24-10+1)。因此,train.csv当中的数据可以分为3600组(3600=122015)。当然为了增加数据量,也可以将数据分为5652组(5652=12*(20*24-10+1)),这是因为我们是连续取出前9个小时的PM2.5的值作为输入,第10个小时的数据值作为label。这里我只是将train.csv分为了3600组。
数据预处理代码如下:

#数据预处理
def dataProcess(df):
    x_list, y_list = [], []
    #将df中的空数据填为0
    df = df.replace(['NR'], [0.0])
    #将所有数据转换成float类型
    array = np.array(df).astype(float)
    #将数据集拆分成多个数据帧
    for i in range(0, 4320, 18): #18*240 = 4320(len(array)
        for j in range(15): #24-9=15(组)
            mat = array[i:i+18][9][j:j+9] #截取PM2.5前9项作为训练,i:i+18表示一天中的所有数据项,[9]表示第9行数据,也就是PM2.5,[j:j+9]表示前九小时的数据
            lable = array[i:i+18][9][j+9] #截取PM2.5第十项作为lable,[j+9]表示第十小时的PM2.5的值
            x_list.append(mat)
            y_list.append(lable)
    x = np.array(x_list)
    y = np.array(y_list)
    return x, y, array

因为train.csv文件当中RAINFALL这一项给的是NR,由于这一项对本次任务没有太多的联系,所以将它全部替换成0值表示。
数据预处理得到的x,y的shape为
在这里插入图片描述
四、训练模型

#训练模型,从训练集中拿出3200个数据用来训练,400个数据用来验证
def trainModel(x_data, y_data, epoch):
    bias = 0 #初始化偏置
    weight = np.ones(9) #生成一个9列的行向量,并全部初始化为1
    learning_rate = 1 #初始化学习率为1
    reg_rate = 0.001 #初始化正则项系数为0.001
    bias_sum = 0  # 用于存放偏置的梯度平方和
    weight_sum = np.zeros(9)  # 用于存放权重的梯度平方和
    for i in range(epoch):
        b_g = 0 #bias梯度平均值
        w_g = np.zeros(9) #weight梯度平均值
        #在所有数据上计算w和b的梯度
        for j in range(3200):
            b_g += (y_data[j] - weight.dot(x_data[j]) - bias) * (-1) #如果两个一维向量dot,则结果为它们的内积
            for k in range(9):
                w_g[k] += (y_data[j] - weight.dot(x_data[j]) - bias) * (-x_data[j, k])
        #求平均值
        b_g /= 3200
        w_g /= 3200
        for k in range(9):
            w_g[k] += reg_rate * weight[k]
        #adagrad优化方式
        bias_sum += b_g ** 2
        weight_sum += w_g ** 2
        bias -= learning_rate / (bias_sum ** 0.5) * b_g
        weight -= learning_rate / (weight_sum ** 0.5) * w_g

        #每训练200次输出一次误差
        if i % 200 ==0:
            loss = 0
            for j in range(3200):
                loss += (y_data[j] - weight.dot(x_data[j]) - bias) ** 2
            loss /= 3200
            for j in range(9):
                loss += reg_rate * (weight[j] ** 2)
            print('after {} epoch, the loss on the train_set is {:.2f}'.format(i, loss / 2))
    return weight, bias

训练结果如下:
在这里插入图片描述
五、测试模型

#用测试数据集测试模型
def testModel(x_test, weight, bias):
    f = open("ouput.csv", 'w', encoding='utf-8', newline="")
    csv_write = csv.writer(f)
    csv_write.writerow(["id", "value"])
    for i in range(len(x_test)):
        output = weight.dot(x_test[i]) + bias
        csv_write.writerow(["id_" + str(i), str(output)])
    f.close()

测试结果保存在output.csv当中,结果如下:
在这里插入图片描述
六、总结
由于本次任务选择的模型较为简单,而且训练数据集也并没有按照正规方法分为training data和validation data,只是简单地将前3200项作为training data,后400项作为validation data;此外,本次训练只考虑了PM2.5作为输入,其他观测信息并未使用,所以可能并没有达到很好的效果。在这个模型当中,感觉增加Regularization并未起多大的作用。
七、完整代码和相关数据
https://github.com/Timothiy/Machine_Learning

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值