我正在学习为7个班级的Cover Type数据做分类。我使用scikit-learn的GradientBoostingClassifier训练我的模型。当我试图绘制我的损失函数时,这就像这样:
这种情节是否表明我的模型存在很大差异?如果是,我该怎么办?我不知道为什么在迭代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')
答案 0 :(得分:0)
有几个问题,我将一一解释,也为您的示例添加了正确的代码。
staged_predict(X)
方法
staged_predict(X)
输出预测的类别而不是预测的概率,因此使用它是不正确的。staged_decision_function(X)
方法,并将在每个阶段计算出的决策传递给model.loss_
属性。但是在this示例中,它不起作用(基于阶段决策的损失增加而损失减少)。 您应该将staged_predict_proba(X)
用于交叉熵损失
staged_predict_proba(X)
为什么会有大的飞跃
代码和图解在下面给出
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,很难说。
这看起来很奇怪。验证集中的数据存在问题(因为验证集不会产生这种影响),或者您的代码存在问题。如果您提供样品,我们可能会帮助您更多。