首页 > 数据库 > 数据库开发技术 > 冲击冠军24W,独家开源方案,马栏山防盗链赛道
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
%% 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]
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')
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;如有侵权,请联系管理员删除。