欢迎访问Sunbet官网(www.sunbet.us),Allbet欧博官网(www.ALLbetgame.us)!

首页Sunbet_行业观察正文

初探Kaggle之再探微软歹意软件展望挑战赛

b9e08c31ae1faa592019-01-0976

0x01 基本知识

数据方面:我们还能置信CV吗

练习集和测试集的散布存在差别性,以是可以也许致使过拟合征象,即在练习集上的CV分数对照高,而在展望集上的提拔效果不是很显着,可以也许CV分数进步一个百分点,展望分数都进步不了一个千分点,这也就形成了CV分数和LB分数的鸿沟,应当去做的是在不下降太多CV分数的情况下,削减CV和LB分数的差别,进步模子的泛化能力。当练习集和测试集的特性有一样的散布时,我们可以也许置信CV,依据CV分数继承去练习模子,然则当练习集和测试集上的特性散布变化时,CV可以也许合适做个参考,而应当置信测试集的分数,即LB分数,存眷测试集的数据散布和特性散布,并和练习集的散布做对照,拔取泛化能力强的特性举行模子练习。

特性工程方面:我们能进步模子的上限吗

数据变更,有基于多项式、指数函数、对数函数的数据变更。

特性工程博学多才,花50%的时刻在上面都不为过,这可以也许决议着模子练习的上限,罕见的特性编码有规范化、归一化、二值化、One-hot编码、频次编码、统计盘算、标签编码等,罕见的新特性提取有数值特性的简朴数据变更、种别特性之间交织组合、种别特性和数值特性之间交织组合、树算法制造新特性等,罕见的特性挑选要领有filter、Wrapper、Embedded。

无量纲化中的规范化和归一化可以也许使分歧规格的数据转换到统一规格下,若是不转换的化,就欠好放在一同对照;
对定量特性二值化,设定一个阈值,大于阈值的赋值为1,小于阈值的赋值为0;
对定性特性One-hot编码,关于种别型特性,一样平常算法没法对其直接处置责罚,须要向量化种别型特性,将定性数据编码为定量数据,对照经常运用的处置责罚体式格局是One-hot编码、频次编码、标签编码。关于无序种别特性,运用One-hot编码虽然会发生大批的希罕特性,然则不失为一种可用的体式格局。然则关于有序种别特性就不方便运用One-hot编码了,可以也许须要本身界说映照映照有序种别特性;
缺失值盘算,缺失值可添补为均值;

模子评价目的:数据发掘竞赛经常运用logloss、AUC

在调参之前,我们起首要明白模子评价目的,因为拿到一个题目,可以也许题目的官方评价规范是AUC或是logloss等等,评价规范不一样,我们练习时参数设置也不一样。在一些数据发掘竞赛中,好比Kaggle,logloss和AUC是最罕见的模子评价目的,这是因为许多机械进修对分类题目的效果都是几率,若是要盘算accuracy,就要把几率转换为种别,这就要设置阈值,阈值的设置很大水平上会影响accuracy的盘算,运用AUC或logloss可以也许制止将几率转换为种别。

从理论上说,模子评价目的涉及到丧失函数和机能评价目的。模子练习的目的函数=丧失函数(价值函数)+正则项,丧失函数是用来估计模子的展望值和实在值的不一致水平,丧失函数可以也许明白为履历风险,而正则项重要用来责罚,防备模子过于庞杂,目的函数可以也许明白为组织风险。丧失函数有log对数丧失函数又叫做交织熵丧失函数(逻辑回归)、平方丧失函数(最小二乘法)、指数丧失函数(Adaboost)、Hinge丧失函数(SVM)等丧失函数。在lightgbm中metric参数(设置丧失函数)中有binary_cross_entropy选项,即二分类交织熵,就可以也许套用逻辑回归的丧失函数即对数丧失函数来盘算。

AUC只能用于二分类,指ROC曲线下面地区的面积,ROC曲线的x轴、y轴可以也许依据二分类的殽杂矩阵盘算出,AUC反应的是分类器对样本的排序能力。

调参方面:调包侠vs调参怪

