Lesson 6.4 逻辑回归手动调参实验

news2024/11/26 17:53:22

文章目录

  • 一、数据准备与评估器构造
    • 1. 数据准备
    • 2. 构建机器学习流
  • 二、评估器训练与过拟合实验
  • 三、评估器的手动调参

  • 在补充了一系列关于正则化的基础理论以及 sklearn 中逻辑回归评估器的参数解释之后,接下来,我们尝试借助 sklearn 中的逻辑回归评估器,来执行包含特征衍生和正则化过程的建模试验,同时探索模型经验风险和结构风险之间的关系。
  • 一方面巩固此前介绍的相关内容,同时也进一步加深对于 Pipeline 的理解并熟练对其的使用。
  • 当然更关键的一点,本节的实验将为后续文章当中的的网格搜索调参做铺垫,并在后续借助网格搜索工具,给出更加完整、更加自动化、并且效果更好的调参策略。
# 科学计算模块
import numpy as np
import pandas as pd
​
# 绘图模块
import matplotlib as mpl
import matplotlib.pyplot as plt
​
# 自定义模块
from ML_basic_function import *# Scikit-Learn相关模块
# 评估器类
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
​
# 实用函数
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

一、数据准备与评估器构造

  • 首先需要进行数据准备。为了更好的配合进行模型性能与各种方法效果的测试,此处先以手动创建数据集为例进行试验。

1. 数据准备

  • 在 Lesson 5.1 的阅读部分内容中,我们曾介绍到关于逻辑回归的决策边界实际上就是逻辑回归的线性方程这一特性,并由此探讨了一元函数与二维平面的决策边界之间的关系。
  • 据此我们可以创建一个满足分类边界为 y 2 = − x + 1.5 y^2=-x+1.5 y2=x+1.5 的分布,创建方法如下:
np.random.seed(24)
X = np.random.normal(0, 1, size=(1000, 2))
y = np.array(X[:,0]+X[:, 1]**2 < 1.5, int)

plt.scatter(X[:, 0], X[:, 1], c=y)

在这里插入图片描述

  • 此时边界为 y 2 = − x + 1.5 y^2=-x+1.5 y2=x+1.5,而选取分类边界的哪一侧为正类哪一侧为负类(即不等号的方向),其实并不影响后续模型建模。
  • 而利用分类边界来划分数据类别,其实也是一种为这个分类数据集赋予一定规律的做法。
  • 同样,为了更好地贴近真实情况,我们在上述分类边界的规律上再人为增加一些扰动项,即让两个类别的分类边界不是那么清晰,具体方法如下:
np.random.seed(24)
for i in range(200):
    y[np.random.randint(1000)] = 1
    y[np.random.randint(1000)] = 0

plt.scatter(X[:, 0], X[:, 1], c=y)

在这里插入图片描述

  • 当然,如果要增加分类难度,可以选取更多的点随机赋予类别。
  • 在整体数据准备完毕后,接下来进行数据集的切分:
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, random_state = 42)
  • 至此,数据准备工作全部完成。

2. 构建机器学习流

  • 接下来,调用逻辑回归中的相关类,来进行模型构建。
  • 很明显,面对上述曲线边界的问题,通过简单的逻辑回归无法达到较好的预测效果,因此需要借助此前介绍的 PolynomialFeatures 来进行特征衍生,或许能够提升模型表现。
  • 此外我们还需要对数据进行标准化处理,以训练过程稳定性及模型训练效率,当然我们还可以通过 Pipeline 将这些过程封装在一个机器学习流中,以简化调用过程。
  • 我们知道,整个建模过程我们需要测试在不同强度的数据衍生下,模型是否会出现过拟合倾向,同时如果出现过拟合之后应该如何调整。
  • 因此我们可以将上述 Pipelin e封装在一个函数中,通过该函数我们可以非常便捷进行核心参数的设置,同时也能够重复实例化不同的评估器以支持重复试验。
