赞
踩
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")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。