树范例算法参数重要可以也许分为历程影响类和子模子影响类。在子模子稳固的情况下,可以也许转变历程影响类参数,好比n_estimators、learning_rate来转变团体的练习历程,历程影响类参数可以也许很大影响模子的团体机能,别的我们还可以也许微调子模子的参数来进一步进步模子的机能。对随机丛林来讲,增添“子模子数”(n_estimators)可以也许显着下降团体的方差,而不会对子模子的误差和方差,还可以也许调解叶子节点最小样本数、破裂所需最小样本树来仔细的调解子树的组织。

调参的目的是误差和方差的谐和。以树系列算法为例,树系列算法重要基于bagging和boosting。基于bagging的随机丛林的子模子都有较低的误差,团体模子的练习历程旨在下降方差,以是须要较少的子模子数(n_estimators默以为10)且子模子不为弱模子(max_depth默以为None)。基于boosting的Gradient Tree Boosting的子模子都有较低的方差,团体模子的练习历程在下降误差,以是须要较多的子模子数(n_estimators默以为100)且子模子为弱模子(max_depth默以为3)。

模子融会方面:如虎添翼or破釜沉舟

模子融会基本上是机械进修练习模子的末了步调了。若是我们前期把题目明白好,做好特性工程、参数调解,那末末了的模子融会可以也许让我们的模子机能再上一层楼,然则若是我们前期做的欠好时,也不要摒弃,模子融会可以也许让我们翻一翻身。

理论上来讲,模子融会可以也许带来三个方面的优点:起首,从统计的方面来看,因为进修义务的假定空间很大,可以也许有多个假定在练习集上到达一致机能,此时若运用单进修器可以也许因误选而致使泛化机能欠安,连系多个进修器可以也许减小这一风险。第二,从盘算的方面来看,进修算法往往会堕入局部极小,有的局部极小点所对应的泛化机能可以也许很蹩脚,而经由过程屡次运转以后举行连系,可以也许下降堕入蹩脚局部极小点的风险。第三,从透露表现的方面来看,某些进修义务的实在假定可以也许不在以后进修算法所斟酌的假定空间中,此时若运用单进修器肯定无效,而经由过程连系多个进修器,因为响应的假定空间有所扩展,有可以也许学得更好的近似。详细的连系战略有均匀法、投票法和进修法(典范代表为Stacking)。

0x02 详细剖析:微软歹意软件展望

对数据的明白是特性工程的基本,以是数据方面可以也许归到特性工程类,模子的评价目的分歧,调包时设置的参数分歧,可以也许归到调参方面,以是上面说过的五个方面可以也许归类到三个方面:特性工程、调参、 模子融会。这是大多数数据发掘竞赛的中心,以是我们离别从这三个方面看一下Kagglers是如何处置责罚微软歹意软件展望竞赛的。

-------------------------------------

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

-------------------------------------

特性工程

此次竞赛的特性工程对照难做,缘由可以也许在于微软供应赛题数据的时刻移除局部时刻序列数据(最最原始的数据应当是依照时刻分别好的),微软也在赛题中说清楚明了这点,时刻序列数据可以也许很症结。到现在为止总计有793只部队列入竞赛,0.690+的分数只要50只部队,只要一人到达0.700,而排名在50-150之间的分数0.688-0.690都是靠模子融会才到达的(前二十名的部队可以也许单模子就到达0.690+),也就是可以也许只要少于50人真正做了有肯定提拔效果的特性工程。

