【问题标题】:Scikit learn: RidgeCV seems not to give the best option?Scikit learn:RidgeCV 似乎没有给出最好的选择?
【发布时间】:2018-02-21 22:48:18
【问题描述】:

这是我的X

 X =  np.array([[  5.,   8.,   3.,   4.,   0.,   5.,   4.,   0.,   2.,   5.,  11.,
              3.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   1.,   4.,   0.,   3.,   5.,  13.,
              4.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   4.,   4.,   0.,   3.,   5.,  12.,
              2.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   1.,   4.,   0.,   4.,   5.,  12.,
              4.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   1.,   4.,   0.,   3.,   5.,  12.,
              5.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   2.,   4.,   0.,   3.,   5.,  13.,
              3.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   2.,   4.,   0.,   4.,   5.,  11.,
              4.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   2.,   4.,   0.,   3.,   5.,  11.,
              5.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   1.,   4.,   0.,   3.,   5.,  12.,
              5.,  19.,   2.],
           [  5.,   8.,   3.,   4.,   0.,   1.,   4.,   0.,   3.,   5.,  12.,
              5.,  19.,   2.]])

这是我的回复y

y = np.array([ 70.14963195,  70.20937046,  70.20890363,  70.14310389,
        70.18076206,  70.13179977,  70.13536797,  70.10700998,
        70.09194074,  70.09958111])

岭回归

    # alpha = 0.1
    model = Ridge(alpha = 0.1)
    model.fit(X,y)
    model.score(X,y)   # gives 0.36898424479816627

    # alpha = 0.01
    model1 = Ridge(alpha = 0.01)
    model1.fit(X,y)
    model1.score(X,y)     # gives 0.3690347045143918 > 0.36898424479816627

    # alpha = 0.001
    model2 = Ridge(alpha = 0.001)
    model2.fit(X,y)
    model2.score(X,y)  #gives 0.36903522192901728 > 0.3690347045143918

    # alpha = 0.0001
    model3 = Ridge(alpha = 0.0001)
    model3.fit(X,y)
    model3.score(X,y)  # gives 0.36903522711624259 > 0.36903522192901728

因此从这里应该清楚alpha = 0.0001 是最好的选择。确实阅读文档它说分数是决定系数。如果最接近 1 的系数描述了最佳模型。现在让我们看看RidgeCV 告诉我们什么

RidgeCV 回归

modelCV = RidgeCV(alphas = [0.1, 0.01, 0.001,0.0001], store_cv_values = True)
modelCV.fit(X,y)
modelCV.alpha_  #giving 0.1
modelCV.score(X,y)  # giving 0.36898424479812919 which is the same score as ridge regression with alpha = 0.1

出了什么问题?当然,我们可以像我所做的那样手动检查所有其他 alpha 是否更好。所以不仅不是选择最好的 alpha,而是选择最差的!

谁能给我解释一下这是怎么回事?

【问题讨论】:

    标签: python scikit-learn statistics regression cross-validation


    【解决方案1】:

    这是完全正常的行为。

    您的手动方法不进行任何交叉验证,因此训练数据和测试数据是相同的!

    # alpha = 0.1
    model = Ridge(alpha = 0.1)
    model.fit(X,y)   #!!
    model.score(X,y) #!!
    

    对分类器(例如凸优化问题)和求解器(保证 epsilon-convergence)有一些温和的假设,这意味着 对于最少正则化的模型,您总是会得到最低分(过拟合!):在你的情况下:alpha = 0.0001。 (看看 RidgeRegression 的 formula

    虽然使用 RidgeCV默认激活交叉验证,选择 leave-one-out。用于确定最佳参数的评分过程并未使用相同的数据进行训练和测试。

    您可以在使用 store_cv_values = True 时打印出平均值 cv_values_

    print(np.mean(modelCV.cv_values_, axis=0))
    # [ 0.00226582  0.0022879   0.00229021  0.00229044]
    # alpha [0.1, 0.01, 0.001,0.0001]
    # by default: mean squared errors!
    # left / 0.1 best; right / 0.0001 worst 
    # this is only a demo: not sure how sklearn selects best (mean vs. ?)
    

    这是意料之中的,但不是一般规则。由于您现在使用两个不同的数据集进行评分,因此您正在优化以不过度拟合,并且很有可能需要进行一些正则化!

    【讨论】:

    • 好的,让我看看我是否明白你所说的。在Ridge() 我们使用整个X,所以训练集和测试集是一样的。而在RidgeCV() 中,我们正在进行留一交叉验证,因此我们对X 进行回归划分,这样每个观察结果都恰好在测试集中出现一次?
    • 另外,RidgeCV() 给出0.1 的原因是因为在进行交叉验证时0.1 给出的模型不如0.0001 灵活,因为复杂性更低,因此0.1过拟合是否小于0.0001
    • 那么这主要是数据过拟合的问题吗? alpha 值越小,我们越容易过拟合?
    • 没有一般规则。我只查看了 MSE,因为它是默认输出。值得信任的决定是一些具有可能不同结果的模型决定。但很难一概而论。我不得不说,我从未对这些措施进行过深入研究。
    • 是的。通过docs
    【解决方案2】:

    sascha 的回答是正确的。这是 RidgeCV 确实选择了正确的 alpha 的证明。

    我编写了一个函数来测试 alpha 的最小交叉验证错误的索引是否与 alpha 列表中的索引 0.1 匹配。

    def test_RidgeCV(alphas):
        modelCV = RidgeCV(alphas = alphas, store_cv_values = True)
        modelCV.fit(X,y)
        modelCV.score(X,y)
        # print(modelCV.alpha_)
        CV_values =modelCV.cv_values_
        mean_error = np.min(CV_values, axis=0)
        return alphas.index(0.1) == np.argmin(mean_error)
    

    然后我遍历问题中提供的 alpha 列表的完整排列。无论我们把 0.1 放在哪里,它的索引总是匹配最小误差的索引。
    这是一个详尽的测试。我们得到了 24 个 True。

    alphas=[0.1, 0.01, 0.001,0.0001]
    
    from itertools import permutations
    alphas_list = list(permutations(alphas))
    for i in range(len(alphas_list)):
        print(test_RidgeCV(alphas=alphas_list[i]))
    

    输出: 真的 真的 ... 是的

    【讨论】:

      猜你喜欢
      • 2015-08-07
      • 1970-01-01
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多