当前位置:   article > 正文

一个GPU版本的遗传算法迭代xgboost最优参数的示例,这里用的是自定义损失函数_遗传算法gpu

遗传算法gpu

一个简单的遗传算法迭代xgboost最优参数的示例,这里用的是自定义损失函数

import pandas as pd
import numpy as np
import xgboost as xgb
from sko.GA import GA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn import metrics
from log_color import log,LogLevel
from tqdm import tqdm
# from matplotlib import pyplot as plt

train_df = pd.read_csv('./train_v2.csv')
test_df =pd.read_csv('./test_v2.csv')

x = train_df.drop(['user_id','merchant_id','label'],axis=1)
y = train_df['label']

# ## 混合打乱数据
# y_to_numpy = y.to_numpy()
# x_to_numpy = x.to_numpy()
# m,n = x_to_numpy.shape
# y_to_numpy = y_to_numpy.reshape((m,1))
# xy = np.c_[x_to_numpy,y_to_numpy]

# for i in tqdm(range(20),desc="随机打乱数据"):
#     np.random.shuffle(xy)

# x,y = xy[:,0:13],xy[:,13:14]

# log(f"x.shape:{x.shape},y.shape:{y.shape}",LogLevel.INFO)

x_train, x_val, y_train, y_val = train_test_split(x, y, test_size=0.2, random_state = 42)

gamma = 0
### 自动计算alpha值的取值范围 取负例的比例
train_Y = y_train 

alpha = (train_Y==0).sum()/train_Y.size

def logistic_obj(p, dtrain):
   y = dtrain.get_label()
   p = 1.0 / (1.0 + np.exp(-p))
   grad = p * (1 - p) * (alpha * gamma * y * (1 - p) ** gamma * np.log(p) / (1 - p) - alpha * y * (
               1 - p) ** gamma / p - gamma * p ** gamma * (1 - alpha) * (1 - y) * np.log(1 - p) / p + p ** gamma * (
                                     1 - alpha) * (1 - y) / (1 - p))
   hess = p * (1 - p) * (p * (1 - p) * (
               -alpha * gamma ** 2 * y * (1 - p) ** gamma * np.log(p) / (1 - p) ** 2 + alpha * gamma * y * (
                   1 - p) ** gamma * np.log(p) / (1 - p) ** 2 + 2 * alpha * gamma * y * (1 - p) ** gamma / (
                           p * (1 - p)) + alpha * y * (1 - p) ** gamma / p ** 2 - gamma ** 2 * p ** gamma * (
                           1 - alpha) * (1 - y) * np.log(1 - p) / p ** 2 + 2 * gamma * p ** gamma * (1 - alpha) * (
                           1 - y) / (p * (1 - p)) + gamma * p ** gamma * (1 - alpha) * (1 - y) * np.log(
           1 - p) / p ** 2 + p ** gamma * (1 - alpha) * (1 - y) / (1 - p) ** 2) - p * (
                                     alpha * gamma * y * (1 - p) ** gamma * np.log(p) / (1 - p) - alpha * y * (
                                         1 - p) ** gamma / p - gamma * p ** gamma * (1 - alpha) * (1 - y) * np.log(
                                 1 - p) / p + p ** gamma * (1 - alpha) * (1 - y) / (1 - p)) + (1 - p) * (
                                     alpha * gamma * y * (1 - p) ** gamma * np.log(p) / (1 - p) - alpha * y * (
                                         1 - p) ** gamma / p - gamma * p ** gamma * (1 - alpha) * (1 - y) * np.log(
                                 1 - p) / p + p ** gamma * (1 - alpha) * (1 - y) / (1 - p)))
   return grad, hess

# class Myobj(xgb.core.):
#     def __call__(self,preds,label):
#         grad,hess = logistic_obj(preds,label)
#         return grad,hess
   
#     def create_obj(self):
#         return self