def plr(degree=1, penalty='none', C=1.0):
    pipe = make_pipeline(PolynomialFeatures(degree=degree, include_bias=False), 
                         StandardScaler(), 
                         LogisticRegression(penalty=penalty, tol=1e-4, C=C, max_iter=int(1e6)))
    return pipe
  • 其中,和数据增强的强度相关的参数是 degree,决定了衍生特征的最高阶数,而 penalty、C 则是逻辑回归中控制正则化及惩罚力度的相关参数,该组参数能够很好的控制模型对于训练数据规律的挖掘程度。
  • 当然,最终的建模目标是希望构建一个很好挖掘全局规律的模型,即一方面我们希望模型尽可能挖掘数据规律,另一方面我们又不希望模型过拟合。
  • 上述过程有两点需要注意:
  • 首先,复杂模型的建模往往会有非常多的参数需要考虑,但一般来说我们会优先考虑影响最终建模效果的参数(如影响模型前拟合、过拟合的参数),然后再考虑影响训练过程的参数(如调用几核心进行计算、采用何种迭代求解方法等),前者往往是需要调整的核心参数;
  • 其次,上述实例化逻辑回归模型时,我们适当提高了最大迭代次数,这是一般复杂数据建模时都需要调整的参数。
  • 合理的设置调参范围,是调好参数的第一步。

二、评估器训练与过拟合实验

  • 接下来进行模型训练,并且尝试进行手动调参来控制模型拟合度。
pl1 = plr()
  • 更多参数查看和修改方法
  • 当然,函数接口只给了部分核心参数,但如果想调整更多的模型参数,还可以通过使用此前介绍的 set_params 方法来进行调整:
pl1.get_params()

pl1.get_params()['polynomialfeatures__include_bias']
#False

# 调整PolynomialFeatures评估器中的include_bias参数
pl1.set_params(polynomialfeatures__include_bias=True)
#Pipeline(steps=[('polynomialfeatures', PolynomialFeatures(degree=1)),
#                ('standardscaler', StandardScaler()),
#                ('logisticregression',
#                 LogisticRegression(max_iter=1000000, penalty='none'))])

pl1.get_params()['polynomialfeatures__include_bias']
#True
  • 建模结果观察与决策边界函数
  • 接下来测试模型性能,首先是不进行特征衍生时的逻辑回归建模结果:
pr1 = plr()
pr1.fit(X_train, y_train)
pr1.score(X_train, y_train),pr1.score(X_test, y_test)
#(0.6985714285714286, 0.7066666666666667)
  • 我们发现,模型整体拟合效果并不好,我们可以借助此前定义的决策边界来进行一个更加直观的模型建模结果的观察。
  • 当然,由于此时我们是调用 sklearn 的模型,因此需要在此前的决策边界绘制函数基础上略微进行修改:
def plot_decision_boundary(X, y, model):
    """
    决策边界绘制函数
    """
    
    # 以两个特征的极值+1/-1作为边界,并在其中添加1000个点
    x1, x2 = np.meshgrid(np.linspace(X[:, 0].min()-1, X[:, 0].max()+1, 1000).reshape(-1,1),
                         np.linspace(X[:, 1].min()-1, X[:, 1].max()+1, 1000).reshape(-1,1))
    
    # 将所有点的横纵坐标转化成二维数组
    X_temp = np.concatenate([x1.reshape(-1, 1), x2.reshape(-1, 1)], 1)
    
    # 对所有点进行模型类别预测
    yhat_temp = model.predict(X_temp)
    yhat = yhat_temp.reshape(x1.shape)
    
    # 绘制决策边界图像
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#90CAF9'])
    plt.contourf(x1, x2, yhat, cmap=custom_cmap)
    plt.scatter(X[(y == 0).flatten(), 0], X[(y == 0).flatten(), 1], color='red')
    plt.scatter(X[(y == 1).flatten(), 0], X[(y == 1).flatten(), 1], color='blue')
  • 修改完成后,对函数性能进行测试。
# 测试函数性能
plot_decision_boundary(X, y, pr1)

在这里插入图片描述

  • 不难看出,逻辑回归在不进行数据衍生的情况下,只能捕捉线性边界,当然这也是模型目前性能欠佳的核心原因。当然,我们尝试衍生 2 次项特征再来进行建模:
pr2 = plr(degree=2)
pr2.fit(X_train, y_train)
pr2.score(X_train, y_train),pr2.score(X_test, y_test)
#(0.7914285714285715, 0.7866666666666666)

