-
错误类型
-
第一种是用苍蝇拍来杀死哥斯拉龙, 它过度简化了我们要解决的问题, 当我们过度简化问题时 我们称之为欠拟合
image.png
-
另一种是用火箭筒杀死苍蝇, 它过度复杂化了我们要解决的问题, 当我们过度复杂化时称之为过拟合, 也即模型太具体
image.png
-
通过回归进行理解
-
欠拟合(右边的直线并没有很好的反应训练集)
image.png -
过拟合(右边的曲线对训练集良好, 但是无法对测试集进行良好泛化)
image.png
-
-
通过分类模型进行理解
-
欠拟合
image.png -
过拟合
image.png
-
-
好的模型
image.png
-
-
模型复杂性图(检测上述的两种错误, 欠拟合和过拟合)
-
一次线性模型,
image.png -
二次方程模型,
image.png -
六次多项式模型
image.png -
模型复杂度图
- 左侧是一个欠拟合模型, 具有较高的训练误差和测试误差
- 右边的模型过拟合, 具有较低的训练误差和较高的测试误差
-
中间的模型刚刚好, 具有相对较低的训练和测试误差
image.png
-
注意: 请勿使用测试集进行训练, 再不使用测试集的情况下, 对模型做出决定, 可以进一步拆分数据集, 获取交叉验证集
- 训练集用于训练参数
- 交叉验证集用于对模型做出决定, 例如多项式的次数
- 测试集将用于模型的最终测试
-
模型复杂图的一般图示
image.png
-
-
K-fold交叉验证
- 将数据集分成K个桶, 例如K=4, 然后训练模型K次, 每一次使用不同的桶作为测试集, 剩下的数据作为训练集, 然后将训练K次后的模型求均值
-
学习曲线
image.png
-
用学习曲线检测欠拟合和过拟合以选择最佳模型
- 数据如图所示
-
通过对SVM, Logistic Regression, Decision Tree对以上所示数据进行分类
-
学习曲线代码实现
train_sizes, train_scores, test_scores = learning_curve( estimator, X, y, cv=None, n_jobs=1, train_sizes=np.linspace(.1, 1.0, num_trainings))
-
estimator
是所使用的分类器, e.g.,LogisticRegression()
orGradientBoostingClassifier()
. -
X
和y
是被分类的数据进行分割后特征
和标签
-
train_sizes
用于绘制学习曲线中每个点的数据块的大小 -
train_scores
是针对每个数据块训练的算法的训练分数 -
test_scores
是在每个数据块上训练的算法的测试分数
# Import, read, and split data
import pandas as pd
data = pd.read_csv('data.csv')
import numpy as np
X = np.array(data[['x1', 'x2']])
y = np.array(data['y'])
# Fix random seed
np.random.seed(55)
### Imports
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.svm import SVC
# TODO: Uncomment one of the three classifiers, and hit "Test Run"
# to see the learning curve. Use these to answer the quiz below.
### Logistic Regression
#estimator = LogisticRegression()
### Decision Tree
#estimator = GradientBoostingClassifier()
### Support Vector Machine
#estimator = SVC(kernel='rbf', gamma=1000)
from sklearn.model_selection import learning_curve
# It is good to randomize the data before drawing Learning Curves
def randomize(X, Y):
permutation = np.random.permutation(Y.shape[0])
X2 = X[permutation,:]
Y2 = Y[permutation]
return X2, Y2
X2, y2 = randomize(X, y)
def draw_learning_curves(X, y, estimator, num_trainings):
train_sizes, train_scores, test_scores = learning_curve(
estimator, X2, y2, cv=None, n_jobs=1, train_sizes=np.linspace(.1, 1.0, num_trainings))
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.grid()
plt.title("Learning Curves")
plt.xlabel("Training examples")
plt.ylabel("Score")
plt.plot(train_scores_mean, 'o-', color="g",
label="Training score")
plt.plot(test_scores_mean, 'o-', color="y",
label="Cross-validation score")
plt.legend(loc="best")
plt.show()
image.png
-
上面的模型:Logistic回归模型使用的是一条过于简单的线。 它在训练集上表现不佳。 因此,它不合适。 决策树模型使用正方形,这非常适合,并且很好地概括。 因此,这个模型很好。 支持向量机模型实际上在每个点周围绘制一个小圆圈。 这显然只是记住训练集,并不会很好地概括。 因此,它过度拟合。
-
网格搜索
- 逻辑回归: 如下图所示, 在训练数据集上从自由度1到4计算出四个模型, 即第二列, 然后通过交叉验证集通过对F1进行排序选出得分最高的一个模型, 然后再测试集上进行测试是否为最佳模型.
-
决策树: 如下图所示, 在训练数据集上从树深度1到4计算出四个模型, 即第二列, 然后通过交叉验证集通过对F1进行排序选出得分最高的一个模型, 然后再测试集上进行测试是否为最佳模型.
image.png
-
支持向量机:
-
支持向量机包含的超参数, 如下图所示
image.png
-
-
如何选取模型的超参数???, 例如支持向量机的gamma和kernal
-
需要用到网格搜索技巧, 如果像支持向量机一样只考虑两个超参数, 那么可以将每个超参数分别作为表格的x,y, 然后找出所有的可能性, 并分别在每个可能性下计算模型, 如下图所示, 然后找出最优模型, 通过F1值.
image.png
-
-
网格搜索的sklearn实现
-
在 sklearn 中的网格搜索非常简单。我们用一个例子来说明它。假设我们要训练一个支持向量机, 我们想在以下参数之间做出决定:
- kernal :
poly
rbf
. - C: 0.1、1或10。
- kernal :
-
第一步: 导入网格搜索package
from sklearn.model_selection import GridSearchCV
-
第二步: 选择参数, 在这里, 我们选择我们要选择的参数是什么, 然后形成一个字典。在此字典中, 键将是参数的名称, 值将是每个参数的可能值列表。
parameters = {'kernal':['poly','rbf'], 'C':[0.1,1,10]}
-
第三步: 构建评分器, 我们需要决定用什么指标来为每个候选模型打分。在这里, 我们将使用 f1 分数。
from sklearn.metrics import make_scorer from sklearn.metrics import f1_score scorer = make_scorer(f1_score)
-
第四步: 创建一个含有超参数和评分器的网格搜索对象
# Create the object. grid_obj = GridSearchCV(clf, parameters, scoring=scorer) # Fit the data grid_fit = grid_obj.fit(X,y)
-
第五步: 获得最优估计
best_clf = grid_fit.best_estimator_
-
网友评论