def XGBoostAUC(p):
   etas = [0.0001,0.001,0.01,0.1]
   sampling_methods = ["uniform","gradient_based"]
   # tree_methods = ["auto","exact","approx","hist"]
   w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17 = p
   params = { #"objective":Myobj()
               "learning_rate":w1 #0.1
              , "n_estimators":int(w2)#11 #即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越 大,模型的效果往往越好。但是相应的,任何模型都有决策边  n_estimators达到一定的程度之后,随机森林的 精确性往往不在上升或开始波动,并且,n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越 长。对于这个参数,我们是渴望在训练难度和模型效果之间取得平衡。
              , "max_depth":int(w3) #构建树的深度,越大越容易过拟合
              , "min_child_weight":w4 #0.8 #越大min_child_weight,算法越保守。范围:[0,无穷大] 孩子节点中最小的样本权重和。如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束
#                , "num_class ":1#类别数,与 multisoftmax 并用
               , "gamma":w5 #损失下降多少才进行分裂, 控制叶子节点的个数
              , "subsample":w6#0.8 #随机采样训练样本
              #, "colsample_bytree":1 #生成树时进行的列采样
#                , "objective":'binary:logistic' # {'binary:logistic'}是二分类的问题,{'multi:softmax',}是多分类的问题 这个是优化目标,必须得有,因为xgboost里面有求一阶导数和二阶导数,其实就是这个。
              , "nthread":5 #cpu 线程数
              , "scale_pos_weight":(train_Y==0).sum()/(train_Y==1).sum() #负样本总数/正样本总数 。若训练负样本总数是500 ,正样本总数100,那么设置 scale_pos_weigh为 5
              , "lambda":w7#2 # 正则化参数
              , "eta":etas[int(w8)] #0.001 # 如同学习率
               , "verbosity":1 # 打印消息的详细程度。有效值为 0(静默)、1(警告)、2(信息)、3(调试)。
#                , metrics='auc'
              , "eval_metric":"auc"
#                , "silent ": 0 # ,设置成1则没有运行信息输出,最好是设置为0.
              , "seed":int(w9)
              , "max_delta_step":w10 #范围:[0,无穷大] ,我们允许每个叶子输出的最大增量步长。如果该值设置为0,则表示没有约束。如果将其设置为正值,则可以帮助使更新步骤更加保守。通常不需要此参数,但当类别极度不平衡时,它可能有助于逻辑回归。将其设置为 1-10 的值可能有助于控制更新。
               ,"subsample":w11
               ,"sampling_method":sampling_methods[int(w12)]
               ,'colsample_bytree':w13
               , 'colsample_bylevel':w14
               , 'colsample_bynode':w15
               ,"gpu_id":0 # 使用GPU的参数1
               ,"tree_method":"gpu_hist"#tree_methods[int(w16)]# #使用GPU的参数2
               ,"max_leaves":int(w16) #要添加的最大节点数。不被树方法使用
               ,"num_parallel_tree":int(w17) #每次迭代期间构建的并行树的数量。此选项用于支持增强随机森林
       }
   dtrain = xgb.DMatrix(x_train,label=y_train)
   clf = xgb.train(params=params
                   ,dtrain=dtrain
                   ,num_boost_round=100
                   ,evals=[(dtrain,"train")]
                   ,verbose_eval=False # 不显示训练信息就改False
                   ,obj=logistic_obj
                   )
   dtest = xgb.DMatrix(x_val,label=y_val)
   lr_proba = clf.predict(dtest)
   lr_proba = np.nan_to_num(lr_proba,0)
   fpr,tpr,threshold = metrics.roc_curve(y_val, lr_proba)
   roc_auc = metrics.auc(fpr,tpr)
   dtrain=None
   clf = None
   dtest = None
   lr_proba = None
   fpr,tpr,threshold = None,None,None
   log(f"本次迭代AUC分数为:[{roc_auc}],本次X值为:[{p}]",LogLevel.PASS)

   return -roc_auc


