Как сохранить собственноручно написанную модель XGBoost?
Нужно написать класс XGBoost и сохранить обученную модель в файл:
class XGBoost():
def __init__(self, n_estimators=100, learning_rate=0.2, max_depth=3, random_state=17, n_samples = 15, min_size = 5):
self.n_estimators = n_estimators
self.max_depth = max_depth
self.learning_rate = learning_rate
self.initialization = lambda y: np.mean(y) * np.ones([y.shape[0]])
self.min_size = min_size
self.loss_by_iter = []
self.trees_ = []
self.loss_by_iter_test = []
self.n_samples = n_samples
self.add_to_max_depth = 1
self.init_mse_board = 1.5
def fit(self, X, y):
self.X = X
self.y = y
b = self.initialization(y)
prediction = b.copy()
for t in tqdm_notebook(range(self.n_estimators)):
if t == 0:
resid = y
else:
resid = (y - prediction)
if (mse(temp_resid,resid) < self.init_mse_board):
self.init_mse_board /= 1.5
self.add_to_max_depth += 1
self.learning_rate /= 1.1
tree = Bagging(max_depth=self.max_depth+self.add_to_max_depth,
min_size = self.min_size)
resid = -resid
tree.fit(X, resid)
b = tree.predict(X).reshape([X.shape[0]])
self.trees_.append(tree)
prediction += self.learning_rate * b
temp_resid = resid
return self
def predict(self, X):
pred = np.ones([X.shape[0]]) * np.mean(self.y)
for t in range(self.n_estimators):
pred += self.learning_rate * self.trees_[t].predict(X).reshape([X.shape[0]])
return (pred>0.5).astype('int')
def predict_proba(self, X):
pred = np.ones([X.shape[0]]) * np.mean(self.y)
for t in range(self.n_estimators):
pred += self.learning_rate * self.trees_[t].predict(X).reshape([X.shape[0]])
pred = [[1-i, i] for i in pred]
return np.array(pred)
def __getstate__(self) -> dict:
state = {}
state['y'] = self.y
state['n_estimators'] = self.n_estimators
state['learning_rate'] = self.learning_rate
state['max_depth'] = self.max_depth
state['random_state'] = 17
state['n_samples'] = self.n_samples
state['min_size'] = self.min_size
state['trees_'] = self.trees_
state['initialization'] = self.initialization
state['loss_by_iter'] = self.loss_by_iter
state['loss_by_iter_test'] = self.loss_by_iter_test
return state
def __setstate__(self, state: dict):
self.y = state['y']
self.n_estimators = state['n_estimators']
self.learning_rate = state['learning_rate']
self.max_depth = state['max_depth']
self.random_state = state['random_state']
self.n_samples = state['n_samples']
self.min_size = state['min_size']
self.trees_ = state['trees_']
self.initialization = state['initialization']
self.loss_by_iter = state['loss_by_iter']
self.loss_by_iter_test = state['loss_by_iter_test']
Обучаю и сохраняю модель через pickle:
dataset = numpy.loadtxt('pima-indians-diabetes.csv', delimiter=",")
X = dataset[:,0:8]
Y = dataset[:,8]
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = XGBoost()
model.fit(X_train, y_train)
with open('model.pkl','wb') as f:
pickle.dump(model,f)
Выдает ошибку:
AttributeError: Can't pickle local object 'XGBoost.__init__.<locals>.<lambda>'
В ЧЕМ проблема может кто объяснить?
Ответы (2 шт):
Автор решения: CrazyElf
→ Ссылка
AttributeError: Can't pickle local object 'XGBoost.__init__.<locals>.<lambda>'
Ну, судя по всему, ругается на эту строчку в __init__:
self.initialization = lambda y: np.mean(y) * np.ones([y.shape[0]])
Опишите обычную функцию в классе, вычисляющую это всё, вам ведь не принципиальна lambda здесь? Можете даже и с lambda, но отдельно от инициализации класса чтобы это было. pickle не понимает, как потом инициализировать объект, у которого в __init__ есть lambda.
Автор решения: Max Pyankov
→ Ссылка
Нашел еще решение: Вместо модуля pickle можно использовать dill, он не ругается на лямбда функции
with open('model.pkl','wb') as f:
dill.dump(model,f)