XGBoost中参数调整的完整指南(包含Python中的代码)
(搬运)XGBoost中参数调整的完整指南(包含Python中的代码)
介绍
如果事情不适合预测建模,请使用XGboost。XGBoost算法已成为许多数据科学家的终极武器。它是一种高度复杂的算法,功能强大,足以处理各种不规则的数据。
使用XGBoost构建模型很容易。但是,使用XGBoost改进模型很困难(至少我很挣扎)。该算法使用多个参数。要改进模型,必须进行参数调整。很难得到像实际问题的答案 - 你应该调整哪一组参数?获得最佳输出的这些参数的理想值是多少?
本文最适合XGBoost新手。在本文中,我们将学习参数调整的技巧以及有关XGBoost的一些有用信息。此外,我们将使用Python中的数据集来练习此算法。

你应该知道什么?
XGBoost(eXtreme Gradient Boosting)是梯度增强算法的高级实现。由于我在上一篇文章 - Gradient Boosting中的参数调整完整指南(GBM)中详细介绍了Gradient Boosting Machine ,我强烈建议在进一步阅读之前先仔细阅读。它将帮助您加强对GBM的增强和参数调整的理解。
特别感谢:就个人而言,我要感谢Sudalai Rajkumar先生 (又名SRK)提供的永恒支持,目前是 AV等级2。没有他的帮助,这篇文章是不可能的。他正在帮助我们指导数千名数据科学家。非常感谢SRK!
目录
- XGBoost优势
- 了解XGBoost参数
- 调整参数(带示例)
1. XGBoost优势
我一直很钦佩这种算法在预测模型中注入的增强功能。当我在高精度下探索更多有关其性能和科学的知识时,我发现了许多优点:
- 正则:
- 标准GBM实现没有像XGBoost那样的正则化,因此它也有助于减少过度拟合。
- 实际上,XGBoost也被称为“ 正则化增强 ”技术。
- 并行处理:
- 高灵活性
- XGBoost允许用户定义自定义优化目标和评估标准。
- 这为模型增加了一个全新的维度,我们可以做的事情没有限制。
- 处理缺失值
- XGBoost有一个内置的例程来处理缺失值。
- 用户需要提供与其他观察值不同的值,并将其作为参数传递。XGBoost会尝试不同的事情,因为它在每个节点上遇到缺失值,并了解将来丢失值的路径。
- 树修剪:
- 当GBM在分割中遇到负损失时,它将停止分割节点。因此,它更像是一种贪婪的算法。
- 另一方面,XGBoost分割到指定的max_depth,然后开始向后修剪树并删除没有正增益的分裂。
- 另一个优点是,有时负损失的分裂表示-2后可能会出现正损失+10的分裂。GBM会在遇到-2时停止。但是XGBoost会更深入,它会看到分裂的+8和两者的综合效果。
- 内置交叉验证
- XGBoost允许用户在每次增强过程的迭代中运行交叉验证,因此很容易在一次运行中获得精确的最佳增强迭代次数。
- 这与GBM不同,我们必须运行网格搜索,并且只能测试有限的值。
- 继续使用现有模型
- 用户可以从上一次运行的最后一次迭代开始训练XGBoost模型。这在某些特定应用中具有显着优势。
- sklearn的GBM实现也具有此功能,因此它们甚至在这一点上。
我希望你现在能理解XGBoost算法的强大功能。请注意,这些是我可以集合的要点。你知道更多吗?随意在下面发表评论,我会更新列表。
我有胃口吗?好。您可以参考以下网页以获得更深入的了解:
2. XGBoost参数
XGBoost作者将整体参数分为3类:
- 一般参数: 指导整体功能
- 助推器参数: 在每个步骤指导个体助推器(树/回归)
- 学习任务参数: 指导执行的优化
我将在这里对GBM进行类比,并强烈建议阅读本文 以从基础知识中学习。
一般参数
这些定义了XGBoost的整体功能。
- 助推器[默认= gbtree]
- 选择要在每次迭代时运行的模型类型。它有2个选项:
- gbtree:基于树的模型
- gblinear:线性模型
- 选择要在每次迭代时运行的模型类型。它有2个选项:
- 无声[default = 0]:
- 静音模式激活设置为1,即不会打印正在运行的消息。
- 保持0通常是好的,因为消息可能有助于理解模型。
- nthread [默认为未设置的最大线程数]
- 这用于并行处理,应输入系统中的核心数
- 如果您希望在所有核心上运行,则不应输入值,并且算法将自动检测
还有2个参数由XGBoost自动设置,您无需担心它们。让我们转到Booster参数。
助推器参数
虽然有两种类型的助推器,但我 在这里只考虑 树助推器,因为它总是优于线性助力器,因此后者很少使用。
- eta [默认= 0.3]
- 类似于GBM中的学习率
- 通过缩小每一步的权重,使模型更加健壮
- 使用的典型最终值:0.01-0.2
- min_child_weight [default = 1]
- 定义儿童所需观察的最小权重总和。
- 这类似于GBM中的min_child_leaf,但并不完全相同。这指的是观察的最小“权重总和”,而GBM具有最小“观察数”。
- 用于控制过度拟合。较高的值会阻止模型学习关系,这种关系可能对为树选择的特定样本高度特定。
- 太高的值会导致欠拟合,因此应使用CV进行调整。
- max_depth [default = 6]
- 树的最大深度,与GBM相同。
- 用于控制过度拟合,因为更高的深度将允许模型学习非常特定于特定样本的关系。
- 应该使用CV进行调整。
- 典型值:3-10
- max_leaf_nodes
- 树中终端节点或叶子的最大数量。
- 可以定义代替max_depth。由于创建了二叉树,因此深度'n'将产生最多2 ^ n个叶子。
- 如果已定义,则GBM将忽略max_depth。
- gamma [default = 0]
- 仅当结果分割给出损失函数的正减少时,才会分割节点。Gamma指定进行拆分所需的最小损失减少量。
- 使算法保守。值可能会根据损耗函数而有所不同,因此应进行调整。
- max_delta_step [default = 0]
- 在最大增量步长中,我们允许每棵树的权重估计。如果该值设置为0,则表示没有约束。如果将其设置为正值,则可以帮助使更新步骤更加保守。
- 通常不需要此参数,但当类非常不平衡时,它可能有助于逻辑回归。
- 这通常不使用,但如果您愿意,可以进一步探索。
- 子样本[default = 1]
- 与GBM的子样本相同。表示观察的比例是每棵树的随机样本。
- 较低的值使算法更加保守并防止过度拟合,但是太小的值可能导致不合适。
- 典型值:0.5-1
- colsample_bytree [default = 1]
- 与GBM中的max_features类似。表示每个树的随机样本列的分数。
- 典型值:0.5-1
- colsample_bylevel [default = 1]
- 表示每个级别中每个拆分的列的子采样率。
- 我不经常使用它,因为subsample和colsample_bytree将为您完成这项工作。但如果你有这种感觉,你可以进一步探索。
- lambda [default = 1]
- 关于权重的L2正则项(类似于岭回归)
- 这用于处理XGBoost的正则化部分。虽然许多数据科学家不经常使用它,但应该探索减少过度拟合。
- alpha [默认= 0]
- 关于权重的L1正则化项(类似于Lasso回归)
- 可以在非常高的维度的情况下使用,以便算法在实现时运行得更快
- scale_pos_weight [default = 1]
- 在高级别不平衡的情况下,应使用大于0的值,因为它有助于更快收敛。
学习任务参数
这些参数用于定义要在每个步骤计算的度量的优化目标。
- 客观[default = reg:linear]
- 这定义了要最小化的损失函数。最常用的值是:
- binary:logistic -logistic回归用于二进制分类,返回预测概率(不是类)
- multi:使用softmax目标的softmax -multiclass分类,返回预测类(不是概率)
- 您还需要设置一个额外的 num_class (类数)参数,用于定义唯一类的数量
- multi:softprob -same as softmax,但返回属于每个类的每个数据点的预测概率。
- 这定义了要最小化的损失函数。最常用的值是:
- eval_metric [默认根据目标]
- 用于验证数据的度量标准。
- 回归的默认值为rmse,分类的误差为rmse。
- 典型值为:
- rmse - 均方根误差
- mae - 平均绝对误差
- logloss - 负对数似然
- 错误 - 二进制分类错误率(0.5阈值)
- merror - 多类分类错误率
- mlogloss - 多类logloss
- auc: 曲线下面积
- 种子[默认= 0]
- 随机数种子。
- 可用于生成可重现的结果,也可用于参数调整。
如果您到目前为止一直在使用Scikit-Learn,那么这些参数名称可能看起来并不熟悉。一个好消息是python中的xgboost模块有一个名为XGBClassifier的sklearn包装器。它使用sklearn样式命名约定。将更改的参数名称为:
- eta - > learning_rate
- lambda - > reg_lambda
- alpha - > reg_alpha
您必须想知道我们已经定义了除GBM中“n_estimators”参数之外的所有内容。那么它作为XGBClassifier中的参数存在。但是,在标准xgboost实现中调用fit函数时,必须将其作为“num_boosting_rounds”传递。
我建议您阅读xgboost指南的以下部分,以便更好地理解参数和代码:
3.使用示例进行参数调整
我们将从Data Hackathon 3.x AV黑客马拉松中获取数据集,与GBM文章中的相同。问题的详细信息可以在竞赛页面上找到。您可以从此处下载数据集。我执行了以下步骤:
- 城市变量因类别太多而下降
- DOB转换为Age | DOB掉线了
- EMI_Loan_Submitted_Missing已创建,如果EMI_Loan_Submitted缺失则为1,否则为0 | 原始变量EMI_Loan_Submitted掉线
- 由于类别太多,EmployerName被删除
- Existing_EMI估算为0(中位数),因为只有111个值丢失
- Interest_Rate_Missing创建,如果Interest_Rate丢失则为1,否则为0 | 原始变量Interest_Rate下降
- Lead_Creation_Date被删除,因为对结果的影响很小
- Loan_Amount_Applied,Loan_Tenure_Applied用中值估算
- 已创建Loan_Amount_Submitted_Missing,如果Loan_Amount_Submitted缺失则为1,否则为0 原始变量Loan_Amount_Submitted丢弃
- 已创建Loan_Tenure_Submitted_Missing,如果Loan_Tenure_Submitted缺失则为1,否则为0 原始变量Loan_Tenure_Submitted丢弃
- LoggedIn,Salary_Account下降了
- 如果Processing_Fee丢失,则创建Processing_Fee_Missing为1,否则为0 | 原始变量Processing_Fee掉线
- 来源 - 前2名保持不变,所有其他人合并为不同类别
- 执行数字和单热编码
对于那些从竞争中获得原始数据的人,您可以从存储库中的data_preparation iPython笔记本中查看这些步骤。
让我们从导入所需的库并加载数据开始:
#Import libraries:
import pandas as pd
import numpy as np
import xgboost as xgb
from xgboost.sklearn import XGBClassifier
from sklearn import cross_validation, metrics #Additional scklearn functions
from sklearn.grid_search import GridSearchCV #Perforing grid search import matplotlib.pylab as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 12, 4 train = pd.read_csv('train_modified.csv')
target = 'Disbursed'
IDcol = 'ID'
请注意,我已导入2种形式的XGBoost:
- xgb - 这是直接的xgboost库。我将使用此库中的特定函数“cv”
- XGBClassifier - 这是XGBoost的sklearn包装器。这使得我们可以像对待GBM一样使用sklearn的网格搜索和并行处理
在继续之前,让我们定义一个函数,它将帮助我们创建XGBoost模型并执行交叉验证。最好的部分是您可以按原样使用此功能,稍后将其用于您自己的模型。
def modelfit(alg, dtrain, predictors,useTrainCV=True, cv_folds=5, early_stopping_rounds=50):
if useTrainCV:
xgb_param = alg.get_xgb_params()
xgtrain = xgb.DMatrix(dtrain[predictors].values, label=dtrain[target].values)
cvresult = xgb.cv(xgb_param, xgtrain, num_boost_round=alg.get_params()['n_estimators'], nfold=cv_folds,
metrics='auc', early_stopping_rounds=early_stopping_rounds, show_progress=False)
alg.set_params(n_estimators=cvresult.shape[0])
#Fit the algorithm on the data
alg.fit(dtrain[predictors], dtrain['Disbursed'],eval_metric='auc')
#Predict training set:
dtrain_predictions = alg.predict(dtrain[predictors])
dtrain_predprob = alg.predict_proba(dtrain[predictors])[:,1]
#Print model report:
print "\nModel Report"
print "Accuracy : %.4g" % metrics.accuracy_score(dtrain['Disbursed'].values, dtrain_predictions)
print "AUC Score (Train): %f" % metrics.roc_auc_score(dtrain['Disbursed'], dtrain_predprob)
feat_imp = pd.Series(alg.booster().get_fscore()).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
参数调整的一般方法
我们将在这里使用类似于GBM的方法。要执行的各个步骤是:
- 选择相对较高的学习率。通常学习率为0.1,但介于0.05到0.3之间,可能适用于不同的问题。确定此学习率的最佳树木数量。XGBoost有一个非常有用的函数叫做“cv”,它在每次增强迭代时执行交叉验证,从而返回所需的最佳树数。
- 调整树特定参数 (max_depth,min_child_weight,gamma,subsample,colsample_bytree)以确定学习速率和树木数量。请注意,我们可以选择不同的参数来定义树,我将在这里举一个例子。
- 调整 xgboost的正则化参数(lambda,alpha),这有助于降低模型复杂性并提高性能。
- 降低学习率并确定最佳参数。
让我们看一个更详细的一步一步的方法。
步骤1:修复学习率和用于调整基于树的参数的估计量的数量
为了决定提升参数,我们需要设置其他参数的一些初始值。让我们采取以下价值观:
- max_depth = 5 :这应该在3-10之间。我从5开始,但你也可以选择不同的数字。4-6可以是很好的起点。
- min_child_weight = 1 :选择较小的值是因为它是一个高度不平衡的类问题,并且叶节点可以具有较小的大小组。
- gamma = 0 :也可以选择较小的值如0.1-0.2来启动。无论如何,这将在以后进行调整。
- subsample,colsample_bytree = 0.8:这是一个常用的使用起始值。典型值介于0.5-0.9之间。
- scale_pos_weight = 1:由于高级别的不平衡。
请注意,以上所有内容仅为初步估算值,稍后会进行调整。让我们在这里采用默认的学习率0.1,并使用xgboost的cv函数检查树的最佳数量。上面定义的函数将为我们完成。
#Choose all predictors except target & IDcols
predictors = [x for x in train.columns if x not in [target, IDcol]]
xgb1 = XGBClassifier(
learning_rate =0.1,
n_estimators=1000,
max_depth=5,
min_child_weight=1,
gamma=0,
subsample=0.8,
colsample_bytree=0.8,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=1,
seed=27)
modelfit(xgb1, train, predictors)

