火车损失和验证损失GradientBoostingClassifier

时间:2018-05-26 17:26:08

标签: python machine-learning scikit-learn

我正在学习为7个班级的Cover Type数据做分类。我使用scikit-learn的GradientBoostingClassifier训练我的模型。当我试图绘制我的损失函数时,这就像这样:

enter image description here

这种情节是否表明我的模型存在很大差异?如果是,我该怎么办?我不知道为什么在迭代200到500的中间,情节形状像一个矩形。

(适用EDIT) 要编辑这篇文章,我不确定我的代码有什么问题,因为我只是使用常规代码来拟合训练数据。我正在使用jupyter笔记本。所以我只是提供代码

Y = train["Cover_Type"]
X = train.drop({"Cover_Type"}, axis=1) 

#split training data dan cross validation
from sklearn.model_selection import train_test_split

X_train, X_val, Y_train, Y_val = train_test_split(X,Y,test_size=0.3,random_state=42)

from sklearn.metrics import mean_squared_error
from sklearn.datasets import make_friedman1
from sklearn.ensemble import GradientBoostingClassifier

params = {'n_estimators': 1000,'learning_rate': 0.3, 'max_features' : 'sqrt'}

dtree=GradientBoostingClassifier(**params)
dtree.fit(X_train,Y_train)

#mau lihat F1-Score
from sklearn.metrics import f1_score

Y_pred = dtree.predict(X_val) #prediksi data cross validation menggunakan model tadi
print Y_pred
score = f1_score(Y_val, Y_pred, average="micro") 

print("Gradient Boosting Tree F1-score: "+str(score)) # I got 0.86 F1-Score

import matplotlib.pyplot as plt
# Plot training deviance

# compute test set deviance
val_score = np.zeros((params['n_estimators'],), dtype=np.float64)

for i, Y_pred in enumerate(dtree.staged_predict(X_val)):
    val_score[i] = dtree.loss_(Y_val, Y_pred.reshape(-1, 1))

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title('Deviance')
plt.plot(np.arange(params['n_estimators']) + 1, dtree.train_score_, 'b-',
             label='Training Set Deviance')
plt.plot(np.arange(params['n_estimators']) + 1, val_score, 'r-',
             label='Validation Set Deviance')
plt.legend(loc='upper right')
plt.xlabel('Boosting Iterations')
plt.ylabel('Deviance')

2 个答案:

答案 0 :(得分:0)

有几个问题,我将一一解释,也为您的示例添加了正确的代码。

    不得使用
  1. staged_predict(X)方法

    • 由于staged_predict(X)输出预测的类别而不是预测的概率,因此使用它是不正确的。
    • 一个人可以(在上下文可以接受的情况下)使用staged_decision_function(X)方法,并将在每个阶段计算出的决策传递给model.loss_属性。但是在this示例中,它不起作用(基于阶段决策的损失增加而损失减少)。
  2. 您应该将staged_predict_proba(X)用于交叉熵损失

    • 您应该使用staged_predict_proba(X)
    • 您还需要定义一个函数来计算每个阶段的交叉熵损失。
    • 我提供了以下代码。请注意,我将详细程度设置为2,然后您可以看到每个阶段的sklearn训练损失与我们的损失相同(作为健全性检查,我们的方法可以正常工作)。
  3. 为什么会有大的飞跃

    • 我认为原因是GBC变得非常有信心,然后以概率 1 来预测标签为1(例如),但不正确(例如标签为2)。这会产生很大的跳跃(因为交叉熵达到无穷大)。在这种情况下,您应该更改GBC参数。
  4. 代码和图解在下面给出

    • 代码是:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_covtype
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier


def _cross_entropy_like_loss(model, input_data, targets, num_estimators):
    loss = np.zeros((num_estimators, 1))
    for index, predict in enumerate(model.staged_predict_proba(input_data)):
        loss[index, :] = -np.sum(np.log([predict[sample_num, class_num-1]
                                         for sample_num, class_num in enumerate(targets)])) 
        print(f'ce loss {index}:{loss[index, :]}')
    return loss


covtype = fetch_covtype()
X = covtype.data
Y = covtype.target
n_estimators = 10
X_train, X_val, Y_train, Y_val = train_test_split(X, Y, test_size=0.3, random_state=42)
clf = GradientBoostingClassifier(n_estimators=n_estimators, learning_rate=0.3, verbose=2 )
clf.fit(X_train, Y_train)


tr_loss_ce = _cross_entropy_like_loss(clf, X_train, Y_train, n_estimators)
test_loss_ce = _cross_entropy_like_loss(clf, X_val, Y_val, n_estimators)


plt.figure()
plt.plot(np.arange(n_estimators) + 1, tr_loss_ce, '-r', label='training_loss_ce')
plt.plot(np.arange(n_estimators) + 1, test_loss_ce, '-b', label='val_loss_ce')
plt.ylabel('Error')
plt.xlabel('num_components')
plt.legend(loc='upper right')
  • 控制台的输出如下所示,您可以从中轻松验证该方法是否正确。
     Iter       Train Loss   Remaining Time 
         1      482434.6631            1.04m
         2      398501.7223           55.56s
         3      351391.6893           48.51s
         4      322290.3230           41.60s
         5      301887.1735           34.65s
         6      287438.7801           27.72s
         7      276109.2008           20.82s
         8      268089.2418           13.84s
         9      261372.6689            6.93s
        10      256096.1205            0.00s
ce loss 0:[ 482434.6630936]
ce loss 1:[ 398501.72228276]
ce loss 2:[ 351391.68933547]
ce loss 3:[ 322290.32300604]
ce loss 4:[ 301887.17346783]
ce loss 5:[ 287438.7801033]
ce loss 6:[ 276109.20077844]
ce loss 7:[ 268089.2418214]
ce loss 8:[ 261372.66892149]
ce loss 9:[ 256096.1205235]

答案 1 :(得分:-1)

好像你有几个问题。很难说,因为你没有提供任何代码。

我的模型是否存在高差异?

首先,您的模型从一开始就过度拟合。你可以说这是事实,因为你的验证损失正在增加,尽管你的训练正在减少。有趣的是,您的验证损失从一开始就在增加,这表明您的模型无法正常工作。所以要回答你的问题,是的,它会受到高度差异的影响。

我该怎么办?

您确定数据存在趋势吗?验证从一开始就增加的事实暗示该模型根本不适用于您的数据,您的数据没有趋势,或者您的代码存在问题。也许尝试其他模型,并确保您的代码是正确的。同样,如果没有minimal example,很难说。

奇怪的矩形

这看起来很奇怪。验证集中的数据存在问题(因为验证集不会产生这种影响),或者您的代码存在问题。如果您提供样品,我们可能会帮助您更多。