机器学习基石-作业四-代码部分

这次的作业内容主要就是对带正则化项的线性规划的闭式解做各种操作:选择\lambda、把数据分成训练集和交叉验证、k-折交叉验证。完全套公式就可以了,这里唯一的一个问题就是偏移量参不参加正则化;

在林老师的课程中,最后的闭式解的公式为:

w_{reg}=(X^TX+\lambda I)^{-1}X^Ty

按照这个公式,线性得分函数中的b也参加了正则化。

而在吴恩达的课程,以及很多其他的地方得到的经验是,b一般是不参加正则化的。按照这样的理解,假设w0=b,那么公式为:

w_{reg}=(X^TX+\lambda\begin{bmatrix} 0 & & & \\ & 1 & & \\ & & 1 & \\ & & & ... \\ & & & 1 \end{bmatrix})^{-1}X^Ty

本人更倾向于后者。但是为了和林老师的答案一致,程序中采用了第一种计算公式。

具体代码如下,套公式就可以了:

# -*- coding:utf-8 -*-
# Author: Evan Mi
import numpy as np


def load_data(file_name):
    x = []
    y = []
    with open(file_name, 'r+') as f:
        for line in f:
            line = line.rstrip("\n")
            temp = line.split(" ")
            temp.insert(0, '1')
            x_temp = [float(val) for val in temp[:-1]]
            y_tem = [int(val) for val in temp[-1:]][0]
            x.append(x_temp)
            y.append(y_tem)

    nx = np.array(x)
    ny = np.array(y)
    return nx, ny


def sign_zero_as_neg(x):
    """
    这里修改了np自带的sign函数,当传入的值为0的时候,不再返回0,而是-1;
    也就是说在边界上的点按反例处理
    :param x:
    :return:
    """
    result = np.sign(x)
    result[result == 0] = -1
    return result


def get_w_reg(x, y, lambdas):
    w_reg = np.dot(np.linalg.pinv(np.dot(np.transpose(x), x) + lambdas * np.eye(np.size(x, axis=1))),
                   np.dot(np.transpose(x), y))
    return w_reg.flatten()


def e_counter(x, y, w):
    local_result = sign_zero_as_neg(np.dot(x, w))
    e = np.where(local_result == y, 0, 1)
    return e.sum()/np.size(e)


def exe_13():
    print('#13:')
    train_x, train_y = load_data("data/train.txt")
    test_x, test_y = load_data("data/test.txt")
    w_reg_one = get_w_reg(train_x, train_y, 10)
    e_in = e_counter(train_x, train_y, w_reg_one)
    e_out = e_counter(test_x, test_y, w_reg_one)
    print("E_IN:", e_in)
    print("E_OUT:", e_out)


def exe_14_15():
    print('#14,#15')
    train_x, train_y = load_data("data/train.txt")
    test_x, test_y = load_data("data/test.txt")
    for i in range(-10, 3):
        lambda_tem = 10 ** i
        w_reg_tem = get_w_reg(train_x, train_y, lambda_tem)
        e_in_tem = e_counter(train_x, train_y, w_reg_tem)
        e_out_tem = e_counter(test_x, test_y, w_reg_tem)
        print("log_10(%d)" % i, e_in_tem, e_out_tem)


def exe_16_17():
    print('#16,17')
    x_tem, y_tem = load_data("data/train.txt")
    test_x, test_y = load_data("data/test.txt")
    train_x = x_tem[:120, :]
    val_x = x_tem[120:, :]
    train_y = y_tem[:120]
    val_y = y_tem[120:]
    for i in range(-10, 3):
        lambda_tem = 10 ** i
        w_reg_tem = get_w_reg(train_x, train_y, lambda_tem)
        e_in_tem = e_counter(train_x, train_y, w_reg_tem)
        e_val_tem = e_counter(val_x, val_y, w_reg_tem)
        e_out_tem = e_counter(test_x, test_y, w_reg_tem)
        print("log_10(%d)" % i, e_in_tem, e_val_tem, e_out_tem)


def exe_18():
    print('#18:')
    train_x, train_y = load_data("data/train.txt")
    test_x, test_y = load_data("data/test.txt")
    # lambda = log_10(0)
    w_reg_one = get_w_reg(train_x, train_y, 1)
    e_in = e_counter(train_x, train_y, w_reg_one)
    e_out = e_counter(test_x, test_y, w_reg_one)
    print("E_IN:", e_in)
    print("E_OUT:", e_out)


def exe_19():
    print('#19')
    train_x, train_y = load_data("data/train.txt")
    for i in range(-10, 3):
        lambda_tem = 10 ** i
        e_cross = []
        for j in range(0, 200, 40):
            x_val = train_x[j:j+40, :]
            y_val = train_y[j:j+40]
            x_remain_left = train_x[0:j, :]
            x_remain_right = train_x[j+40:, :]
            y_remain_left = train_y[0:j]
            y_remain_right = train_y[j + 40:]
            if np.size(x_remain_left, axis=0) == 0:
                x_train = x_remain_right
                y_train = y_remain_right
            elif np.size(x_remain_right, axis=0) == 0:
                x_train = x_remain_left
                y_train = y_remain_left
            else:
                x_train = np.concatenate((train_x[0:j, :], train_x[j + 40:, :]), axis=0)
                y_train = np.concatenate((train_y[0:j], train_y[j + 40:]), axis=0)

            w_reg_tem = get_w_reg(x_train, y_train, lambda_tem)
            e_cross.append(e_counter(x_val, y_val, w_reg_tem))
        print("lambda:", "log_10(%d)" % i, "E_CV", np.array(e_cross).mean())


def exe_20():
    print('#20:')
    train_x, train_y = load_data("data/train.txt")
    test_x, test_y = load_data("data/test.txt")
    # lambda = log_10(-8)
    w_reg_one = get_w_reg(train_x, train_y, 10 ** -8)
    e_in = e_counter(train_x, train_y, w_reg_one)
    e_out = e_counter(test_x, test_y, w_reg_one)
    print("E_IN:", e_in)
    print("E_OUT:", e_out)


if __name__ == '__main__':
    exe_13()
    exe_14_15()
    exe_16_17()
    exe_18()
    exe_19()
    exe_20()

详细代码及代码使用的数据见:机器基石作业四

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值