ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

李宏毅机器学习2020春季作业

2021-04-23 18:33:19  阅读:185  来源: 互联网

标签:12 李宏毅 春季 test 471 2020 18 np data


参考自https://blog.csdn.net/qq_46126258/article/details/112468420?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

第一次写机器学习的作业,基本上都是借鉴,但是也发现该博主在gradient descent 的 gradient和loss计算时的错误。

实验数据及jupyternotebook 代码

链接:https://pan.baidu.com/s/1koHjoEkpEy7SsLOFRp6Oxg
提取码:ux8i
复制这段内容后打开百度网盘手机App,操作更方便哦

实验环境

  • python 3.8
  • jupyter notebook + chrome

实验目的

  • 利用每天前 9个小时的18个特征,来预测第十个小时的pm2.5
  • 给定一个训练集数据和测试集数据,学会对数据的预处理
  • 熟悉regression的线性模型,并且用Gradient Descent 和Adamgrad 来优化模型

具体实验步骤

  1. 加载数据
# 导入所需要的的包
import sys
import pandas as pd 
import numpy as np
data = pd.read_csv('data/train.csv', encoding = 'big5') 
  1. 观察数据
    每天有18项数据,并且RAINFALL存在不能处理的字符串,需要先将字符串更改为可操作的数字,便于操作vector
    在这里插入图片描述
data = data.iloc[:, 3:]  # 提取所有行,并且列从第三列开始
data[data == 'NR'] = 0  # data 和data[] 是不一样的,一个为int,一个为列表
raw_data = data.to_numpy() # 将data

作为一条python新狗,下面连接介绍了pandas 的iloc loc 的具体用法

--------------

  1. 特征提取
# 查看 .csv表格,我们观察到,去掉第一行表头,表中有 每月中前二十天的数据,每天24小时记录 18 行feature,
# 所以每天用 18 * 24 矩阵表示
# 一个月有 24 * 20 = 480 个小时,所以12个月由 18 行 * 12 * 480 列

month_data = {} # 按照month做索引,方便以后的数据查找,是一个三维矩阵
for month in range(12):##求12个每月
    sample = np.empty([18, 480])##初始化每月:18 * 480
    for day in range(20):##每个月的20天
        sample[:, day * 24 : (day + 1) * 24] = raw_data[18 * (20 * month + day) : 18 * (20 * month + day + 1), :]
    month_data[month] = sample# 将求好的单月赋值给 month_data
    
    
# 根据题目含义,分为训练集数据和测试集数据,前九个小时做训练集,第十个小时做验证集,所以将十个小时划分为一组。
# 所以可以0-9 为一组,其中0-8为训练集,9为测试集,同时1-10 又为一组
# 因此,可以会得到471组数据,最后一组长9小时,没有验证集 
# 一年有 12 * 471 = 5652 组数据,472 * 12 个测试集,每个测试集有 18 * 9 个feature,对应471 * 12个验证集:PM2.5

x = np.empty([12 * 471, 18 * 9], dtype = float)  # 训练集 12 * 471 行,每列为 18 * 9的数据 
y = np.empty([12 * 471, 1], dtype = float)       #  12 * 471 行, 1列  PM 2.5

#由于已经将一个月的数据合并,那么天与小时都已经是次要的信息。
#因此,此处对于1个月,只需要一个index,从0到471取到就可以了            
for month in range(12):
    for index in range(471):
        x[index + 471 * month, :] = month_data[month][:, index:index + 9].reshape(1, -1)  # 数据reshape为 1 行,列的参数-1会默认得到列
        y[index + 471 * month, :] = month_data[month][9, index + 9]   #  单个数据,一列 ,从第9个位验证数据集,9,10,11,12,13,14 依次为测试集
print(len(x))
  1. Normalize 标准化处理数据,就是feature scaling,使得gradient的速度更快