LongYin给出了几点做好特性工程的提示。若是我是一个黑客,我想去进击windows的机械,那末我会怎么做呢?第一,我会试验寻觅盛行软件的破绽,若是一个软件有许多用户,而我进击胜利,那末收益就会最大化(然则这类软件的防护性大多很好),这就是计数特性非常重要的缘由;第二,我会进击一些防护差的机械,(尤其是一些新的软件,不像老产物经由很长时刻的保护,安全性很好一样,新的产物的防护大多很弱,因而进击者有许多时机进击新产物,这就是boolean型特性非常重要的缘由。LongYin提到了CountryIdentifier, Wdft_RegionIdentifier, Census_OSBranch等特性的计数特性提拔了他的模子效果。有人依据此次提示很好的提拔了模子的机能,然则也有人试验了count feature、frequency encoding和mean encoding,效果不是很好,LongYin发起先分别练习集和考证集,再做特性工程,也有其他kaggler说将练习集和测试集离开做count feature效果好。这点我不是很明白,若是说练习集和测试集某一个feature的散布有差别,对练习集、测试集零丁做谁人特性的count feature和对练习集和测试集一同做谁人特性的count feature,我想后者效果应当好过前者啊,因为零丁做的话,练习集的count feature只能反应练习集的散布,练习的时刻依照count feature练习泛化能力应当弱的不克不及很好顺应测试集了,若是夹杂练习集测试集做count feature,那末测试集的数据会影响count feature,相当于不知不觉把测试集的一些数据散布特性带入到了模子练习中去,练习出的模子泛化能力应当很强啊。以是总的来讲,我以为夹杂数据集做特性工程比数据集零丁做特性工程获得的模子的泛化能力强。然则我试验了两种要领,效果差别可以也许忽略不计。

olivier发明了此次竞赛中一个很奇异的征象:CV分数和LB分数差别较大,并且就算是相差不大的CV分数,获得的LB分数可以也许相差很大,让Kagglers不知道该不该置信CV分数。这个征象多是数据的散布题目形成的,测试集合的许多数据在练习集合没有涌现过,好比测试集合包罗的AvSigVersion的值许多没有涌如今练习集合。针对这一题目,olivier提出了一种处理思绪:匹敌性考证要领。匹敌性考证处置责罚的是,练习集和测试集差别性较大,此时考证集已不合适评价该模子了,因为考证集来源于练习集,以是须要一个考证集可以也许代表测试集。基本思想就是,经由过程一个具有区分力的分类器,选出被分类器分错的练习集,以为这些数据和测试集很像,作为考证集。详细操纵:将练习集和测试集离别举行二种别符号,好比练习集种别设为0,测试集种别设为1。然后将这两局部数据举行夹杂,再分为新的练习集和测试集,运用新的练习集练习一个二分类收集,对新的测试数据举行测试,挑选新的测试集内里本来的练习集数据得分举行排序,选出得分最差的所需数量的数据作为我们须要的考证集。为何这么操纵呢,是因为我们以为选出的这些数据和测试集最接近。olivier经由过程这类要领做试验得出0.97的AUC,以是他预测练习集和测试集真的不一样,而匹敌考证中最大的特性是AvSigVersion和EngineVersion,这正考证了前面说到的测试集合AvSigVersion的值许多没有涌如今练习集合,olivier试着把这两个不太友爱的特性去撤除练习模子,发明效果更差了,以是这两个特性要被保存,然则须要被处置责罚能力削减扰动。有些kagglers最先试验匹敌考证要领组织练习集的子集举行练习,然则效果并非很好。

调参

调参只能提拔模子少量机能,关于此处用到的lightgbm,无非是增添树的数量;先设置轻微大一点的learning_rate,以防备迭代太慢;设置叶子节点数量;设置树的深度;设置特性挑选的比例等等。好比

Python版
param = {'num_leaves': 60,
 'min_data_in_leaf': 60, 
 'objective':'binary',
 'max_depth': -1,
 'learning_rate': 0.1,
 "boosting": "gbdt",
 "feature_fraction": 0.8,
 "bagging_freq": 1,
 "bagging_fraction": 0.8 ,
 "bagging_seed": 11,
 "metric": 'auc',
 "lambda_l1": 0.1,
 "random_state": 133,
 "verbosity": -1}

R语言版
params = list(
    boosting_type = 'gbdt', 
    objective = 'binary',
    metric = 'auc', 
    nthread = 4, 
    learning_rate = 0.05, 
    max_depth = 5,
    num_leaves = 40,
    sub_feature = 0.1*i, 
    sub_row = 0.1*i, 
    bagging_freq = 1,
    lambda_l1 = 0.1, 
    lambda_l2 = 0.1
)

因为此次竞赛中官方的模子评价规范是AUC,以是大多数人都把metric参数设置成了‘auc’,然则olivier发出了一个提示:在以AUC为评价规范的竞赛中,设置metric参数为‘binary cross entropy’也许比设置为‘auc’更好,因为auc作为一个器量规范时可以也许不稳固,可以也许触发early_stopping早停(early_stopping设置较小的情况下),而binary cross entropy更加稳固,模子效果可以也许会好一些。ps:我试验了两种参数值,发明相差无几。

模子融会

此次竞赛中症结点之一就是模子融会,我以为做模子融会有利有弊,若是前期就做模子融会,虽然能提拔很多结果,然则会舍本逐末,一味地在融模子,而没有做真正的特性工程,只管在做特性工程时可以也许会一向卡住收益很低,然则每一个阶段都有每一个阶段该做的事,以是前期须要把重心放在前期对题目的明白和剖析上面,到了后期再做模子融会再提拔一下模子机能。除非特性工程真的太难了,模子效果一向欠好,可以也许试验融会一下模子看看效果如何,也许能获得一些启示。此次歹意软件展望的特性工程就对照难做,以是最先一向卡住,有人提出了几种融会的体式格局,比方融会了已公布出来的五六个kernel:python版的lightgbm、R语言版的lightgbm、python版的ftrl,这很大的提拔了LB分数,这也许是提拔了模子在测试集上的泛化能力,如今人人的分数都挤在0.688-0.690之间一向没法打破。

0x03 详细做法:代码级

我引用了四五个kernel举行模子融会,最好的结果是LB:0.688,临时排名121/793。这里贴出R语言版的kernel。

# A quick and dirty lightgbm run. Still need to do parameter tuning and cv

library(data.table)
library(lightgbm)

# read data
dtrain <- fread('../input/train.csv', drop = 'MachineIdentifier')
dtest <- fread('../input/test.csv')

# check size in memory
print(object.size(dtrain), units='Gb')
print(object.size(dtest), units='Gb')

#sample 1/2 of training data. Will optimize later so we can use all of the data
rows = sample(1:nrow(dtrain), size = nrow(dtrain)/2, replace=FALSE)

#set dtrain to only sample rows
dtrain <- dtrain[rows, ]
print(object.size(dtrain), units='Gb')

#assign target variable to y_train
y_train <- dtrain$HasDetections
dtrain[, HasDetections := NULL]

# assign test data ids to id_test
id_test <- dtest$MachineIdentifier
dtest[, MachineIdentifier := NULL]

# save # rows in dtrain and dtest
nrow_dtrain <- nrow(dtrain)
nrow_dtest <- nrow(dtest)

# combine dtrain and dtest for preprocessing
alldata <- rbindlist(list(dtrain, dtest))

# remove dtrain and dtest
rm(dtrain, dtest)
gc()

# get vector of character columns
char_cols <- names(which(sapply(alldata, class) == 'character'))

# convert character columns to integer
alldata[, (char_cols) := lapply(.SD, function(x) as.integer(as.factor(x))), .SDcols = char_cols]

# split back into dtrain and dtest
dtrain <- alldata[1:nrow_dtrain, ]
dtest <- alldata[(nrow_dtrain+1):nrow(alldata)]

rm(alldata); gc();

# Set up processed data for lgbm
x_train <- lgb.Dataset(data = data.matrix(dtrain), label = y_train)
x_test <- data.matrix(dtest)

rm(dtrain, dtest); gc();

for (i in c(5, 6, 7, 8, 9)){
params = list(
boosting_type = 'gbdt', 
objective = 'binary',
metric = 'auc', 
nthread = 4, 
learning_rate = 0.05, 
max_depth = 5,
num_leaves = 40,
sub_feature = 0.1*i, 
sub_row = 0.1*i, 
bagging_freq = 1,
lambda_l1 = 0.1, 
lambda_l2 = 0.1
)

# train model
lgbm_mod <- lgb.train(params = params,
  nrounds = 5120,
  data = x_train, 
  verbose = 1
)

# make predictions
preds <- predict(lgbm_mod, data = x_test)

# set up submission frame
sub <- data.table(
MachineIdentifier = id_test,
HasDetections = preds
)

# write to disk
fwrite(sub, file = sprintf('submission_lgbm_%s.csv', i), row.names = FALSE)
rm(params, lgbm_mod, preds, sub); gc();
}

0x04 设法主意

现在单模子最好的结果CV:0.736,LB:0.681,CV-LB=0.736-0.681=0.055,差值有点大,而top20结果部队的CV有的还比我低,然则LB都在0.690+,差值在0.040摆布,觉得重要缘由照样我的模子泛化能力缺乏。现在做特性工程一向卡住,试验了一些特性都没法进步单模子的结果,多是因为我只剖析了练习集而没有太存眷练习集和测试集的对照,接下来盘算对照剖析一下练习集和测试集,不求CV有多高,只求削减一下CV和LB的差别。用到的代码在我的github。

网友评论