Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么可以';t我匹配LGBM';你的简历分数是多少?_Python_Machine Learning_Scikit Learn_Cross Validation_Lightgbm - Fatal编程技术网

Python 为什么可以';t我匹配LGBM';你的简历分数是多少?

Python 为什么可以';t我匹配LGBM';你的简历分数是多少?,python,machine-learning,scikit-learn,cross-validation,lightgbm,Python,Machine Learning,Scikit Learn,Cross Validation,Lightgbm,我无法手动匹配LGBM的简历分数 这是一个MCVE: from sklearn.datasets import load_breast_cancer import pandas as pd from sklearn.model_selection import train_test_split, KFold from sklearn.metrics import roc_auc_score import lightgbm as lgb import numpy as np data = loa

我无法手动匹配LGBM的简历分数

这是一个MCVE:

from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score
import lightgbm as lgb
import numpy as np

data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

folds = KFold(5, random_state=42)

params = {'random_state': 42}

results = lgb.cv(params, lgb.Dataset(X_train, y_train), folds=folds, num_boost_round=1000, early_stopping_rounds=100, metrics=['auc'])
print('LGBM\'s cv score: ', results['auc-mean'][-1])

clf = lgb.LGBMClassifier(**params, n_estimators=len(results['auc-mean']))

val_scores = []
for train_idx, val_idx in folds.split(X_train):
    clf.fit(X_train.iloc[train_idx], y_train.iloc[train_idx])
    val_scores.append(roc_auc_score(y_train.iloc[val_idx], clf.predict_proba(X_train.iloc[val_idx])[:,1]))
print('Manual score: ', np.mean(np.array(val_scores)))
我原以为这两个简历分数是一样的——我随机设定了种子,做了完全相同的事情。然而,它们却有所不同

以下是我得到的输出:

LGBM's cv score:  0.9851513530737058
Manual score:  0.9903622177441328

为什么??我没有正确使用LGMB的
cv
模块吗?

您正在将X拆分为X_序列和X_测试。 对于cv,您将X_列拆分为5倍,而手动将X拆分为5倍。i、 e手动使用的点比cv使用的点多

results=lgb.cv(参数,lgb.Dataset(X\u序列,y\u序列)
更改为
results=lgb.cv(参数,lgb.Dataset(X,y)

此外,可能有不同的参数。例如,lightgbm使用的线程数会改变结果。在cv期间,模型是并行拟合的。因此,使用的线程数可能与手动顺序训练不同

第一次更正后编辑:

使用以下代码,可以使用手动拆分/cv获得相同的结果:

from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score
import lightgbm as lgb
import numpy as np

data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

folds = KFold(5, random_state=42)


params = {
        'task': 'train',
        'boosting_type': 'gbdt',
        'objective':'binary',
        'metric':'auc',
        }

data_all = lgb.Dataset(X_train, y_train)

results = lgb.cv(params, data_all, 
                 folds=folds.split(X_train), 
                 num_boost_round=1000, 
                 early_stopping_rounds=100)

print('LGBM\'s cv score: ', results['auc-mean'][-1])

val_scores = []
for train_idx, val_idx in folds.split(X_train):

    data_trd = lgb.Dataset(X_train.iloc[train_idx], 
                           y_train.iloc[train_idx], 
                           reference=data_all)

    gbm = lgb.train(params,
                    data_trd,
                    num_boost_round=len(results['auc-mean']),
                    verbose_eval=100)

    val_scores.append(roc_auc_score(y_train.iloc[val_idx], gbm.predict(X_train.iloc[val_idx])))
print('Manual score: ', np.mean(np.array(val_scores)))
屈服

LGBM's cv score:  0.9914524426410262
Manual score:  0.9914524426410262

区别在于这一行
reference=data\u all
。在cv过程中,变量的组合(reference)是使用整个数据集(X\u序列)构建的,而在手动for循环中,它是在训练子集(X\u train.iloc[train\u idx])上构建的。通过将引用传递给包含所有数据的数据集,lightGBM将重用相同的分块,得到相同的结果。

可能是您的手动分类器没有使用相同的
num\u boost\u round
early\u stop\u round
参数吗?正如我所见,您没有将它们显式地传递到
\u init\u\u
方法中d或调用
fit
num\u boost\u round
n\u估计器
相同。如果我明确设置估计器的数量,没有必要提前停止啊,好吧,但是如果我们在一种情况下启用了提前停止,而在另一种情况下没有启用,这可能是差异的原因吗?在
cv
在这种情况下,你设置了一个最大迭代次数,一旦你的cv分数没有提高超过
提前停止\u轮
迭代次数,你就停止。在另一种情况下,我直接将这个数字设置为要进行的迭代次数,这是一个好点-我已经纠正了这个错误。但是,结果仍然不匹配。因此,一旦我有了结果,我就可以如果
lightgbm.cv
,如果
lightgbm.LGBMClassifier
的行为不完全相同,我应该如何使用它?我只是接受他们的差异吗?问题是分类过程。我正在编辑我的帖子,给你一个可复制的例子啊,这太棒了!谢谢Florian,我真的很感激你问我使用它的一个好方法是在整个数据集(data_all)上使用更多的树(比如len(results['auc-mean'])*1.1)重新训练模型,而不进行验证。这样做应该可以提高X_测试/y_测试拆分的性能(因为使用了更多的数据,所以添加了更多的树)。