У меня есть XGBoostClassifier о повреждениях, которые классифицируются как простые случаи и сложные случаи, и я хочу оптимизировать его с точки зрения затрат, но прежде чем разделить на категории разных размеров.Поскольку классификатор неправильно классифицирует некоторые случаи, я хочу, чтобы hyperopt оптимизировал эти категории размеров.Поэтому, если ущерб более дорогостоящий, ему будет сложнее классифицировать его как простой случай.По некоторым причинам hyperopt не работает лучше после каждой категории размеров.
rstate = np.random.RandomState(7)
CM = []
paramst = {'colsample_bytree': 0.9697677752045393, 'gamma': 2,
'learning_rate': 0.08597574025592336, 'max_depth': 14,
'n_estimators': 29, 'subsample': 0.900027377690923}
model = XGBClassifier(**paramst, random_state = 7)
model.fit(X_train, y_train)
probab = model.predict_proba(X_valid)
prob = np.array(probab[:,0])
y_pred_pre = model.predict(X_valid)
cost = X_valid['cost']
cost = np.array(cost)
ClassK = [100,200,300,400,500,600,700,800,900,901]
PercentK = 0.1
def treshold(params):
def classification(x, y):
class1 = [None]*len(y)
for idx, i in enumerate(y):
l = True
if (x[idx] < ClassK[0]):
if (params['100'] > i):
l = False
elif (x[idx] < ClassK[1]) and (x[idx] > ClassK[0]):
if (params['200'] > i):
l = False
elif (x[idx] < ClassK[2]) and (x[idx] > ClassK[1]):
if (params['300'] > i):
l = False
elif (x[idx] < ClassK[3]) and (x[idx] > ClassK[2]):
if (params['400'] > i):
l = False
elif (x[idx] < ClassK[4]) and (x[idx] > ClassK[3]):
if (params['500'] > i):
l = False
elif (x[idx] < ClassK[5]) and (x[idx] > ClassK[4]):
if (params['600'] > i):
l = False
elif (x[idx] < ClassK[6]) and (x[idx] > ClassK[5]):
if (params['700'] > i):
l = False
elif (x[idx] < ClassK[7]) and (x[idx] > ClassK[6]):
if (params['800'] > i):
l = False
elif (x[idx] < ClassK[8]) and (x[idx] > ClassK[7]):
if (params['900'] > i):
l = False
elif (x[idx] >= ClassK[9]):
if (params['901'] > i):
l = False
class1[idx] = l
return class1
cl = classification(x=cost, y= prob)
def cmsumfunction(cl):
CM = []
for i in range(len(y_valid)):
if not y_valid[i] and not cl[i]:
CM.append(0)
elif not y_valid[i] and cl[i]:
CM.append(1)
elif y_valid[i] and not cl[i]:
CM.append(2)
elif y_valid[i] and cl[i]:
CM.append(3)
X_valid.loc[:,'CM'] = CM
cmsum = X_valid.groupby('CM')['cost'].sum()
X_valid.drop('CM', axis = 1, errors = 'ignore', inplace = True)
return cmsum, CM
def costfunc(cl):
cmsum, CM = cmsumfunction(cl)
a = 0
try:
a = cmsum[1]*PercentK
except:
print('Error')
b = CM.count(3)*10+CM.count(1)*10
return a-b
return {'loss': costfunc(cl), 'status': 'ok', 'class': cl, 'Parameter': params}
def optimize (random_state = 7):
resultlist = []
trialslist = []
for i in space:
space_copy = space1.copy()
space_copy[i] = space[i]
global trials
trials = Trials()
best = fmin(treshold, space_copy, algo=tpe.suggest, max_evals = 100, trials = trials)
resultlist.append(best)
trialslist.append(trials)
return(resultlist, trialslist)
result_hyper = []
result, thresholds = optimize()
result_hyper.append(result)
Вывод:
100%|█████████████████████████████████████████████████| 100/100 [00:12<00:00, 7.24it/s, best loss: 117349.50499999977]
100%|██████████████████████████████████████████████████| 100/100 [00:14<00:00, 7.85it/s, best loss: 112980.0749999994]
100%|██████████████████████████████████████████████████| 100/100 [00:12<00:00, 8.36it/s, best loss: 98664.08699999997]
100%|██████████████████████████████████████████████████| 100/100 [00:13<00:00, 7.32it/s, best loss: 96265.73999999941]
100%|█████████████████████████████████████████████████| 100/100 [00:13<00:00, 7.36it/s, best loss: 101592.99399999916]
100%|██████████████████████████████████████████████████| 100/100 [00:13<00:00, 6.67it/s, best loss: 105445.9679999993]
100%|█████████████████████████████████████████████████| 100/100 [00:16<00:00, 6.03it/s, best loss: 105469.19599999941]
100%|█████████████████████████████████████████████████| 100/100 [00:15<00:00, 6.87it/s, best loss: 109068.51899999939]
100%|██████████████████████████████████████████████████| 100/100 [00:13<00:00, 7.63it/s, best loss: 110204.6389999995]
100%|██████████████████████████████████████████████████| 100/100 [00:12<00:00, 7.75it/s, best loss: 99880.33999999936]
result_hyper Результат в этом:
[[{'100': 0.02},
{'200': 0.98},
{'300': 1.0},
{'400': 0.97},
{'500': 0.98},
{'600': 0.97},
{'700': 0.96},
{'800': 0.99},
{'900': 0.98},
{'901': 0.99}]]
Я быложидая найти лучшее решение для самой высокой отрицательной стоимости (прибыли).Например, если я устанавливаю a = 1 и меняю класс от 100 до 0,8, я получаю отрицательные результаты.Прежде чем я сам начну его оптимизировать, есть ли какое-то решение, почему Hyperopt не дает хорошего результата?Спасибо за любую помощь, ребята.