plot_decision_boundary(X, y, pr2)

在这里插入图片描述

  • 能够发现,模型效果有了明显提升,这里首先我们可以通过训练完的逻辑回归模型参数个数来验证当前数据特征数量:
pr2.named_steps
#{'polynomialfeatures': PolynomialFeatures(include_bias=False),
# 'standardscaler': StandardScaler(),
# 'logisticregression': LogisticRegression(max_iter=1000000, penalty='none')}

pr2.named_steps['logisticregression'].coef_
#array([[-0.81012988,  0.04384694, -0.48583038,  0.02977868, -1.12352417]])
  • 此处我们可以通过 Pipeline 中的 named_steps 来单独调用机器学习流中的某个评估器,从而能够进一步查看该评估器的相关属性,named_steps 返回结果同样也是一个字典,通过 key 来调用对应评估器。
  • 当然该字典中的 key 名称其实是对应评估器类的函数(如果有的话)。
  • 最后查看模型总共 5 个参数,对应训练数据总共 5 个特征,说明最高次方为二次方、并且存在交叉项目的特征衍生顺利执行。(当前 5 个特征为 x 1 x_1 x1 x 1 2 x_1^2 x12 x 2 x_2 x2 x 2 2 x_2^2 x22 x 1 x 2 x_1x_2 x1x2)。
  • 而模型在进行特征衍生之后为何会出现一个类似圆形的边界?
  • 其实当我们在进行特征衍生的时候,就相当于是将原始数据集投射到一个高维空间,而在高维空间内的逻辑回归模型,实际上是构建了一个高维空间内的超平面(高维空间的“线性边界”)在进行类别划分。
  • 而我们现在看到的原始特征空间的决策边界,实际上就是高维空间的决策超平面在当前特征空间的投影。
  • 而由此我们也知道了特征衍生至于逻辑回归模型效果提升的实际作用,就是突破了逻辑回归在原始特征空间中的线性边界的束缚。
  • 而经过特征衍生的逻辑回归模型,也将在原始特征空间中呈现出非线性的决策边界的特性。

1

  • 需要知道的是,尽管这种特征的衍生看起来很强大,能够帮逻辑回归在原始特征空间中构建非线性的决策边界。
  • 但同时需要知道的是,这种非线性边界其实也是受到特征衍生方式的约束的,无论是几阶的特征衍生,能够投射到的高维空间都是有限的,而我们最终也只能在这些有限的高维空间中寻找一个最优的超平面。
  • 过拟合倾向实验
  • 当然,我们可以进一步进行 10 阶特征的衍生,然后构建一个更加复杂的模型:
pr3 = plr(degree=10)
pr3.fit(X_train, y_train)
pr3.score(X_train, y_train),pr3.score(X_test, y_test)

