码迷,mamicode.com
首页 > 编程语言 > 详细

python 机器学习中模型评估和调参

时间:2017-12-22 12:24:14      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:分布   form   降维   red   transform   步骤   模型训练   tween   输入   

在做数据处理时,需要用到不同的手法,如特征标准化,主成分分析,等等会重复用到某些参数,sklearn中提供了管道,可以一次性的解决该问题

先展示先通常的做法

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression

df = pd.read_csv(wdbc.csv)
X = df.iloc[:, 2:].values
y = df.iloc[:, 1].values
# 标准化
sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)
# 主成分分析PCA
pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_std)
X_test_pca = pca.transform(X_test_std)
# 逻辑斯蒂回归预测
lr = LogisticRegression(random_state=1)
lr.fit(X_train_pca, y_train)
y_pred = lr.predict(X_test_pca)

先对数据标准化,然后做主成分分析降维,最后做回归预测

现在使用管道

from sklearn.pipeline import Pipeline

pipe_lr = Pipeline([(sc, StandardScaler()), (pca, PCA(n_components=2)), (lr, LogisticRegression(random_state=1))])
pipe_lr.fit(X_train, y_train)
pipe_lr.score(X_test, y_test)

Pipeline对象接收元组构成的列表作为输入,每个元组第一个值作为变量名,元组第二个元素是sklearn中的transformer或Estimator。

管道中间每一步由sklearn中的transformer构成,最后一步是一个Estimator。我们的例子中,管道包含两个中间步骤,一个StandardScaler和一个PCA,这俩都是transformer,逻辑斯蒂回归分类器是Estimator。

当管道pipe_lr执行fit方法时,首先StandardScaler执行fit和transform方法,然后将转换后的数据输入给PCA,PCA同样执行fit和transform方法,最后将数据输入给LogisticRegression,训练一个LR模型。

对于管道来说,中间有多少个transformer都可以。工作方式如下

技术分享图片

使用管道减少了很多代码量

现在回归模型的评估和调参

训练机器学习模型的关键一步是要评估模型的泛化能力。如果我们训练好模型后,还是用训练集取评估模型的性能,这显然是不符合逻辑的。一个模型如果性能不好,要么是因为模型过于复杂导致过拟合(高方差),要么是模型过于简单导致导致欠拟合(高偏差)。可是用什么方法评价模型的性能呢?这就是这一节要解决的问题,你会学习到两种交叉验证计数,holdout交叉验证和k折交叉验证, 来评估模型的泛化能力

一、holdout交叉验证(评估模型性能)

holdout方法很简单就是将数据集分为训练集和测试集,前者用于训练,后者用于评估

如果在模型选择的过程中,我们始终用测试集来评价模型性能,这实际上也将测试集变相地转为了训练集,这时候选择的最优模型很可能是过拟合的。

更好的holdout方法是将原始训练集分为三部分:训练集、验证集和测试集。训练机用于训练不同的模型,验证集用于模型选择。而测试集由于在训练模型和模型选择这两步都没有用到,对于模型来说是未知数据,因此可以用于评估模型的泛化能力。下图展示了holdout方法的步骤:

技术分享图片

缺点:它对数据分割的方式很敏感,如果原始数据集分割不当,这包括训练集、验证集和测试集的样本数比例,以及分割后数据的分布情况是否和原始数据集分布情况相同等等。所以,不同的分割方式可能得到不同的最优模型参数

二、K折交叉验证(评估模型性能)

k折交叉验证的过程,第一步我们使用不重复抽样将原始数据随机分为k份,第二步 k-1份数据用于模型训练,剩下那一份数据用于测试模型。然后重复第二步k次,我们就得到了k个模型和他的评估结果(译者注:为了减小由于数据分割引入的误差,通常k折交叉验证要随机使用不同的划分方法重复p次,常见的有10次10折交叉验证)

然后我们计算k折交叉验证结果的平均值作为参数/模型的性能评估。使用k折交叉验证来寻找最优参数要比holdout方法更稳定。一旦我们找到最优参数,要使用这组参数在原始数据集上训练模型作为最终的模型。

k折交叉验证使用不重复采样,优点是每个样本只会在训练集或测试中出现一次,这样得到的模型评估结果有更低的方法。

下图演示了10折交叉验证:

技术分享图片

10次10折交叉验证我的理解是将按十种划分方法,每次将数据随机分成k分,k-1份训练,k份测试。获取十个模型和评估结果,然后取10次的平均值作为性能评估

from sklearn.cross_validation import StratifiedKFold

pipe_lr = Pipeline([(sc, StandardScaler()), (pca, PCA(n_components=2)), (lr, LogisticRegression(random_state=1))]) pipe_lr.fit(X_train, y_train) kfold = StratifiedKFold(y=y_train, n_folds=10, random_state=1) scores= [] for k, (train, test) in enumerate(kfold): pipe_lr.fit(X_train[train], y_train[train]) score = pipe_lr.score(X_train[test], y_train[test]) scores.append(scores) print(Fold: %s, Class dist.: %s, Acc: %.3f %(k+1, np.bincount(y_train[train]), score))print(CV accuracy: %.3f +/- %.3f %(np.mean(scores), np.std(scores)))

更简单的方法

from sklearn.cross_validation import StratifiedKFold

    pipe_lr = Pipeline([(sc, StandardScaler()), (pca, PCA(n_components=2)), (lr, LogisticRegression(random_state=1))])
    pipe_lr.fit(X_train, y_train)
    scores = cross_val_score(estimator=pipe_lr, X=X_train, y=y_train, cv=10, n_jobs=1)
    print(CV accuracy scores: %s %scores)
    print(CV accuracy: %.3f +/- %.3f %(np.mean(scores), np.std(scores)))

cv即k

三、学习曲线(调试算法)

 from sklearn.learning_curve import learning_curve    

    pipe_lr = Pipeline([(scl, StandardScaler()), (clf, LogisticRegression(penalty=l2, random_state=0))])
    train_sizes, train_scores, test_scores = learning_curve(estimator=pipe_lr, X=X_train, y=y_train, train_sizes=np.linspace(0.1, 1.0, 10), cv=10, n_jobs=1)
    train_mean = np.mean(train_scores, axis=1)
    train_std = np.std(train_scores, axis=1)
    test_mean = np.mean(test_scores, axis=1)
    test_std = np.std(test_scores, axis=1)
    plt.plot(train_sizes, train_mean, color=blue, marker=0, markersize=5, label=training accuracy)
    plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color=blue)
    plt.plot(train_sizes, test_mean, color=green, linestyle=--, marker=s, markersize=5, label=validation accuracy)
    plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color=green)
    plt.grid()
    plt.xlabel(Number of training samples)
    plt.ylabel(Accuracy)
    plt.legend(loc=lower right)
    plt.ylim([0.8, 1.0])
    plt.show()

 

python 机器学习中模型评估和调参

标签:分布   form   降维   red   transform   步骤   模型训练   tween   输入   

原文地址:http://www.cnblogs.com/lgh344902118/p/8085309.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!