ITPub博客

首页 > 数据库 > 数据库开发技术 > 冲击冠军24W,独家开源方案,马栏山防盗链赛道

冲击冠军24W,独家开源方案,马栏山防盗链赛道

原创 数据库开发技术 作者:quincyqiang 时间:2021-05-02 10:18:53 0 删除 编辑

前言

ChallengeHub核心成员starry独家授权本次防盗链baseline方案(starry太忙没时间写),本次方案良心之作,仔细阅读学习,你将会学习很多。

赛题介绍

赛题链接请点击我跳转

随着业务的发展,芒果的视频内容也深受网友的喜欢,不少视频网站和应用开始盗播芒果的视频内容,盗链网站不经过芒果TV的前端系统,跳过广告播放,且消耗大量的服务器、带宽资源,直接给公司带来了巨大的经济损失,因此防盗链在日常运营中显得尤为重要。如何从海量日志中识别出盗链行为,并进行有效拦截,也是防盗链工作的核心。

赛题任务

以大赛组织方提供的访问日志,通过算法,识别出危险用户(auth_ret = 1)

评审规则

比赛数据分为A.zip(训练集 a.txt,验证集 a-test.txt),B.zip(测试集 b.txt)。其中训练集包括auth_ret 字段,日志格式以及示例请点击上面的赛题链接

参赛选手按行提交结果,每一行对应一个结果auth_ret。计算正确分类F1值,如下示例。

0
0
1

分数计算方法: F1-score

方案解读

1.读取训练集和测试集txt数据

%% time
data=[]
with open('a.txt',"r") as f:
     for i,line in enumerate(f.readlines()):
            res=json.loads(line.strip())
            if len(res)==13:
                data.append(res)

with open('a-test.txt',"r") as f:
     for i,line in enumerate(f.readlines()):
            res=json.loads(line.strip())
            if len(res)==12:
                res.append("-1")
                data.append(res)
col=["remote_addr", "time_iso8601", "status", "file", "body_bytes_sent", "request_time", "uuid", "http_referer", "http_user_agent", "http_x_forwarded_for", "pno", "ld", "auth_ret"] 

dd=pd.DataFrame(data,columns=col)
del data

df=dd[:2000]

2.特征工程

file字段字符串都是不规则的,从一长串的字符串中提取有用的信息,得到文件第一个日期:

def get_file_day(x):
    tem=x.split("/")
    for i,j in enumerate(tem):
        if j[:2]=="20":
            try:
                date=tem[i]+"-"+tem[i+1]+"-"+tem[i+2].split("_")[0]
                time.strptime(date, "%Y-%m-%d")
                return date
            except:
                return 
    return 
        
        
dd['file_day1']=dd['file'].apply(get_file_day)

得到文件第二个日期

def get_file_day2(x):
    tem=x.split("/")
    for i,j in enumerate(tem):
        if len(j)>15:
            try:
                cc=j.split("_")[1]
                date=cc[:4]+"-"+cc[4:6]+"-"+cc[6:]
                time.strptime(date, "%Y-%m-%d")
                return date
            except:
                return 
    return 
        
        
dd['file_day2']=dd['file'].apply(get_file_day2)

得到文件所属类型

def get_file_type(x):
    tem=x.split("/")
    return tem[-2].split("_")[-1]
    
    

dd['file_type']=dd['file'].apply(get_file_type)
dd['file_type']=dd['file_type'].apply(lambda x:  "N" if len(x)>10 else x)

提取time_iso8601字段的时间信息:天、小时、分钟等

dd["day"]=dd["time_iso8601"].apply(lambda x:x[:10])
dd["H"]=dd["time_iso8601"].apply(lambda x:x[11:13])
dd["time"]=dd["time_iso8601"].apply(lambda x:x[11:19])
dd["minute"]=dd["time_iso8601"].apply(lambda x:x[11:16])

处理一些异常字符

dd['http_x_forwarded_for']=dd['http_x_forwarded_for'].apply(lambda x:0 if x=="-" else 1)

Count计数特征,反馈特征出现的频率高低:

##count特征
for i in ['H',"minute","day","file_day1","file_day2",'http_user_agent',"http_referer","remote_addr","time"]:
    col=i+"count"
    dd[col]=dd[i].map(dd.groupby([i])['pno'].count())

逻辑特征,判断字符出现的日期是否相同

dd["day=day1"]=(dd['day']==dd['file_day1']).astype(int)
dd["day=day2"]=(dd['day']==dd['file_day2']).astype(int)
dd["day1=day2"]=(dd['file_day2']==dd['file_day1']).astype(int)

对string特征转化为数值型特征,便于输入到模型中学习

dd['auth_ret']=dd['auth_ret'].astype(int)
dd['request_time']=dd['request_time'].astype(float)

指定类别特征,让LGBM模型处理

for i in dd.columns:
    if dd[i].dtype=="object":
        dd[i]=dd[i].astype('category')

3.模型建立

skf = StratifiedKFold(n_splits=5, random_state=1996, shuffle=True)
X_train=dd[dd['auth_ret']!=-1].reset_index(drop=True)
X_test=dd[dd['auth_ret']==-1].reset_index(drop=True)
del dd

y=X_train.auth_ret
X_train=X_train[fea]
X_test=X_test[fea]

oof = np.zeros(X_train.shape[0])
prediction = np.zeros(X_test.shape[0])

# del X_train
# del X_test




for index, (train_index, test_index) in enumerate(skf.split(X_train, y)):
    train_x, test_x, train_y, test_y = X_train.iloc[train_index], X_train.iloc[
            test_index], y.iloc[train_index], y.iloc[test_index]
    dtrain = lgb.Dataset(train_x, label=train_y)
    dval = lgb.Dataset(test_x, label=test_y)
    lgb_model = lgb.train(
            parameters,
            dtrain,
            num_boost_round=10000,
            valid_sets=[dval],
            early_stopping_rounds=50,
            verbose_eval=50,
            #feval=myeval,
        )
    x2 = lgb_model.predict(test_x, num_iteration=lgb_model.best_iteration)
    y2 = lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration)
    oof[test_index] += x2
    prediction+= y2 / 5
roc_auc_score(y,oof)

以上就是整个baseline的过程,主要是特征工程环节,由于本次比赛数据量级非常大,因此批量的特征工程是不现实的,因此从业务角度挖掘少而强特征是非常有必要的。如果这对你工作学习有帮助,点赞关注一键三连,支持我的工作。

获取完整notebook代码,请关注公众号:ChallengeHub,回复“马栏山防盗链”,获取群文件。


扫码加我好友进微信群|QQ群


原文作者:ChallengeHub;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-01-07

  • 博文量
    350
  • 访问量
    160988