波士顿房价预测(二)——参数越多,模型效果越不好 !?

导语

上一次手撸一下波士顿房价预测的代码,但是在上一次遗留下了一个问题就是我只用两个参数训练出来的效果要远远好于13个参数的效果。当时呢我认为参数越多,代表着对于结果的预测走向就越精确所以应该会更准确,然后找了一下资料,以及自己也开发大脑想了想,大概有了一点点了解。

代码

上一次的代码,有需要的同学可以回顾一下
波士顿房价预测(一)
这一次的代码虽然差不多,但还是把过程和运行结果放在这
注:该代码是从notebook环境上copy下来的,在py文件下运行的同学注意一下格式,或者不必要的可以删除
python3.8.3 / jupyter1.0.0 / vscode

# 先导入相关库
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston

#导入数据,查看数据情况
datasets = load_boston()
datasets.keys()  

#制作数据集
data = datasets['data']
target = datasets['target']
feature_name = datasets['feature_names']

using_data = np.array(data)
price = np.array(target)

training_data,test_data = np.split(using_data ,[int(using_data.shape[0]*0.7),] )
training_price,test_price = np.split(price ,[int(price.shape[0]*0.7),] )


#训练模型的定义
def model(x,w,b):
    return np.dot(x,w.T) + b

def loss(y,yhat):
    return np.mean((yhat-y)**2)

def partial_w(x,y,yhat):
    return np.array([2 * np.mean(yhat - y) *x[i] for i in range(len(x))])

def partial_b(x,y,yhat):
    return 2* np.mean(yhat - y)


#开始训练
w = np.random.random_sample((1,training_data.shape[1]))
b = random.random()

learning_rate = 1e-7
losses = []

epoch = 600
for i in range(epoch):
    batch_losses = []
    for batch in range(training_data.shape[0]):
        index = np.random.choice(range(training_data.shape[0]))
        x = training_data[index,:]
        y = price[index]
        yhat = model(x,w,b)

        loss_v = loss(y,yhat)
        batch_losses.append(loss_v)

        w = w - partial_w(x,y,yhat) * learning_rate
        b = b - partial_b(x,y,yhat) * learning_rate
        
        if batch % 100 == 0:
            print(f'epoch:{i}  ,batch:{batch}  ,loss:{loss_v}')
    losses.append(np.mean(batch_losses))

# 查看训练时的loss变化
plt.figure(figsize=(12,8),dpi = 80)
plt.plot(losses)
plt.show()

# 测试集查看模型效果
model_price = []
for i in range(test_data.shape[0]):
    x = test_data[i,:]
    res = model(x,w,b)
    model_price.append(res)

plt.figure(figsize=(12,8),dpi = 80)
plt.plot(model_price ,label = 'model_price')
plt.plot(test_price ,color = 'r' ,label = 'price')

plt.legend()  # 不加的话,不会显示线条注释
plt.show()


在这里插入图片描述
在这里插入图片描述

这里附上上一次的效果

在这里插入图片描述
对比可以发现上一次用两个参数拟合的效果要远远好于现在的13个参数。

分析原因

我们可以结合相关性的图来看
在这里插入图片描述

在这里插入图片描述

以及这是训练好之后的模型参数在这里插入图片描述
可以很清晰的看到就是很多训练好的参数其实和他的相关性有很大的出入的,与price呈负相关的参数一共有7个,而训练结果中只有2个是负相关而且而且权重并不是很高。所以我感觉是训练的问题,然后我调整了训练次数结果也没有太大改善。
因为刚开始学习,对数据集的概念不是很深,后来查了资料发现是因为数据量太少了。sklearn中的数据集只有500多个,其实这对于14个样本是远远不够,大概是每多一个参数数据量就需要多一个数量级,当然这也不是固定。所以总体来讲是因为因为数据量不够,所以才导致训练模型不好。

奥卡姆剃刀原则

奥卡姆剃刀定律(Occam’s Razor, Ockham’s Razor)又称"奥康的剃刀",它是由14世纪英格兰的逻辑学家、圣方济各会修士奥卡姆的威廉(William of Occam,约1285年至1349年)提出。这个原理称为"如无必要,勿增实体",即"简单有效原理"。正如他在《箴言书注》2卷15题说"切勿浪费较多东西去做,用较少的东西,同样可以做好的事情。"

这个让我想到了奥卡姆剃刀原则。
我的理解是,在机器学习中,应该选取尽可能简单的模型去解决问题。因为对于一个预测的问题来讲,越复杂和精细化,你所考虑的东西就越多,那么问题预测的方向就越可能偏离,所以模型越简单,预测的方向就越趋于准确。
在这里插入图片描述
以上图的二叉树为例,I 是终点,只有一个A路口,那么可以很清楚 I 在A左边,但是把C、D和E也加进来,那么就可能造成混淆,尤其是在训练过程中I在D的左边,如果上式可以用
权重 x 节点相对位置来表示,如果D权重过大,那么就会造成错误。
可能解释的不是很好,暂时想不到比较好的例子

还有一点就是通过这次过程理解的奥卡姆剃刀,针对于参数的多少的话,其实我感觉是基于数据量的多少,就相当于,数据量是你学习能力的下限,只要数据量足够,那么理论上支持无限个参数训练,如果数据量有限的话,应该选取影响力较大的参数去训练,在该案例中的[‘RM’] 和[‘LSTAT’]就分别是正相关性和负相关性最大的两个参数。

总结

个人感觉说的还是不够清晰明了,也是由于刚刚接触的因素,不论是机器学习还是写这种文章,之后会在学习的过程中再进一步改善。总体来讲这次遇到的问题,最根本的原因就是因为数据量不够从而导致训练结果不够好,那么在这种情况下,我们可以通过相关性或其它手段先了解对结果影响最大的参数去训练。可以在有限的训练资源下,得到最优的模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值