台大hw1-预测pm25-手动实现gradient descent

Homework 1 - PM2.5 Prediction

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
import matplotlib as mpl

# 先考虑比较简单的一种模型:
# 9+1=10 个feature,9小时内所有pm2.5,bias
# 清洗train data
# 将所有的pm25数据放入到一个list中

#%%
def train():
    all_pm25 = []
    with open("train.csv",encoding="big5") as f:
        for line in f:
            if "PM2.5" in line:
                temp = line.strip().split(",",3)
                pm25 = temp[3].split(',')
                pm25 = [float(i) for i in pm25]
                all_pm25 += pm25
    # 划分features和label
    X = []
    Y = []
    # method 1:
    # for i in range(len(all_pm25)-10):
    #     X.append(all_pm25[i:i+9]) # 连续的9个data作为feature
    #     y.append(all_pm25[i+9]) # 紧挨的data作为label
    # method 2: 正好划分到最好一个
    for i in range(0, len(all_pm25), 10):
        X.append(all_pm25[i:i+9])
        Y.append(all_pm25[i+9])
    return X,Y

def test():
    X = []
    with open("test.csv",encoding="big5") as f:
        for line in f:
            if "PM2.5" in line:
                temp = line.strip().split(",",2)
                pm25 = temp[2].split(',')
                pm25 = [float(i) for i in pm25]
                X.append(pm25)
    return X

X,Y = train()
X_test = test()


def loss(w,b):
    loss = 0
    for x,y in zip(X,Y):
        sum_wi_xi = np.dot(w,x)
        one_loss = (sum_wi_xi + b - y)**2
        loss = loss + one_loss
    return loss

#%%
def sgd(iteration):
    """sgd效果似乎好于adagrad
    """
    # random pick initial parameters
    w = np.ones(9)  # [1,1,1,...]
    b = 1           # 1
    lr = 0.00001

    w_history = [w]
    b_history = [b]
    loss_history = []

    print("iter:",iteration)
    for i in range(iteration):
        for x,y in zip(X,Y):
            sum_wi_xi = np.dot(w,x)
            w_grad = 2*(sum_wi_xi + b - y) * np.array(x)
            w = w - np.multiply(w_grad, lr)

            b_grad = 2*(sum_wi_xi + b - y)
            b = b - b_grad * lr

        w_history.append(w)
        b_history.append(b)
        current_loss = loss(w,b)
        loss_history.append(current_loss)
    
    plt.plot(np.arange(len(loss_history)),loss_history, "o")
    plt.show()
    return (w_history, b_history, loss_history)



for i in [100,130]:
    w_hist_sgd, b_hist_sgd, loss_hist_sgd = sgd(i)
    plt.plot(np.arange(len(loss_hist_sgd[-20:])),loss_hist_sgd[-20:], "o")
    plt.show()


def sgd_predict(w, b, X):
    """
    :input: [[x1, x2, ..., x9],
             [x1, x2, ..., x9]]
    :output: [y, y]
    """
    y_hat = []
    for x in X:
        predict = np.dot(w, x) + b
        y_hat.append(predict)
    return y_hat

w_hat = w_hist_sgd[-1]
b_hat = b_hist_sgd[-1]
# 预测出来的结果非常符合对test数据直观理解
sgd_predict(w_hat,b_hat,X_test)


#%%
def adagrad(iteration):
    w = np.ones(9)  # [1,1,1,...]
    b = 1           # 1
    lr = 0.000001

    w_history = [w]
    b_history = [b]
    loss_history = []
    
    print("iter:",iteration)
    for i in range(iteration):
        w_grad = np.zeros(9)
        b_grad = 0
        for x,y in zip(X,Y):
            sum_wi_xi = np.dot(w,x)
            w_grad_one = 2*(sum_wi_xi + b - y) * np.array(x)
            b_grad_one = 2*(sum_wi_xi + b - y)
            w_grad = w_grad_one + w_grad
            b_grad = b_grad_one + b_grad
            
        lr_w = lr/np.sqrt(np.sum(np.array(w_history)**2, axis=0))
        lr_b = lr/np.sqrt(np.sum(np.array(b_history)**2))
        w = w - np.multiply(w_grad, lr_w)
        b = b - b_grad * lr_b

        w_history.append(w)
        b_history.append(b)
        current_loss = loss(w,b)
        loss_history.append(current_loss)
    
    plt.plot(np.arange(len(loss_history)),loss_history, "o")
    plt.show()
    return (w_history, b_history, loss_history)

for i in [1000]:
    w_hist, b_hist, loss_hist = adagrad(i)
    plt.plot(np.arange(len(loss_hist[-40:])),loss_hist[-40:], "o")
    plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值