/Users/wuhaotian/opt/anaconda3/lib/python3.8/site-packages/sklearn/linear_model/_logistic.py:762: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of f AND g EVALUATIONS EXCEEDS LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  n_iter_i = _check_optimize_result(

#(0.8314285714285714, 0.78)
  • 如果在运行过程中显示上述警告信息,首先需要知道的是警告并不影响最终模型结果的使用,其次,上述警告信息其实是很多进行数值解求解过程都会面临的典型问题,就是迭代次数(max_iter)用尽,但并没有收敛到 tol 参数设置的区间。
  • 解决该问题一般有三种办法:
  • 其一是增加 max_iter 迭代次数,其二就是增加收敛区间,其三则是加入正则化项。
  • 加入正则化项的相关方法我们稍后尝试,而对于前两种方法来说,一般来说,如果我们希望结果更加稳定、更加具有可信度,则可以考虑增加迭代次数而保持一个较小的收敛区间。
  • 但此处由于我们本身只设置了 1000 条数据,较小的数据量是目前无法收敛止较小区间的根本原因,因此此处建议稍微扩大收敛区间以解决上述问题。
  • 其实我们还可以通过更换迭代方法来解决上述问题,但限于逻辑回归模型的特殊性,此处不建议更换迭代方法。
  • 而要求改 tol 参数,则可以使用前面介绍的 set_param 方法来进行修改:
pr3.get_params()

pr3 = plr(degree=10)
pr3.set_params(logisticregression__tol=1e-2)
#Pipeline(steps=[('polynomialfeatures',
#                 PolynomialFeatures(degree=10, include_bias=False)),
#                ('standardscaler', StandardScaler()),
#                ('logisticregression',
#                 LogisticRegression(max_iter=1000000, penalty='none',
#                                    tol=0.01))])

pr3.fit(X_train, y_train)
pr3.score(X_train, y_train),pr3.score(X_test, y_test)
#(0.8314285714285714, 0.79)
  • 不过,因为放宽了收敛条件,最后收敛结果也会略受影响,在参数设置时需要谨慎选择。
  • 此外,我们可以绘制 pr3 中逻辑回归的决策边界,不难看出,模型已呈现出过拟合倾向。
plot_decision_boundary(X, y, pr3)

在这里插入图片描述

  • 在基本验证上述代码执行过程无误之后,接下来我们可以尝试通过衍生更高阶特征来提高模型复杂度,并观察在提高模型复杂度的过程中训练误差和测试误差是如何变化的。
# 用于存储不同模型训练准确率与测试准确率的列表
score_l = []# 实例化多组模型,测试模型效果
for degree in range(1, 21):
    pr_temp = plr(degree=degree)
    pr_temp.fit(X_train, y_train)
    score_temp = [pr_temp.score(X_train, y_train),pr_temp.score(X_test, y_test)]
    score_l.append(score_temp)

np.array(score_l)
#array([[0.69857143, 0.70666667],
#       [0.79142857, 0.78666667],
#       [0.79428571, 0.78666667],
#       [0.79428571, 0.78333333],
#       [0.79428571, 0.77666667],
#       [0.80285714, 0.79      ],
#       [0.8       , 0.78333333],
#       [0.83142857, 0.77      ],
#       [0.83      , 0.77666667],
#       [0.83142857, 0.78      ],
#       [0.83857143, 0.78      ],
#       [0.83714286, 0.78666667],
#       [0.84428571, 0.79333333],
#       [0.84571429, 0.79      ],
#       [0.84428571, 0.79333333],
#       [0.84857143, 0.79333333],
#       [0.84857143, 0.78666667],
#       [0.85      , 0.79333333],
#       [0.84857143, 0.78333333],
#       [0.85142857, 0.78333333]])

plt.plot(list(range(1, 21)), np.array(score_l)[:,0], label='train_acc')
plt.plot(list(range(1, 21)), np.array(score_l)[:,1], label='test_acc')
plt.legend(loc = 4)

在这里插入图片描述

  • 最终,我们能够较为明显的看出,伴随着模型越来越复杂(特征越来越多),训练集准确率逐渐提升。
  • 但测试集准确率却在一段时间后开始下降,说明模型经历了由开始的欠拟合到拟合再到过拟合的过程,和上一小节介绍的模型结构风险伴随模型复杂度提升而提升的结论一致。

在这里插入图片描述

  • 而接下来的问题就是,如何同时控制结构风险和经验风险。
  • 根据上一小节的介绍,采用正则化将是一个不错的选择,当然我们也可以直接从上图中的曲线变化情况来挑选最佳的特征衍生个数。
  • 接下来,我们尝试对上述模型进行手动调参。

三、评估器的手动调参

  • 根据上一小节的介绍,我们知道,对于过拟合,我们可以通过 l 1 l1 l1 l 2 l2 l2 正则化来抑制过拟合影响,并且从上一小节我们得知,一个比较好的建模流程是先进行数据增强(特征衍生),来提升模型表现,然后再通过正则化的方式来抑制过拟合倾向。
  • 接下来,我们就上述问题来进行相关尝试。
  • 验证正则化对过拟合的抑制效果
# 测试l1正则化
pl1 = plr(degree=10, penalty='l1', C=1.0)

pl1.fit(X_train, y_train)

pl1.set_params(logisticregression__solver='saga')
#Pipeline(steps=[('polynomialfeatures',
#                 PolynomialFeatures(degree=10, include_bias=False)),
#                ('standardscaler', StandardScaler()),
#                ('logisticregression',
#                 LogisticRegression(max_iter=1000000, penalty='l1',
#                                    solver='saga'))])

pl1.fit(X_train, y_train)
pl1.score(X_train, y_train),pl1.score(X_test, y_test)
#(0.7914285714285715, 0.7833333333333333)

# 测试l2正则化
pl2 = plr(degree=10, penalty='l2', C=1.0).fit(X_train, y_train)
pl2.score(X_train, y_train),pl2.score(X_test, y_test)
#(0.8071428571428572, 0.79)

pr3.score(X_train, y_train),pr3.score(X_test, y_test)
#(0.8314285714285714, 0.79)

plot_decision_boundary(X, y, pr3)

在这里插入图片描述

plot_decision_boundary(X, y, pl1)

在这里插入图片描述

plot_decision_boundary(X, y, pl2)

在这里插入图片描述

  • 尽管从决策边界上观察并不明显,但从最终建模结果来看,正则化确实起到了抑制过拟合的效果。接下来我们尝试手动对上述模型进行调参,尝试能否提高模型表现。
  • 此处我们采用一个非常朴素的想法来进行调参,即使用 degree、C 和正则化选项( l 1 l1 l1 l 2 l2 l2)的不同组合来进行调参,试图从中选择一组能够让模型表现最好的参数,并且先从 degree 开始进行搜索:
  • l 1 l1 l1 正则化下最优特征衍生阶数
# 用于存储不同模型训练准确率与测试准确率的列表
score_l1 = []# 实例化多组模型,测试模型效果
for degree in range(1, 21):
    pr_temp = plr(degree=degree, penalty='l1')
    pr_temp.set_params(logisticregression__solver='saga')
    pr_temp.fit(X_train, y_train)
    score_temp = [pr_temp.score(X_train, y_train),pr_temp.score(X_test, y_test)]
    score_l1.append(score_temp)
    
# 观察最终结果
plt.plot(list(range(1, 21)), np.array(score_l1)[:,0], label='train_acc')
plt.plot(list(range(1, 21)), np.array(score_l1)[:,1], label='test_acc')
plt.legend(loc = 4)

在这里插入图片描述

score_l1
#[[0.7, 0.7133333333333334],
# [0.79, 0.79],
# [0.7885714285714286, 0.7933333333333333],
# [0.7914285714285715, 0.7933333333333333],
# [0.7885714285714286, 0.7833333333333333],
# [0.7928571428571428, 0.7833333333333333],
# [0.7957142857142857, 0.7766666666666666],
# [0.7914285714285715, 0.7833333333333333],
# [0.7957142857142857, 0.78],
# [0.7914285714285715, 0.7833333333333333],
# [0.7914285714285715, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.79],
# [0.7871428571428571, 0.79],
# [0.7871428571428571, 0.79],
# [0.7871428571428571, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.7933333333333333]]
  • 此处我们选取 3 阶为下一步搜索参数时确定的 degree 参数取值。
  • l 2 l2 l2 正则化下最优特征衍生阶数
# 用于存储不同模型训练准确率与测试准确率的列表
score_l2 = []# 实例化多组模型,测试模型效果
for degree in range(1, 21):
    pr_temp = plr(degree=degree, penalty='l2')
    pr_temp.fit(X_train, y_train)
    score_temp = [pr_temp.score(X_train, y_train),pr_temp.score(X_test, y_test)]
    score_l2.append(score_temp)
    
# 观察最终结果
plt.plot(list(range(1, 21)), np.array(score_l2)[:,0], label='train_acc')
plt.plot(list(range(1, 21)), np.array(score_l2)[:,1], label='test_acc')
plt.legend(loc = 4)

在这里插入图片描述

score_l2
#[[0.7, 0.7066666666666667],
# [0.79, 0.7966666666666666],
# [0.79, 0.7833333333333333],
# [0.7914285714285715, 0.79],
# [0.7914285714285715, 0.78],
# [0.7985714285714286, 0.7933333333333333],
# [0.7971428571428572, 0.7833333333333333],
# [0.8, 0.7866666666666666],
# [0.8057142857142857, 0.79],
# [0.8071428571428572, 0.79],
# [0.8085714285714286, 0.79],
# [0.8071428571428572, 0.7933333333333333],
# [0.81, 0.7933333333333333],
# [0.81, 0.7966666666666666],
# [0.8128571428571428, 0.7966666666666666],
# [0.8114285714285714, 0.7966666666666666],
# [0.8128571428571428, 0.7966666666666666],
# [0.8128571428571428, 0.7966666666666666],
# [0.8128571428571428, 0.7966666666666666],
# [0.8128571428571428, 0.7966666666666666]]
  • 此处我们选取 15 阶为下一步搜索参数时确定的 degree 参数取值。
  • 接下来继续搜索 C 的取值:
# 用于存储不同模型训练准确率与测试准确率的列表
score_l1_3 = []

# 实例化多组模型,测试模型效果
for C in np.arange(0.5, 2, 0.1):
    pr_temp = plr(degree=3, penalty='l1', C=C)
    pr_temp.set_params(logisticregression__solver='saga')
    pr_temp.fit(X_train, y_train)
    score_temp = [pr_temp.score(X_train, y_train),pr_temp.score(X_test, y_test)]
    score_l1_3.append(score_temp)
    
# 观察最终结果
plt.plot(list(np.arange(0.5, 2, 0.1)), np.array(score_l1_3)[:,0], label='train_acc')
plt.plot(list(np.arange(0.5, 2, 0.1)), np.array(score_l1_3)[:,1], label='test_acc')
plt.legend(loc = 4)

在这里插入图片描述

score_l1_3
#[[0.7871428571428571, 0.7966666666666666],
# [0.7885714285714286, 0.7966666666666666],
# [0.7885714285714286, 0.7966666666666666],
# [0.7885714285714286, 0.7966666666666666],
# [0.7885714285714286, 0.7966666666666666],
# [0.7885714285714286, 0.7933333333333333],
# [0.7885714285714286, 0.7933333333333333],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.79],
# [0.7885714285714286, 0.7866666666666666],
# [0.79, 0.7866666666666666],
# [0.7914285714285715, 0.7866666666666666],
# [0.7914285714285715, 0.7866666666666666],
# [0.7928571428571428, 0.7866666666666666]]

# 用于存储不同模型训练准确率与测试准确率的列表
score_l2_15 = []# 实例化多组模型,测试模型效果
for C in np.arange(0.5, 2, 0.1):
    pr_temp = plr(degree=15, penalty='l2', C=C)
    pr_temp.fit(X_train, y_train)
    score_temp = [pr_temp.score(X_train, y_train),pr_temp.score(X_test, y_test)]
    score_l2_15.append(score_temp)
    
# 观察最终结果
plt.plot(list(np.arange(0.5, 2, 0.1)), np.array(score_l2_15)[:,0], label='train_acc')
plt.plot(list(np.arange(0.5, 2, 0.1)), np.array(score_l2_15)[:,1], label='test_acc')
plt.legend(loc = 4)

在这里插入图片描述

score_l2_15
#[[0.8057142857142857, 0.7866666666666666],
# [0.8071428571428572, 0.7866666666666666],
# [0.8057142857142857, 0.7866666666666666],
# [0.8071428571428572, 0.7866666666666666],
# [0.81, 0.79],
# [0.8128571428571428, 0.7966666666666666],
# [0.8114285714285714, 0.7966666666666666],
# [0.8128571428571428, 0.8],
# [0.8142857142857143, 0.8],
# [0.8157142857142857, 0.8],
# [0.8142857142857143, 0.8],
# [0.8142857142857143, 0.8],
# [0.8142857142857143, 0.8],
# [0.8128571428571428, 0.8],
# [0.8128571428571428, 0.8]]
  • 最终,我们通过蛮力搜索,确定了一组能够让测试集准确率取得最大值的参数组合:degree=15, penalty=‘l2’, C=1.0,此时测试集准确率为 0.8。
  • 手动调参评价
  • 尽管上述过程能够帮助我们最终找到一组相对比较好的参数组合,最终建模结果相比此前,也略有提升,但上述手动调参过程存在三个致命问题:
  • (1) 过程不够严谨,诸如测试集中测试结果不能指导建模、参数选取及搜索区间选取没有理论依据等问题仍然存在;
  • (2) 执行效率太低,如果面对更多的参数(这是更一般的情况),手动执行过程效率太低,无法进行超大规模的参数挑选;
  • (3) 结果不够精确,一次建模结果本身可信度其实并不高,我们很难证明上述挑选出来的参数就一定在未来数据预测中拥有较高准确率。
  • 而要解决这些问题,我们就需要补充关于机器学习调参的理论基础,以及掌握更多更高效的调参工具。正因如此,我们将在后续文章详细介绍关于机器学习调参的基本理论以及 sklearn 中的网格搜索调参工具,而后我们再借助更完整的理论、更高效的工具对上述问题进行解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/333012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ts笔记第一天

文章目录安装 ts运行环境 nodeTS类型数字 、字符串 和布尔类型字面量any 和unknown类型断言void和neverobjectArraytuple 元组enum 枚举安装 ts运行环境 node node-v看版本号 2. 安装ts -g全局安装 npm i -g typescript // 这里全局安装 -s安装无法使用tsc 创建一个01.ts文…

第五十章 动态规划——数位DP模型

第五十章 动态规划——数位DP模型一、什么是数位DP数位DP的识别数位DP的思路二、例题1、AcWing 1083. Windy数&#xff08;数位DP&#xff09;2、AcWing 1082. 数字游戏&#xff08;数位DP&#xff09;3、AcWing 1081. 度的数量&#xff08;数位DP&#xff09;一、什么是数位DP…

供应PEG试剂AC-PEG-COOH,Acrylate-PEG-Acid,丙烯酸酯-PEG-羧基

英文名称&#xff1a;AC-PEG-COOH&#xff0c;Acrylate-PEG-Acid 中文名称&#xff1a;丙烯酸酯-聚乙二醇-羧基 丙烯酸酯-PEG-COOH是一种含有丙烯酸酯和羧酸的线性杂双功能PEG试剂。它是一种有用的带有PEG间隔基的交联剂。丙烯酸酯可与紫外光或自由基引发剂聚合。丙烯酸酯-PE…

从FPGA说起的深度学习(二)

这是新的系列教程&#xff0c;在本教程中&#xff0c;我们将介绍使用 FPGA 实现深度学习的技术&#xff0c;深度学习是近年来人工智能领域的热门话题。在本教程中&#xff0c;旨在加深对深度学习和 FPGA 的理解。用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为硬…

Leetcode.1797 设计一个验证系统

题目链接 Leetcode.1797 设计一个验证系统 Rating : 1534 题目描述 你需要设计一个包含验证码的验证系统。每一次验证中&#xff0c;用户会收到一个新的验证码&#xff0c;这个验证码在 currentTime时刻之后 timeToLive秒过期。如果验证码被更新了&#xff0c;那么它会在 curr…

完成各种项目生态环评工作丨全流程基于最新导则下的生态环境影响评价技术方法及图件制作与案例

目录 专题一 生态环境影响评价框架及流程 专题二 基于遥感解译的土地利用现状图的编制 专题三 生物多样性测定及R语言分析 专题四 植被类型及植被覆盖度图的编制 专题五 生物量与净初级生产力测定&#xff1a;实测及模型 专题六 生态系统类型及服务价值评估 专题七 物种…

【漫漫转码路】Day 45 机器学习 day04

梯度下降 梯度下降法是常用于求解无约束情况下凸函数的极小值&#xff0c;是一种迭代类型的算法&#xff0c;因为凸函数只有一个极值点&#xff0c;故求解出来的极小值点就是函数的最小值点 公式 第一个θ&#xff0c;是更新之后的θ&#xff0c;第二个θ是更新之前的θ&…

数据挖掘,计算机网络、操作系统刷题笔记47

数据挖掘&#xff0c;计算机网络、操作系统刷题笔记47 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;orac…

【LeetCode】1797. 设计一个验证系统

1797. 设计一个验证系统 题目描述 你需要设计一个包含验证码的验证系统。每一次验证中&#xff0c;用户会收到一个新的验证码&#xff0c;这个验证码在 currentTime 时刻之后 timeToLive 秒过期。如果验证码被更新了&#xff0c;那么它会在 currentTime &#xff08;可能与之…

理解HDFS工作流程与机制,看这篇文章就够了

HDFS(The Hadoop Distributed File System) 是最初由Yahoo提出的分布式文件系统&#xff0c;它主要用来&#xff1a; 1&#xff09;存储大数据 2&#xff09;为应用提供大数据高速读取的能力 重点是掌握HDFS的文件读写流程&#xff0c;体会这种机制对整个分布式系统性能提升…

训练营day16

104.二叉树的最大深度 559.n叉树的最大深度111.二叉树的最小深度222.完全二叉树的节点个数104.二叉树的最大深度 力扣题目链接 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示…

javaEE 初阶 — UDP 协议

文章目录UDP 协议1. UDP协议报文结构1.1 一个 UDP 数据报能传输的最大数据1.2 校验和1.3 生成校验和的算法UDP 协议 1. UDP协议报文结构 16位UDP长度&#xff0c;表示整个数据报&#xff08;UDP首部UDP数据&#xff09;的最大长度&#xff0c;如果校验和出错&#xff0c;就会直…

计算机网络之http02| HTTPS HTTP1.1的优化

post与get请求的区别 get 是获取资源&#xff0c;Post是向指定URI提交资源&#xff0c;相关信息放在body里 2.http有哪些优点 &#xff08;1&#xff09;简单 报文只有报文首部和报文主体&#xff0c;易于理解 &#xff08;2&#xff09;灵活易拓展 URI相应码、首部字段都没有…

ORB-SLAM2编译、安装等问题汇总大全(Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10)

ORB-SLAM2编译、安装等问题汇总大全&#xff08;Ubuntu20.04、eigen3、pangolin0.5、opencv3.4.10&#xff09; 1&#xff1a;环境说明: 使用的Linux发行版本为Ubuntu 20.04 SLAM2下载地址为&#xff1a;git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2 2&a…

Element UI框架学习篇(二)

Element UI框架学习篇(二) 1 整体布局 1.1 前提说明 el-container标签里面的标签默认是从左往右排列,若想要从上往下排列,只需要写el-header或者el-footer就行了 <el-container>&#xff1a;外层容器 <el-header>&#xff1a;顶栏容器。 <el-aside>&#…

Android框架源码分析——从设计模式角度看 Retrofit 核心源码

Android框架源码分析——从设计模式角度看 Retrofit 核心源码 Retrofit中用到了许多常见的设计模式&#xff1a;代理模式、外观模式、构建者模式等。我们将从这三种设计模式入手&#xff0c;分析 Retrofit2 的核心源码。 1. 宏观 Retrofit 是一个外观模式的设计 外观模式&am…

Intel处理器分页机制

分页模式 Intel 64位处理器支持3种分页模式&#xff1a; 32-bit分页PAE分页IA-32e分页 32-bit分页 32-bit分页模式支持两种页面大小&#xff1a;4KB以及4MB。 4KB页面的线性地址转换 4MB页面的线性地址转换 PAE分页模式 PAE分页模式支持两种页面大小&#xff1a;4KB以及…

Java 验证二叉搜索树

验证二叉搜索树中等给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。有效 二叉搜索树定义如下&#xff1a;节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。示例 1&…

ChatGPT注册流程攻略,含验证码接收(图文步骤)

本文给大家分享一下我成功注册的流程&#xff01; 其实方法都类似&#xff0c;若无海外手机号码可用接验证码的平台&#xff08;ps&#xff1a;我之前使用的是SMS-Activate&#xff09; 必要准备 能够科学上网&#xff08;并且全局模式&#xff09; 能确认登录的电子邮箱&…

ffmpeg硬解码与软解码的压测对比

文章目录ffmpeg硬解码与软解码的压测一、基本知识二、压测实验1. 实验条件及工具说明2. 压测脚本3. 实验数据结果ffmpeg硬解码与软解码的压测 一、基本知识 本文基于intel集显进行压测 软解码&#xff1a;cpu对视频进行解码硬解码&#xff1a;显卡或者多媒体处理芯片对视频进…