-
-
Save sheecegardezi/8cef8a881dc90055bf4bf370df7552ea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class XGBQuantile(XGBRegressor): | |
def __init__(self,quant_alpha=0.95,quant_delta = 1.0,quant_thres=1.0,quant_var =1.0,base_score=0.5, booster='gbtree', colsample_bylevel=1, | |
colsample_bytree=1, gamma=0, learning_rate=0.1, max_delta_step=0,max_depth=3, min_child_weight=1, missing=None, n_estimators=100, | |
n_jobs=1, nthread=None, objective='reg:linear', random_state=0,reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,silent=True, subsample=1): | |
self.quant_alpha = quant_alpha | |
self.quant_delta = quant_delta | |
self.quant_thres = quant_thres | |
self.quant_var = quant_var | |
super().__init__(base_score=base_score, booster=booster, colsample_bylevel=colsample_bylevel, | |
colsample_bytree=colsample_bytree, gamma=gamma, learning_rate=learning_rate, max_delta_step=max_delta_step, | |
max_depth=max_depth, min_child_weight=min_child_weight, missing=missing, n_estimators=n_estimators, | |
n_jobs= n_jobs, nthread=nthread, objective=objective, random_state=random_state, | |
reg_alpha=reg_alpha, reg_lambda=reg_lambda, scale_pos_weight=scale_pos_weight, seed=seed, | |
silent=silent, subsample=subsample) | |
self.test = None | |
def fit(self, X, y): | |
super().set_params(objective=partial(XGBQuantile.quantile_loss,alpha = self.quant_alpha,delta = self.quant_delta,threshold = self.quant_thres,var = self.quant_var) ) | |
super().fit(X,y) | |
return self | |
def predict(self,X): | |
return super().predict(X) | |
def score(self, X, y): | |
y_pred = super().predict(X) | |
score = XGBQuantile.quantile_score(y, y_pred, self.quant_alpha) | |
score = 1./score | |
return score | |
@staticmethod | |
def quantile_loss(y_true,y_pred,alpha,delta,threshold,var): | |
x = y_true - y_pred | |
grad = (x<(alpha-1.0)*delta)*(1.0-alpha)- ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )*x/delta-alpha*(x>alpha*delta) | |
hess = ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )/delta | |
grad = (np.abs(x)<threshold )*grad - (np.abs(x)>=threshold )*(2*np.random.randint(2, size=len(y_true)) -1.0)*var | |
hess = (np.abs(x)<threshold )*hess + (np.abs(x)>=threshold ) | |
return grad, hess | |
@staticmethod | |
def original_quantile_loss(y_true,y_pred,alpha,delta): | |
x = y_true - y_pred | |
grad = (x<(alpha-1.0)*delta)*(1.0-alpha)-((x>=(alpha-1.0)*delta)& (x<alpha*delta) )*x/delta-alpha*(x>alpha*delta) | |
hess = ((x>=(alpha-1.0)*delta)& (x<alpha*delta) )/delta | |
return grad,hess | |
@staticmethod | |
def quantile_score(y_true, y_pred, alpha): | |
score = XGBQuantile.quantile_cost(x=y_true-y_pred,alpha=alpha) | |
score = np.sum(score) | |
return score | |
@staticmethod | |
def quantile_cost(x, alpha): | |
return (alpha-1.0)*x*(x<0)+alpha*x*(x>=0) | |
@staticmethod | |
def get_split_gain(gradient,hessian,l=1): | |
split_gain = list() | |
for i in range(gradient.shape[0]): | |
split_gain.append(np.sum(gradient[:i])/(np.sum(hessian[:i])+l)+np.sum(gradient[i:])/(np.sum(hessian[i:])+l)-np.sum(gradient)/(np.sum(hessian)+l) ) | |
return np.array(split_gain) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment