第8章 多项式回归与模型泛化 学习笔记中

目录

8-4 为什么要训练数据集与测试数据集

为什么使用测试数据集

过拟合

train test split的意义

8-5 学习曲线05-Learning-Curve

8-6 验证数据集与交叉验证

使用交叉验证

回顾网格搜索

cv参数

留一法Loo-CV


8-4 为什么要训练数据集与测试数据集

为什么使用测试数据集

过拟合

模型的泛化能力差

from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler

def PolynomialRegression(degree):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("lin_reg", LinearRegression())
    ])
from sklearn.metrics import mean_squared_error

poly100_reg = PolynomialRegression(degree=100)
poly100_reg.fit(X, y)

y100_predict = poly100_reg.predict(X)
mean_squared_error(y, y100_predict)

机器学习主要解决的是过拟合的问题

 

模型能力太差,不是为了完全拟合这些数据,应该是模型的泛化能力

train test split的意义

 

 

二阶的模型比一阶的模型泛化能力要强

 

10阶时变小,泛化能力下降了,100时就更明显了

 

 

模型复杂度对于不对算法含义不同

knn是k , 多项式回归是n,

对于训练数据就复杂高则准确率会高,但对测试数据就不一样了

过拟合到欠拟合的过程

欠不能表达数据的关系

有眼睛的都是猫或狗,则模型是欠拟合的

毛发是黄色则为过拟合的,太细节的标准做为判断标准

之前的网格搜索一直就是这么干的

8-5 学习曲线05-Learning-Curve

学习曲线

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

train_score = []
test_score = []
for i in range(1, 76):
    lin_reg = LinearRegression()
    lin_reg.fit(X_train[:i], y_train[:i])
    
    y_train_predict = lin_reg.predict(X_train[:i])
    train_score.append(mean_squared_error(y_train[:i], y_train_predict))
    
    y_test_predict = lin_reg.predict(X_test)
    test_score.append(mean_squared_error(y_test, y_test_predict))


plt.plot([i for i in range(1, 76)], np.sqrt(train_score), label="train")
plt.plot([i for i in range(1, 76)], np.sqrt(test_score), label="test")
plt.legend()
plt.show()

def plot_learning_curve(algo, X_train, X_test, y_train, y_test):
    train_score = []
    test_score = []
    for i in range(1, len(X_train)+1):
        algo.fit(X_train[:i], y_train[:i])
    
        y_train_predict = algo.predict(X_train[:i])
        train_score.append(mean_squared_error(y_train[:i], y_train_predict))
    
        y_test_predict = algo.predict(X_test)
        test_score.append(mean_squared_error(y_test, y_test_predict))
        
    plt.plot([i for i in range(1, len(X_train)+1)], 
                               np.sqrt(train_score), label="train")
    plt.plot([i for i in range(1, len(X_train)+1)], 
                               np.sqrt(test_score), label="test")
    plt.legend()
    plt.axis([0, len(X_train)+1, 0, 4])
    plt.show()
    
plot_learning_curve(LinearRegression(), X_train, X_test, y_train, y_test)

from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

def PolynomialRegression(degree):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("lin_reg", LinearRegression())
    ])

poly2_reg = PolynomialRegression(degree=2)
plot_learning_curve(poly2_reg, X_train, X_test, y_train, y_test)

 

稳定后两者的间距很大,这样通常就是过拟合的情况,泛化能力 不够

欠拟合训练数据上大

训练的上小,但测试的上大,两者的间距也大

 

8-6 验证数据集与交叉验证

的训练数据集上误差很好,但测试上不好

所以将数据集分开 

这样肯定比只用全为训练数据要好

有了模型后,通过测试数据上效率最好,调试参数,模型在围绕着测试数据集打转,有可能在测试数据集上过拟合

找到训练的模型在已知测试数据集 上过拟合,如通过将数据分为三部分解决

训练好后,模型给验证数据,找到验证数据的好参数模型

测试数据没有用过,完全不知的

这时的问题是随机,数据集的分割,如果有特殊的数据直接影响模型的结果

为了解决这个问题就是交叉验证

把数据分为k分,比如三分

每一个会有一个模型参数,求匀值 

 

 

from sklearn.neighbors import KNeighborsClassifier

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)
        knn_clf.fit(X_train, y_train)
        score = knn_clf.score(X_test, y_test)
        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, 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)
        scores = cross_val_score(knn_clf, X_train, y_train)
        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)

 

交叉验证和  结果不一样

可能交叉验证的结果要好,1,因为这可能是  中过拟合test数据集的结构  2,分数低,因为它不过拟合数据一般

交叉验证是为了得到最佳的k和p,然后就能有自己的最好的分类器

回顾网格搜索

默认分为三分,i为9种可能,p为5种可能,即45*3= 135个模型的结果

 

用三交叉验证的方式得到的结果,用了完全模型没用的数据来衡量模型

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)

cv参数

把数据分为几分通过CV来决定

留一法Loo-CV

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值