3Idiots-2014-Kaggle 比赛源码走读

3Idiots-2014-Kaggle比赛源码走读

  最近在研究ffm,自然要找回3Idiots在2014年kaggle比赛的解决方案。主要是研究他们的特征提取方案,写下此文记录走读大佬代码的过程,目的是方便以后查询,免得忘记。

3Idiots代码下载

git clone https://github.com/guestwalk/kaggle-2014-criteo.git

特征取值统计

  utils/count.py对训练集tr.csv 26个离散型特征(C1~C26)各自不同的取值进行了统计,包括每个值出现次数(Total)、每个值对应的label为0和1的次数(Neg和Pos),写入fc.trva.t10.txt

列名如下

Field,Value,Neg,Pos,Total,Ratio

GBDT特征准备

  converters/pre-a.py将训练集tr.csv转换成gbdt需要的数据格式。分成两部分,数值类特征(I1~I13)被转到tr.gbdt.dense,离散型特征(C1~C26)作者设置了26个特殊的取值,然后遍历csv的每一行,找出每一行中包含的特殊取值,把他们的序号(0~25)写到tr.gbdt.sparse.

数值类特征(I1~I13)处理部分如下,可见仅做了null值补全而已。

...
for j in range(1, 14):
    val = row['I{0}'.format(j)]
    if val == '':
        val = -10 
    feats.append('{0}'.format(val))
f_d.write(row['Label'] + ' ' + ' '.join(feats) + '\n')
...

离散型特征(C1~C26)处理如下,首先各行全部处理成field-value,例如C9-a73ee510这样,然后逐行找出target_cat_feats中包含的field-value,将他们的index写入tr.gbdt.sparse

#These features are dense enough (they appear in the dataset more than 4 million times), so we include them in GBDT
target_cat_feats = ['C9-a73ee510', 'C22-', 'C17-e5ba7672', 
                    'C26-', 'C23-32c7478e', 'C6-7e0ccccf', 
                    'C14-b28479f6', 'C19-21ddcdc9', 'C14-07d13a8f', 
                    'C10-3b08e48b', 'C6-fbad5c96', 'C23-3a171ecb', 
                    'C20-b1252a9d', 'C20-5840adea', 'C6-fe6b92e5', 
                    'C20-a458ea53', 'C14-1adce6ef', 'C25-001f3601', 
                    'C22-ad3062eb', 'C17-07c540c4', 'C6-', 
                    'C23-423fab69', 'C17-d4bb7bd8', 'C2-38a947a1', 
                    'C25-e8b83407', 'C9-7cc72ec2']

...
cat_feats = set()
for j in range(1, 27):
    field = 'C{0}'.format(j)
    key = field + '-' + row[field]
    cat_feats.add(key)

feats = []
for j, feat in enumerate(target_cat_feats, start=1):
    if feat in cat_feats:
        feats.append(str(j))
f_s.write(row['Label'] + ' ' + ' '.join(feats) + '\n')
...

GBDT训练

  solvers/gbdt/gbdt接收tr.gbdt.densetr.gbdt.sparsete.gbdt.densete.gbdt.sparse,训练好模型,然后输出叶子结点编号到te.gbdt.outtr.gbdt.out,都取30棵树,最深层数是7,因此一棵树叶子编号最多是 27 2 7

ffm特征准备

  ffm用到的特征包括三个方面:数值类特征(I1~I13)、离散型特征(C1~C26)和GBDT输出的叶子结点。

  • 数值类特征 numeric features (13)
    数值类特征(I1~I13),大于2的数值进行转化:
    vlog(v)2 v ← ⌊ log ⁡ ( v ) 2 ⌋

common.py/gen_feats函数对数值型特征(I1~I13)的处理:

