使用NumPy实现简单的机器学习任务(加强版)

上一期给出的散点可以根据seed()种子函数的不同,可以得出不同的散点图,并拟合出最接近给定参数的拟合曲线,现在我们想获取200组数据但是我们只使用前面50组数据对后面150组数据进行预测,看看准确性

先进行散点图的绘制

import numpy as np
import matplotlib.pyplot as plt

'''
返回数据集,形如[[x_1, y_1], [x_2, y_2], ..., [x_N, y_N]]
保证 bound[0] <= x_i < bound[1].
- N 数据集大小, 默认为 100
- bound 产生数据横坐标的上下界, 应满足 bound[0] < bound[1]
'''


def get_dataset(N=200, bound=(0, 100)):
    l, r = bound
    x = sorted(np.random.rand(N) * (r - l) + l)
    y = np.sin(x) + np.random.randn(N) / 3
    return np.array([x, y]).T


'''
最小二乘求出解析解, m 为多项式次数
最小二乘误差为 (XW - Y)^T*(XW - Y)
- dataset 数据集
- m 多项式次数, 默认为 5
'''


def fit(dataset, m=5):
    X = np.array([dataset[:, 0] ** i for i in range(m + 1)]).T
    Y = dataset[:, 1]
    return np.dot(np.dot(np.linalg.inv(np.dot(X.T, X)), X.T), Y)


'''
绘制给定系数W的, 在数据集上的多项式函数图像
- dataset 数据集
- w 通过上面四种方法求得的系数
- color 绘制颜色, 默认为 red
- label 图像的标签
'''


def draw(dataset, w, color='red', label=''):
    X = np.array([dataset[:, 0] ** i for i in range(len(w))]).T
    Y = np.dot(X, w)

    plt.plot(dataset[:, 0], Y, c=color, label=label)


if __name__ == '__main__':

    dataset = get_dataset(bound=(-3, 3))
    # 绘制数据集散点图
    for [x, y] in dataset:
        plt.scatter(x, y, color='blue')
    plt.show()

可以看到散点图总体还是比较分散的,这对预测的难度大大增强了

下一卜,进行全部200个散点的曲线拟合

    for [x, y] in dataset:
        plt.scatter(x, y, color='blue')
    coef1 = fit(dataset)
    draw(dataset, coef1, color='black', label='OLS')

    plt.legend()
    plt.show()

可以看到曲线还是比较符合散点走向的总体趋势的

接下来我们只对前面150个点进行曲线拟合,看看后50个点的预测效果,代码只需要把原来的范围修改一下即可

    coef1 = fit(dataset[:150], m=3)
    #coef1 = fit(dataset)

通过图片明显可以看到后面曲线拟合效果明显变差,我们再试试前50个点

效果很明显,预测效果差

前面两张图当m值超过进入计算的值时,过拟合严重。

可以看到拟合在前50或150个点表现很好;而在测试集上表现就很差,为了防止过拟合,可以引入正则化项

 我们使用简单的梯度下降的方法

def GD(dataset, m = 3, max_iteration = 1000, lr = 0.01):
    # 初始化参数
    w = np.random.rand(m + 1)

    N = len(dataset)
    X = np.array([dataset[:, 0] ** i for i in range(len(w))]).T
    Y = dataset[:, 1]

    try:
        for i in range(max_iteration):
            pred_Y = np.dot(X, w)
            # 均方误差(省略系数2)
            grad = np.dot(X.T, pred_Y - Y) / N
            w -= lr * grad

    except RuntimeWarning:
        print('梯度下降法溢出, 无法收敛')

    return w

可以看到梯度下降的方法也就是黄色线,效果更好一点,也就验证了正则化方法是可以对预测效果进行准确性优化的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值