# 正则化处理数据的方法,让数据的值减去均值,再除以标准差
# mean() 函数求均值,np.std()求标准差
# 设置的 axis 参数,axis不设置值,就是求所有数的平均值,
# axis = 0, 压缩行,求各列的平均值,返回一个1 * m 的矩阵
# axis = 1,压缩列,求各行的平均值 ,返回一个 n * 1 的矩阵

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]  # 每个元素减去其所在列的均值,再除以标准差
## 这里就是特征缩放
  1. training
# 模型选取:线性模型
# 输入:一次18 * 9个数据
# 参数:18 * 9个weight + bias
# loss function:均方根误差
# 优化算法:gradient descent,Adagrad 
# np.concatenate((a,b),axis=1) 进行拼接,拼接结果是[a,b], 相当于在x矩阵的左侧第一行添加同等行数的1
# np.dot(a,b) a与b进行矩阵乘法 
import matplotlib.pyplot as plt
dim = 18 * 9 + 1 # w的行数,w为 18 * 9 + 1 行
w = np.ones([dim, 1]) 
x = np.concatenate( (np.ones([12 * 471, 1]), x), axis=1).astype(float)  # 每运行一次加一列
print(x.shape)
# 对列进行拼接,x矩阵被拼接为 471 * 12行,18*9 + 1列,加上的一列为bias
#x = np.concatenate( (np.ones([12 * 471, 1]), x), axis=1).astype(float)
N = 12 * 471 # y-hat 的行的行数
learning_rate = 0.03 
iter_time = 1000 # 训练的迭代次数
loss = np.zeros([iter_time, 1])  # 每次迭代loss更新,所以与迭代次数相同
for i in range(iter_time):
    y1 = np.dot(x, w) # x 为 471*12行,18*9 +1 列 ,w为 18*9+1行 1列
    #loss[i] = np.sqrt(np.sum(np.power(y1-y,2)/N))  
    #gradient = (2/N) * np.dot(x.T,y1-y)  # dot 为两个矩阵相乘 x.t (163,5652) * (5652, 1) = (163,1)
    # 上面的loss function 和 gradient 的计算是不匹配的,下面的匹配 
    loss[i] = np.sum(np.power(y1-y, 2)/N )
    gradient = (2/N) * np.dot(x.T,y1-y)
    w = w - learning_rate * gradient 
plt.plot(loss)  # 为了visualize loss,来调整learning_rate
plt.show()
  1. AdamGrad 优化
## AdaGrad优化
## 上一个算法中learning_rate是凭借试验和经验设置的,且是一个常数保持不变,所以在计算loss的时候可能卡在一个曲线左右循坏跳,而到不了minLoss
## 那么可不可以让他自己根据每一步求出的w来进行自己的更新,自动调节learning_rate
## AdaGrad算法,一开始是激励收敛,到后面变为惩罚收敛,速度越来越慢
x = np.delete(x, 0, axis = 1)
print(x[0][0])
dim = 18 * 9 + 1
w = np.zeros([dim, 1])
x = np.concatenate((np.ones([12*471,1]),x),axis=1).astype(float)
learning_rate = 100
iter_time = 1000
adagrad = np.zeros([dim,1])
eps = 0.0000000001
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.transpose(), np.dot(x,w) - y)
    adagrad += gradient ** 2 #求adagrad的平方power(adagrad,2)  用一次微分的和来替代二次微分(见下图)
    w = w - learning_rate * gradient / np.sqrt(adagrad + eps)
np.save('weight.npy',w)
  1. testing
test_data = pd.read_csv('data/test.csv', header = None, encoding = 'big5')
test_data = test_data.iloc[:, 2:] # 取第二列到最后一列的所以行 
test_data[test_data == 'NR'] = 0
test_data = test_data.to_numpy() # 转换为numpy数据
test_x = np.empty([240, 18*9],dtype=float)
for i in range(240):#将每天的18项数据横排摆放
    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:#确保分母不为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) # 增加一列数据计算bias权重

w = np.load('weight.npy')
ans_y = np.dot(test_x, w)
ans_y
import 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)

标签:12,李宏毅,春季,test,471,2020,18,np,data
来源: https://blog.csdn.net/caiMAMBA001/article/details/116064595

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有