for j in range(1, 14):
    field = 'I{0}'.format(j)
    value = row[field]
    if value != '':
        value = int(value)
        if value > 2:
            value = int(math.log(float(value))**2)
        else:
            value = 'SP'+str(value)
    key = field + '-' + str(value)
    feats.append(key)
  • 离散型特征 categorical features (26)
    首先read_freqent_feats函数读取fc.trva.t10.txt存储出现次数大于10次的离散型特征取值(以C3-xxxx这样的形式)
    离散型特征(C1~C26),出现次数少于10次的,编码成同一个特殊值{field}less,否则保持原值。

converters/pre-b.py对离散值特征的处理:

frequent_feats = read_freqent_feats(args['threshold']) # 10
...
for feat in gen_feats(row):
    field = feat.split('-')[0]
    type, field = field[0], int(field[1:])
    # 离散特征,出现次数少于10次的
    if type == 'C' and feat not in frequent_feats:
        feat = feat.split('-')[0]+'less' # 可见将编码成同一值
    if type == 'C':
        field += 13
    feats.append((field, feat))
  • GBDT特征 (30)
    直接使用.
for i, feat in enumerate(line_gbdt.strip().split()[1:], start=1):
    field = i + 39
    feats.append((field, str(i)+":"+feat)) # e.g. 40:127

最终ffm格式的value总是取1,feature采用hash并取模的方式生成。

converters/pre-b.pygen_hashed_fm_feats的处理方式:

def gen_hashed_fm_feats(feats, nr_bins):
    # 可见value总是1,即使特征中有连续值
    feats = ['{0}:{1}:1'.format(field-1, hashstr(feat, nr_bins)) for (field, feat) in feats]
    return feats

参考资料

github代码 https://github.com/guestwalk/kaggle-2014-criteo/
3 Idiots’ solution PDF
libffm PPT
深入FFM原理与实践

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一个awd攻防比赛的裁判平台。 版本:beta v2.0 开发语言:python3 + django 平台分为两个部分 裁判机 靶机 通过特定接口,来实现靶机flag与服务器的通信 搭建流程 裁判机 安装所需环境 裁判机:python3+django 全局搜索woshiguanliyuan,并修改为随机字符串,此处为管理平台地址 /untitled/urls.py path('woshiguanliyuan/',views.admin,name='admin'), path('woshiguanliyuan/table/',views.admin_table,name='admin_table'), /app/views.py if 'woshiguanliyuan' not in request.META['HTTP_REFERER']: 第31和47换为你的目录 列:("/var/www/awd_platform/app/qwe.txt","a") 修改app/management/commands/init.py,添加用户 #['用户名','用户靶机token','用户靶机token'] user=[ ['123456','FF9C92C7SDFABB71566F73422C','FF9C92C7SDFABB71566F73422C'], ['aaabbb','311F8A54SV9K6B5FF4EAB20536','311F8A54SV9K6B5FF4EAB20536'] ] 修改/app/views.py第行d89f33b18ba2a74cd38499e587cb9dcd为靶机中设置的admin_token值的md5 if('d89f33b18ba2a74cd38499e587cb9dcd'==hl.hexdigest()): 运行 python3 manage.py init python3 manage.py manage.py runserver --insecure 靶机 安装所需环境 靶机:python+requests 修改send_flag.py参数,并将其放入靶机,设权限700。 靶机 sudo python send_flag.py。 靶机生成flag脚本,send_flag.py import requests import time import random import string import hashlib token='woshiwuxudong' # 红队 baji='311F8A54SV9K6B5FF4EAB20536' def getFlag(): #return ''.join(random.sample(string.ascii_letters + string.digits, 48)) m = hashlib.md5(''.join(random.sample(string.ascii_letters + string.digits, 48)).encode(encoding="utf-8")).hexdigest() return m while(1): f=open('/flag','w') flag=getFlag() f.write(flag) data={ 'flag':flag, 'token':token, 'baji':baji, } r=requests.post('http://127.0.0.1/caipanflag/',data=data) print(r.text) f.close() time.sleep(300) 重要须知 更新作者基础上: 1.增加flag验证一次性失效性,使得每个用户都并且仅可以提交一次flag 2.增加排名情况 3.flag改为MD5 4.增加丢失flag一轮扣100分

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值