正如您所看到的,我们在这里得到140作为0.1学习率的最佳估计。请注意,根据系统的功率,此值可能太高。在这种情况下,您可以提高学习率并重新运行命令以减少估算量。
注意:您将在此处的输出中看到测试AUC为“AUC分数(测试)”。但是,如果您尝试在系统上运行该命令,则不会出现这种情况,因为数据未公开。这里提供的仅供参考。生成此输出的代码部分已在此处删除。
第2步:调整max_depth和min_child_weight
我们先调整它们,因为它们对模型结果的影响最大。首先,让我们设置更宽的范围,然后我们将为更小的范围执行另一次迭代。
重要说明:我将在本节中搜索一些重型网格,这可能需要15-30分钟甚至更长的时间才能运行,具体取决于您的系统。您可以根据系统可以处理的内容来更改要测试的值的数量。
param_test1 = {
'max_depth':range(3,10,2),
'min_child_weight':range(1,6,2)
}
gsearch1 = GridSearchCV(estimator = XGBClassifier(learning_rate = 0.1,n_estimators = 140,max_depth = 5,
min_child_weight = 1,gamma = 0,subsample = 0.8,colsample_bytree = 0.8,
objective ='binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27),
param_grid = param_test1,scoring ='roc_auc',n_jobs = 4, iid = False,cv = 5)
gsearch1.fit(train [predictors],train [target])
gsearch1.grid_scores_,gsearch1.best_params_,gsearch1.best_score_

在这里,我们运行了12种组合,值之间的间隔更宽。理想值是5 MAX_DEPTH和5 min_child_weight。让我们更进一步,寻找最佳价值。我们将搜索高于和低于最佳值的值1,因为我们间隔为2。
param_test2 = {
'max_depth':[4,5,6],
'min_child_weight':[4,5,6]
}
gsearch2 = GridSearchCV(estimator = XGBClassifier(learning_rate = 0.1,n_estimators = 140,max_depth = 5,
min_child_weight = 2) ,gamma = 0,subsample = 0.8,colsample_bytree = 0.8,
objective ='binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27),
param_grid = param_test2,scoring ='roc_auc',n_jobs = 4,iid = False,cv = 5)
gsearch2.fit(train [predictors],train [target])
gsearch2.grid_scores_,gsearch2.best_params_,gsearch2.best_score_

在这里,我们得到的最佳值是4 MAX_DEPTH和6 min_child_weight。此外,我们可以看到CV分数略有增加。请注意,随着模型性能的提高,甚至难以实现性能上的边际收益。您会注意到我们在这里得到6作为min_child_weight的最佳值,但我们没有尝试超过6的值。我们可以这样做:
param_test2b = {
'min_child_weight':[6,8,10,12]
}
gsearch2b = GridSearchCV(estimator = XGBClassifier( learning_rate=0.1, n_estimators=140, max_depth=4,
min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8,
objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27),
param_grid = param_test2b, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch2b.fit(train[predictors],train[target])
modelfit(gsearch3.best_estimator_, train, predictors)
gsearch2b.grid_scores_, gsearch2b.best_params_, gsearch2b.best_score_

第3步:调整伽玛
现在让我们使用上面已调整的参数调整伽马值。Gamma可以采用各种值,但我会在这里检查5个值。您可以进入更精确的值。
param_test3 = {
'gamma':[i / 10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(estimator = XGBClassifier(learning_rate = 0.1,n_estimators = 140,max_depth = 4,
min_child_weight = 6,gamma = 0, subsample = 0.8,colsample_bytree = 0.8,
objective ='binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27),
param_grid = param_test3,scoring ='roc_auc',n_jobs = 4,iid = False,cv = 5 )
gsearch3.fit(train [predictors],train [target])
gsearch3.grid_scores_,gsearch3.best_params_,gsearch3.best_score_

这表明我们的伽玛原始值,即0是最佳值。在继续之前,一个好主意是重新校准更新参数的增强轮数。
xgb2 = XGBClassifier(
learning_rate = 0.1,
n_estimators = 1000,
max_depth = 4,
min_child_weight = 6,
gamma = 0,
subsample = 0.8,
colsample_bytree = 0.8,
objective ='binary:logistic',
nthread = 4,
scale_pos_weight = 1,
seed = 27)
modelfit(xgb2,train,predictors)

在这里,我们可以看到得分的提高。所以最终的参数是:
- max_depth:4
- min_child_weight:6
- gamma:0
第4步:调整子样本和colsample_bytree
下一步是尝试不同的subsample和colsample_bytree值。让我们分两个阶段进行,并且两者的值均为0.6,0.7,0.8,0.9。
param_test4 = {
'subsample':[i / 10.0 for i in range(6,10)],
'colsample_bytree':[i / 10.0 for i in range(6,10)]
}
gsearch4 = GridSearchCV(estimator = XGBClassifier(learning_rate) = 0.1,n_estimators = 177,max_depth = 4,
min_child_weight = 6,gamma = 0,subsample = 0.8,colsample_bytree = 0.8,
objective ='binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27),
param_grid = param_test4,scoring ='roc_auc',n_jobs = 4,iid = False,cv = 5)
gsearch4.fit(train [predictors],train [target])
gsearch4.grid_scores_,gsearch4.best_params_,gsearch4.best_score_

在这里,我们发现0.8是 subsample和colsample_bytree 的最佳值。现在我们应该围绕这些值尝试0.05区间的值。
param_test5 = {
'subsample':[i / 100.0 for i in range(75,90,5)],
'colsample_bytree':[i / 100.0 for i in range(75,90,5)]
}
gsearch5 = GridSearchCV(estimator) = XGBClassifier(learning_rate = 0.1,n_estimators = 177,max_depth = 4,
min_child_weight = 6,gamma = 0,subsample = 0.8,colsample_bytree = 0.8,
objective ='binary:logistic',nthread = 4,scale_pos_weight = 1,seed = 27 ),
param_grid = param_test5,scoring ='roc_auc',n_jobs = 4,iid = False,cv = 5)
gsearch5.fit(train [predictors],train [target])

我们再次得到与以前相同的值。因此,最佳值为:
- 子样本:0.8
- colsample_bytree:0.8
第5步:调整正则化参数
下一步是应用正则化来减少过度拟合。虽然很多人不会使用这些参数,因为伽玛提供了一种控制复杂性的实质方法。但我们应该总是尝试一下。我将在这里调整'reg_alpha'值并让你尝试不同的'reg_lambda'值。
param_test6 = {
'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4,
min_child_weight=6, gamma=0.1, subsample=0.8, colsample_bytree=0.8,
objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27),
param_grid = param_test6, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

我们可以看到CV得分低于之前的情况。但是尝试的值非常普遍,我们应该尝试接近最优值的值(0.01),看看我们是否能得到更好的东西。
param_test7 = {
'reg_alpha':[0, 0.001, 0.005, 0.01, 0.05]
}
gsearch7 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4,
min_child_weight=6, gamma=0.1, subsample=0.8, colsample_bytree=0.8,
objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27),
param_grid = param_test7, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch7.fit(train[predictors],train[target])
gsearch7.grid_scores_, gsearch7.best_params_, gsearch7.best_score_

你可以看到我们得到了更好的简历。现在我们可以在模型中应用此正则化并查看影响:
xgb3 = XGBClassifier(
learning_rate = 0.1,
n_estimators = 1000,
max_depth = 4,
min_child_weight = 6,
gamma = 0,
subsample = 0.8,
colsample_bytree = 0.8,
reg_alpha = 0.005,
objective ='binary:logistic',
nthread = 4,
scale_pos_weight = 1,
种子= 27)
modelfit(xgb3,train,predictors)

我们再次看到分数略有改善。
第6步:降低学习率
最后,我们应该降低学习率并增加更多树木。让我们使用XGBoost的cv函数再次完成工作。
xgb4 = XGBClassifier(
learning_rate = 0.01,
n_estimators = 5000,
max_depth = 4,
min_child_weight = 6,
gamma = 0,
subsample = 0.8,
colsample_bytree = 0.8,
reg_alpha = 0.005,
objective ='binary:logistic',
nthread = 4,
scale_pos_weight = 1,
种子= 27)
modelfit(xgb4,train,predictors)

现在我们可以看到性能的显着提升,参数调整的效果更加清晰。
在我们结束时,我想分享两个关键想法:
- 这是很难得到一个非常大的飞跃只要使用在性能参数整定或略好机型。GBM的最高得分为0.8487,而XGBoost得分为0.8494。这是一个不错的改进,但不是非常重要的事情。
- 通过特征工程,创建模型集合,堆叠等其他方法可以获得显着的跳跃
XGBoost中参数调整的完整指南(包含Python中的代码)的更多相关文章
- 接口测试中实际发生的几个问题——python中token传递
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:AFKplayer PS:如有需要Python学习资料的小伙伴可以加点 ...
- Python中的print、input函数以及Python中交换两个变量解析
一.Python中的值交换操作 首先明确一点点,Python中的一切都是面向对象的,可以理解为Python的中一切都是对象. 我们知道Java也是面向对象的语言,但是在Java中定义一个值变量如下: ...
- python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器
1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...
- js方法中参数传过来的值包含括号
前提,传递的id为变量值,比如从后台获取数据循环,在每个循环里调用shenpi()方法,假设传的id包含括号,例如 20190329100833(更正) 这样的数据,那么直接调用会报错,控制台会报错: ...
- PHP中获取当前页面的完整URL & php $_SERVER中的SERVER_NAME 和HTTP_HOST的区别
#测试网址: http://localhost/blog/testurl.php?id=5 //获取域名或主机地址 echo $_SERVER['HTTP_HOST']."<b ...
- 使用 JsonPath 完成接口自动化测试中参数关联和数据验证(Python语言)
背景: 接口自动化测试实现简单.成本较低.收益较高,越来越受到企业重视 restful风格的api设计大行其道 json成为主流的轻量级数据交换格式 痛点: 接口关联 也称为关联参数.在应用业务接口中 ...
- vue不通过路由直接获取url中参数的方法示例
vue不通过路由直接获取url中参数的方法示例 vuejs取得URL中参数的值地址:http://localhost:3333/#/index?id=128console.log(this.$rout ...
- python函数中参数是如何传递的?
python中一切皆对象,函数中参数传递的是对象的引用. 1在函数中改变变量指向的对象,即指向不同对象. 当在函数中修改传递进来的变量指向另一个对象时,实参的对象不会改变. >>> ...
- python函数中参数的传递
Python唯一支持的参数传递方式是『共享传参』(call by sharing)多数面向对象语言都采用这一模式,包括Ruby.Smalltalk和Java(Java的引用类型是这样,基本类型按值传递 ...
随机推荐
- Hive元数据配置到MySql
1 驱动拷贝 1.在/opt/software/mysql-libs目录下解压mysql-connector-java-5.1.27.tar.gz驱动包 [root@hadoop102 mysql-l ...
- React Core Features
React Core Features Here is a summary of the core features. We will cover each feature in detail thr ...
- Error handling in Swift does not involve stack unwinding. What does it mean?
Stack unwinding is just the process of navigating up the stack looking for the handler. Wikipedia su ...
- bzoj1115&&POJ1704&&HDU4315——阶梯Nim
BZOJ1115 题意:阶梯Nim游戏大意:每个阶梯上有一堆石子,两个人在阶梯上玩推石子游戏.每人可以将某堆的任意多石子向左推一阶,所有的石子都推到阶梯下了即算成功,即不能推的输. 分析:根据阶梯Ni ...
- RabbitMQ六种队列模式-路由模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...
- TimeStamp( )函数, TimeStampAdd( )函数 , TimeStampDiff( )函数
官网:https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampdiff TIMES ...
- 【luoguP4720】【模板】扩展卢卡斯
快速阶乘与(扩展)卢卡斯定理 \(p\)为质数时 考虑 \(n!~mod~p\) 的性质 当\(n>>p\)时,不妨将\(n!\)中的因子\(p\)提出来 \(n!\) 可以写成 \(a* ...
- Xilinx ISE中Synplicity.ucf无法加上去的问题
在Xilinx ISE中使用Synplify pro进行综合时,有时出现无法将synplicity.ucf添加进工程的问题.这时可以在其它目录下备份synplicity.ucf, 然后使用clean ...
- 市值TOP10,人类进化及中美坐标
题记:观察人类进化,以及各国.各民族在这个进化中所起的作用.所处的位置,市值 TOP 10 的变迁,会是一个再好不过的指标! 2008年,经历了全球金融危机后,原油期货一路飙升,创出了147.27美元 ...
- MORMOT REST文件上传
MORMOT REST文件上传 上传数据格式必须是:MULTIPART/FORM-DATA uses SynCommons 后端处理参照下列代码: 后端处理参照下列代码: procedure TWeb ...