ga = GA(func=XGBoostAUC
       , n_dim=17 #待求解的自变量数量
       , size_pop=10 #种群初始化个体数量 
       , max_iter=5 # 进化迭代次数
       , prob_mut=0.01 #变异概率
       , lb=[0.1,5,1,0,0,0,0,0,10,0,0,0,0,0,0,0,1] # 自变量下限
       ,ub=[1,20,20,100,1,1,100,3,100,10,1,1,1,1,1,10,10] # 自变量上限
       ,precision=[0.1,1,1,0.1,0.1,0.1,0.1,1,1,0.1,0.1,1,0.1,0.1,0.1,1,1] #精度
       #,early_stop = True # 当出现两个相同值时是否早停退出
      )
best_x,best_y = ga.run()
print('best_x:', best_x,'\n','best_y:',best_y)


opt_x_log = pd.DataFrame({
   "best_x":[best_x]
   ,"best_y":[best_y]
})
print(f"优化结果表:{opt_x_log}")
opt_x_log.to_csv("best_x2.csv")


### 保存参数表
w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17 = best_x

etas = [0.0001,0.001,0.01,0.1]
sampling_methods = ["uniform","gradient_based"]
params = { #"objective":Myobj()
               "learning_rate":w1 #0.1
              , "n_estimators":int(w2)#11 #即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越 大,模型的效果往往越好。但是相应的,任何模型都有决策边  n_estimators达到一定的程度之后,随机森林的 精确性往往不在上升或开始波动,并且,n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越 长。对于这个参数,我们是渴望在训练难度和模型效果之间取得平衡。
              , "max_depth":int(w3) #构建树的深度,越大越容易过拟合
              , "min_child_weight":w4 #0.8 #越大min_child_weight,算法越保守。范围:[0,无穷大] 孩子节点中最小的样本权重和。如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束
               
#               
#                , "num_class ":1#类别数,与 multisoftmax 并用
               , "gamma":w5 #损失下降多少才进行分裂, 控制叶子节点的个数
              , "subsample":w6#0.8 #随机采样训练样本
              #, "colsample_bytree":1 #生成树时进行的列采样
#                , "objective":'binary:logistic' # {'binary:logistic'}是二分类的问题,{'multi:softmax',}是多分类的问题 这个是优化目标,必须得有,因为xgboost里面有求一阶导数和二阶导数,其实就是这个。
              , "nthread":5 #cpu 线程数
              , "scale_pos_weight":(train_Y==0).sum()/(train_Y==1).sum() #负样本总数/正样本总数 。若训练负样本总数是500 ,正样本总数100,那么设置 scale_pos_weigh为 5
              , "lambda":w7#2 # 正则化参数
              , "eta":etas[int(w8)] #0.001 # 如同学习率
               , "verbosity":1 # 打印消息的详细程度。有效值为 0(静默)、1(警告)、2(信息)、3(调试)。
#                , metrics='auc'
              , "eval_metric":"auc"
#                , "silent ": 0 # ,设置成1则没有运行信息输出,最好是设置为0.
              , "seed":int(w9)
              , "max_delta_step":w10 #范围:[0,无穷大] ,我们允许每个叶子输出的最大增量步长。如果该值设置为0,则表示没有约束。如果将其设置为正值,则可以帮助使更新步骤更加保守。通常不需要此参数,但当类别极度不平衡时,它可能有助于逻辑回归。将其设置为 1-10 的值可能有助于控制更新。
               ,"subsample":w11
               ,"sampling_method":sampling_methods[int(w12)]
               ,'colsample_bytree':w13
               , 'colsample_bylevel':w14
               , 'colsample_bynode':w15
               ,"gpu_id":0 # 使用GPU的参数1
               ,"tree_method":"gpu_hist"#tree_methods[int(w16)]# #使用GPU的参数2
               ,"max_leaves":int(w16) #要添加的最大节点数。不被树方法使用
               ,"num_parallel_tree":int(w17) #每次迭代期间构建的并行树的数量。此选项用于支持增强随机森林


       }
params.update({"best_auc":best_y})
best_params_table = pd.DataFrame({k:[v] for k,v in params.items()})
best_params_table.to_csv("best_params_table.csv")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/430517
推荐阅读
相关标签
  

闽ICP备14008679号