2020-09-03--多项式回归02

  • 验证数据集(Validation )与交叉验证(Cross Validation)
  • 模型正则化-Regularization
  • 岭回归 Ridge Regression
  • LASSO回归
  • 总结Ridge和Lasso

6. 验证数据集(Validation )与交叉验证(Cross Validation)

6.1 验证数据集

使用分割训练数据集测试数据集来判断我们的机器学习性能的好坏,虽然是一个非常好的方案,但是会产生一个问题:针对特定测试数据集过拟合

我们每次使用测试数据来分析性能的好坏。一旦发现结果不好,我们就换一个参数(可能是degree也可能是其他超参数)重新进行训练。这种情况下,我们的模型在一定程度上围绕着测试数据集打转。也就是说我们在寻找一组参数,使得这组参数训练出来的模型在测试结果集上表现的最好。但是由于这组测试数据集是已知的,我们相当于在针对这组测试数据集进行调参,那么他也有可能产生过拟合的情况,也就是我们得到的模型针对测试数据集过拟合了。

那么怎么解决这个问题呢?

解决的方式其实就是:我们需要将我们的问题分为三部分,这三部分分别是训练数据集,验证数据集,测试数据集。 我们使用训练数据集训练好模型之后,将验证数据集送给这个模型,看看这个训练数据集训练的效果是怎么样的,如果效果不好的话,我们重新换参数,重新训练模型。直到我们的模型针对验证数据来说已经达到最优了。 这样我们的模型达到最优以后,再讲测试数据集送给模型,这样才能作为衡量模型最终的性能。换句话说,我们的测试数据集是不参与模型的创建的,而其他两个数据集都参与了训练。但是我们的测试数据集对于模型是完全不可知的,相当于我们在模型这个模型完全不知道的数据。

这种方法还会有一个问题。由于我们的模型可能会针对验证数据集过拟合,而我们只有一份验证数据集,一旦我们的数据集里有比较极端的情况,那么模型的性能就会下降很多,那么为了解决这个问题,就有了交叉验证

6.2 交叉验证 Cross Validation

交叉验证相对来说是比较正规的、比较标准的在我们调整我们的模型参数的时候看我们的性能的方式

交叉验证:在训练模型的时候,通常把数据分成k份,例如分成3份(ABC)(分成k分,k属于超参数),这三份分别作为验证数据集训练数据集。这样随机组合后可以分别产生三个模型,这三个模型,每个模型在测试数据集上都会产生一个性能的指标,这三个指标的平均值作为当前这个算法训练处的模型衡量的标准是怎样的。 由于我们有一个求平均的过程,所以不会由于一份验证数据集中有比较极端的数据而导致模型有过大的偏差,这比我们只分成训练、验证、测试数据集要更加准确。

6.3 验证&交叉验证代码示例

1.生成数据
import numpy as np
from sklearn import datasets

'''1. 生成数据(手写数字)'''
digits = datasets.load_digits()
X = digits.data
y = digits.target
print(X.shape)
# (1797, 64)
2.分割数据,并使用KNN算法寻找最佳超参数k,p
'''2. 分割数据'''
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y)

'''3. 使用KNN算法寻找最佳k,p'''
from sklearn.neighbors import KNeighborsClassifier
best_k,best_p,best_score = 0,0,0
# k为knn中寻找k个最近元素
for k in range(2,11):
    # p为举例计算公式(明科夫斯基距离)
    for p in range(1,6):
        knn = KNeighborsClassifier(n_neighbors=k,p=p,weights='distance')
        knn.fit(X_train,y_train)
        score = knn.score(X_test,y_test)
        # 如果该score的值大于之前中的最好的score,那么重新赋值k,p,score
        if score >best_score:
            best_k, best_p, best_score = k, p, score

print(best_k)
print(best_p)
print(best_score)
# 5
# 2
# 0.9977777777777778
3.使用交叉验证

cross_val_score():将数据分为若干份对算法模型进行随机训练。

'''4. 使用交叉验证'''
# 使用sklearn提供的交叉验证
from sklearn.model_selection import cross_val_score

# 实例化算法
knn_clf = KNeighborsClassifier()
# 返回的是一个数组,有三个元素,说明cross_val_score方法默认将我们的训练数据集分成了三份
# 这三份数据集进行交叉验证后产生了这三个结果
# cv默认为3,可以修改改参数
re = cross_val_score(knn_clf,X_train,y_train,cv=4)
print(re)
# [0.99109792 0.97626113 0.97922849 0.97619048]
4.使用交叉验证寻找最佳超参数k,p
best_k, best_p, best_score = 0, 0, 0
for k in range(2, 11):
    for p in range(1, 6):
        knn_clf = KNeighborsClassifier(weights="distance", n_neighbors=k, p=p)
        # 计算所有的score,
        scores = cross_val_score(knn_clf, X_train, y_train,cv=3)
        # 求平均值
        score = np.mean(scores)
        if score > best_score:
            best_k, best_p, best_score = k, p, score

