无意义的结果

2024-10-02 02:38:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图为回归建立一个简单的测试用例,一个x的线性函数,但是sgdregrestor给出了一个错误的结果

import numpy as np
from sklearn.linear_model import SGDRegressor
from random import random
X = np.array(range(1000))
y = np.array([x + random() for x in X])
X = X.reshape(1000,1)
sgd = SGDRegressor()
sgd.fit(X, y)
print [sgd.intercept_, sgd.coef_]

[array([ -4.13761484e+08]), array([ -9.66320825e+10])]


Tags: 函数fromimportnumpyas错误np测试用例
2条回答

我认为这与这样一个事实有关:在0-1000的整数中添加random()对int的影响很小,因为它们越大。使用StandardScaler作为预处理步骤的功能缩放可能会有所帮助。在

根据Sklearn的实用技巧:

Stochastic Gradient Descent is sensitive to feature scaling, so it is highly recommended to scale your data.

在修改了您的示例并没有使用特性缩放之后,我注意到产生差异的参数组合是:loss、nUiter、eta0和power\t是需要重点关注的参数组合-eta0是主要参数。SGDRegressor的默认值对于这个问题来说太高了。在

import numpy as np
from sklearn.linear_model import SGDRegressor
from random import random
import matplotlib.pyplot as plt
import itertools

X = np.array(range(1000))
y = np.array([x + random() for x in X])
X = X.reshape(-1,1)

fig,ax = plt.subplots(2, 2, figsize=(8,6))
coords = itertools.product([0,1], repeat=2)

for coord,loss in zip(coords, ['huber', 'epsilon_insensitive',
                               'squared_epsilon_insensitive', 'squared_loss']):
  row,col = coord
  ax[row][col].plot(X, y, 'k:', label='actual', linewidth=2)
  for iteration in [5, 500, 1000, 5000]: # or try range(1, 11)
    sgd = SGDRegressor(loss=loss, n_iter=iteration, eta0=0.00001, power_t=0.15)
    sgd.fit(X, y)
    y_pred = sgd.intercept_[0] + (sgd.coef_[0] * X)
    print('Loss:', loss, 'n_iter:', iteration, 'intercept, coef:',
          [sgd.intercept_[0], sgd.coef_[0]], 'SSE:', ((y - sgd.predict(X))**2).sum())

    ax[row][col].plot(X, y_pred, label='n_iter: '+str(iteration))
    ax[row][col].legend()
    ax[row][col].set_title(loss)
    plt.setp(ax[row][col].legend_.get_texts(), fontsize='xx-small')


plt.tight_layout()
plt.show()

打印结果如下:

^{pr2}$

这是打印出来的样子(注意:每次重新运行时都会发生变化,因此您的输出看起来可能与我的不同):

SGD Loss Responses

有趣的是,当其他三个损失函数保持在预期范围内时,squared_epsilon_insensitive的y轴突然消失。在

为了好玩,将power_t0.15改为0.5。产生影响的原因是默认的learning_rate参数是由eta = eta0 / pow(t, power_t)计算的'invscaling'

SGD is a sensitive flower

尝试设置低于默认值0.01的初始学习率,例如:

import numpy as np
from sklearn.linear_model import SGDRegressor
from random import random
X = np.array(range(1000))
y = np.array([x + random() for x in X])
X = X.reshape(1000,1)
sgd = SGDRegressor(eta0=0.000001)
sgd.fit(X, y)
print [sgd.intercept_, sgd.coef_]

输出:

^{pr2}$

编辑:我不确定确切的原因,但是X和{}中包含的大值似乎会引起一些数值稳定性问题。在SGDRegressor中设置verbose=1,它将显示具有默认学习率的以下输出:

  Epoch 1
Norm: nan, NNZs: 1, Bias: nan, T: 1000, Avg. loss: nan
Total training time: 0.00 seconds.

这意味着内部计算已经溢出了。使用eta=0.000001

  Epoch 1
Norm: 1.00, NNZs: 1, Bias: 0.006449, T: 1000, Avg. loss: 873.136013
Total training time: 0.00 seconds.
  Epoch 2
Norm: 1.00, NNZs: 1, Bias: 0.006461, T: 2000, Avg. loss: 436.597862
Total training time: 0.00 seconds.
  Epoch 3
Norm: 1.00, NNZs: 1, Bias: 0.006471, T: 3000, Avg. loss: 291.085373
Total training time: 0.00 seconds.
  Epoch 4
Norm: 1.00, NNZs: 1, Bias: 0.006481, T: 4000, Avg. loss: 218.329235
Total training time: 0.00 seconds.
  Epoch 5
Norm: 1.00, NNZs: 1, Bias: 0.006491, T: 5000, Avg. loss: 174.675614
Total training time: 0.00 seconds.
[array([ 0.00649087]), array([ 1.00035165])]

另一种可能的方法是预先将数据(输入和输出)调整到正常范围,例如使用StandardScaler。预处理完成后,默认参数工作良好。在

相关问题 更多 >

    热门问题