2016-06-06 2 views
1

Я пытаюсь использовать xgboost на pythonXGBoost на python: что не так с xgb.cv?

вот мой код. xgb.train работает, но я получаю об ошибке с xgb.cv , хотя, кажется, я использовал это правильный путь

следующие работы для меня

###### XGBOOST ###### 

import datetime 
startTime = datetime.datetime.now() 

import xgboost as xgb 
data_train = np.array(traindata.drop('Category',axis=1)) 
labels_train = np.array(traindata['Category'].cat.codes) 

data_valid = np.array(validdata.drop('Category',axis=1)) 
labels_valid = np.array(validdata['Category'].astype('category').cat.codes) 

weights_train = np.ones(len(labels_train)) 
weights_valid = np.ones(len(labels_valid)) 

dtrain = xgb.DMatrix(data_train, label=labels_train,weight = weights_train) 
dvalid = xgb.DMatrix(data_valid , label=labels_valid ,weight = weights_valid) 




param = {'bst:max_depth':5, 'bst:eta':0.05, # eta [default=0.3] 
     #'min_child_weight':1,'gamma':0,'subsample':1,'colsample_bytree':1,'scale_pos_weight':0, # default 
     # max_delta_step:0 # default 
     'min_child_weight':5,'scale_pos_weight':0, 'max_delta_step':2, 
     'subsample':0.8,'colsample_bytree':0.8, 
     'silent':1, 'objective':'multi:softprob' } 


param['nthread'] = 4 
param['eval_metric'] = 'mlogloss' 
param['lambda'] = 2 
param['num_class']=39 

evallist = [(dtrain,'train'),(dvalid,'eval')] # if there is a validation set 
# evallist = [(dtrain,'train')]     # if there is no validation set 

plst = param.items() 
plst += [('[email protected]','eval_metric')] 

num_round = 100 

bst = xgb.train(plst, dtrain, num_round, evallist,early_stopping_rounds=5) # early_stopping_rounds=10 # when there is a validation set 

# bst.res=xgb.cv(plst,dtrain,num_round,nfold = 5,evallist,early_stopping_rounds=5) 

bst.save_model('0001.model') 

# dump model 
bst.dump_model('dump.raw.txt') 
# dump model with feature map 
# bst.dump_model('dump.raw.txt','featmap.txt') 

x = datetime.datetime.now() - startTime 
print(x) 

но если я изменить линию

bst = xgb.train(plst, dtrain, num_round, evallist,early_stopping_rounds=5) 

этим одним

bst.res=xgb.cv(plst,dtrain,num_round,nfold = 5,evallist,early_stopping_rounds=5) 

я получаю следующую неожиданную ошибку:

File "", line 45 bst.res=xgb.cv(plst,dtrain,num_round,nfold = 5,evallist,early_stopping_rounds=5) SyntaxError: non-keyword arg after keyword arg

EDIT1: я попытался изменить порядок ключевых слов, а

bst.res=xgb.cv(plst,dtrain,num_round,evallist,nfold = 5,early_stopping_rounds=5) 

и я получаю следующую ошибку

--------------------------------------------------------------------------- 
TypeError         
Traceback (most recent call last) <ipython-input-49-36177ef64bab> in <module>() 
     43 # bst = xgb.train(plst, dtrain, num_round, evallist,early_stopping_rounds=5) # early_stopping_rounds=10 # when there is a validation set 
     44 
---> 45 bst.res=xgb.cv(plst,dtrain,num_round,evallist,nfold =5 ,early_stopping_rounds=5) 
     46 
     47 bst.save_model('0001.model') 

TypeError: cv() got multiple values for keyword argument 'nfold' 

edit2 В конце концов, есть нет необходимости в cv для набора проверки. нет аргументов evals в подписи xgb.cv (в то время как она присутствует для xgb.train) поэтому я удалил его и изменил линию