print("Best K =", best_k)
print("Best P =", best_p)
print("Best Score =", best_score)
# Best K = 4
# Best P = 3
# Best Score = 0.985894580549369
  • 其与普通方式寻找k,p的区别就是在寻找best_score时使用交叉验证数据集,随机组合后的平均结果。其测试集数据从来没有参与训练模型。

通过观察两组调参过程的结果可以发现

  1. 两组调参得出的参数结果是不同的,通常这时候我们更愿意详细使用交叉验证的方式得出的结果。 因为使用train_test_split很有可能只是过拟合了测试数据集得出的结果
    2.使用交叉验证得出的最好分数0.982是小于使用分割训练测试数据集得出的0.986,因为在交叉验证的 过程中,通常不会过拟合某一组的测试数据,所以平均来讲这个分数会稍微低一些

但是使用交叉验证得到的最好参数best_score并不是真正的最好的结果,我们使用这种方式只是为了拿到 一组超参数而已,拿到这组超参数后我们就可以训练处我们的最佳模型。

knn_clf = KNeighborsClassifier(weights='distance',n_neighbors=4,p=3)
# 用我们找到的k和p,来对X_train,y_train整体fit一下,来看他对X_test,y_test的测试结果
knn_clf.fit(X_train,y_train)
# 注意这个X_test,y_test在交叉验证过程中是完全没有用过的,也就是说我们这样得出的结果是可信的
score = knn_clf.score(X_test,y_test)
print(score)
# 0.9822222222222222

X_test,y_test从来没有参与过模型的训练,所以这个结果是很好的。

6.4 回顾网格搜索

我们上面的操作,实际上在网格搜索的过程中已经进行了,只不过这个过程是sklean的网格搜索自带的一个过程。

from sklearn.model_selection import GridSearchCV

param_grid = [
    {
        'weights': ['distance'],
        'n_neighbors': [i for i in range(2, 11)], 
        'p': [i for i in range(1, 6)]
    }
]

grid_search = GridSearchCV(knn_clf, param_grid, verbose=1)
grid_search.fit(X_train, y_train)
Fitting 3 folds for each of 45 candidates, totalling 135 fits

[Parallel(n_jobs=1)]: Done 135 out of 135 | elapsed:  1.9min finished

意思是:对于k,p,有45种组合(9*6),每次组合都要将数据分为是3份进随机进行训练模型,这样的话要训练135次模型。

score = grid_search.best_score_
print(score)
# 0.985894580549369

param = grid_search.best_params_
print(param)
# {'n_neighbors': 3, 'p': 4, 'weights': 'distance'}

best_knn_clf = grid_search.best_estimator_
score = best_knn_clf.score(X_test, y_test)
print(score)
# 0.98

6.5 cv参数

cv:将数据分为若干份,随机组合训练模型。默认为3

cross_val_score(knn_clf, X_train, y_train, cv=5)
# array([ 0.99543379,  0.96803653,  0.98148148,  0.96261682,  0.97619048])

grid_search = GridSearchCV(knn_clf, param_grid, verbose=1, cv=5)

6.6 总结

虽然整体速度慢了,但是这个结果却是可信赖的。

7.模型正则化-Regularization

7.1 什么是模型正则化

下图是我们之前使用多项式回归过拟合一个样本的例子,可以看到这条模型曲线非常的弯曲,而且非常的陡峭,可以想象这条曲线的一些θ系数会非常的大。 模型正则化需要做的事情就是限制这些系数的大小

7.2 模型正则化基本原理

也就是在损失函数的基础上加上关于theta值的式子,使J(theta)既要保证误差最小,还要保证theta值不会变的很大。

注意:

  • 对于θ的求和i是从1到n,没有将θ0加进去,因为他不是任意一项的系数,他只是一个截距,决定了整个曲线的高低,但是不决定曲线每一部分的陡峭和缓和。

  • θ求和的系数1/2是一个惯例,加不加都可以,加上的原因是因为,将来对θ2>求导的时候可以抵消系数2,方便计算。不要也是可以的。

  • α实际上是一个超参数,代表在我们模型正则化下新的损失函数中,我们要让每一个θ尽可能的小,小的程度占我们整个损失函数的多少。如果α等于0,相当于没有正则化;如果α是正无穷的话,那么我们主要的优化任务就是让每一个θ尽可能的 小。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344