bst.res=xgb.cv(params=plst,dtrain=dtrain,num_boost_round=num_round,nfold = 5,early_stopping_rounds=5) 

тогда я получаю эту ошибку

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/xgboost/training.pyc 
in cv(params, dtrain, num_boost_round, nfold, metrics, obj, feval, 
maximize, early_stopping_rounds, fpreproc, as_pandas, show_progress, 
show_stdv, seed) 
    413  best_score_i = 0 
    414  results = [] 
--> 415  cvfolds = mknfold(dtrain, nfold, params, seed, metrics, fpreproc) 
    416  for i in range(num_boost_round): 
    417   for fold in cvfolds: 
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/xgboost/training.pyc 
in mknfold(dall, nfold, param, seed, evals, fpreproc) 
    280   else: 
    281    tparam = param 
--> 282   plst = list(tparam.items()) + [('eval_metric', itm) for itm in evals] 
    283   ret.append(CVPack(dtrain, dtest, plst)) 
    284  return ret 
AttributeError: 'list' object has no attribute 'items' 
+0

Вы прочитали сообщение об ошибке? В нем точно сказано, в чем заключается ваша проблема. –

+0

, когда я смотрю учебники, он говорит, что вам просто нужно указать дополнительный параметр nfold, и все будет хорошо. –

+0

Сообщение об ошибке *, которое вы отправили, уже отвечает на вопрос. 'non-keyword arg после ключевого слова arg'. 'arg' не подходит для' argument'. Если вы не знаете разницы между ключевым словом и аргументом без ключевого слова, документация на python чрезвычайно полезна. –

ответ

3

Вот подпись xgboost.cv, скопирована из документации

xgboost.cv(params, dtrain, num_boost_round=10, nfold=3, stratified=False, folds=None, metrics=(), obj=None, feval=None, maximize=False, early_stopping_rounds=None, fpreproc=None, as_pandas=True, verbose_eval=None, show_stdv=True, seed=0, callbacks=None)

Обратите внимание, что существует е xactly строго позиционные параметры, а параметр в четвертой позиции - nfold.

Ваш звонок

xgb.cv(plst, dtrain, num_round, evallist, nfold=5, early_stopping_rounds=5) 

Когда питон разбирает вызов функции, то первые матчи все аргументы, которые вы прошли позиционно положением. Так что в вашем случае, питон матчи как этого

Formal Parameter <-- What You Passed In 
      params <-- plst 
      dtrain <-- dtrain 
num_boost_round <-- num_round 
      nfold <-- evallist 

Тогда питон соответствует всем аргументам, вы прошли в качестве ключевых слов по имени.Так что в вашем случае, питон матчи как этот

Formal Parameter <-- What You Passed In 
      nfold <-- 5 
      early_stopping_rounds <-- 5 

Таким образом, вы можете видеть, что формальный параметр nfold получает дважды назначается, что и порождает этот

TypeError: cv() got multiple values for keyword argument 'nfold' 

Вероятно, самым простым и ясным исправить это pass все ваши аргументы как ключевые слова. Как правило, лучше всего ограничить свои позиционные аргументы очень маленьким числом, большинство программистов, похоже, стремятся к двум позиционным параметрам, самое большее.

but im getting another error, i can't figure it out alas

Похоже, вы передаете список, в котором ожидается словарь. Повторное использование документов, первый аргумент

params (dict) – Booster params.

Должен быть словарь.

+0

спасибо. python немного раздражает меня. мне больше нравится F #, где все напечатано и имеет полную подпись. у меня было много неприятностей, передающих неправильный объект как arg (например, файловый кадр pandas вместо массива numpy, ... и более сложные примеры) –

+0

Python просто хочет, чтобы вы были действительно явным, а когда что-то не так, вызывают тревогу, чем молча, возможно, что-то не так. –

+0

Между вами и мной, хотя я большой фанат python, я также предпочитаю статическую типизацию. Особенно при поддержке сильной функциональной системы. –

Смежные вопросы