初赛的时候,是看交流区大佬分享的一个关于孤立森林的0.49 baseline,然后才使得自己去尝试这个 无标签数据的分类比赛。(去查了下孤立森林就是,异常点检测的算法)
然后也是用 全正样本的提交,根据F1_score算出来了正样本的比例(正样本是攻击日志,数量少 (500w的0.3%),负样本是正常日志,数量多500w)
起初几天,是去调孤立森林的n_estimators的大小,(当时也是忘了之前学的随机森林调参的知识了),因为人家只写了一个参数,我就以为只有一个参数。直至后来比赛要结束了,小伍哥发布了一版“调整了 TF-IDF n-gram 和孤立森林max_features”等等参数的baseline,我才如梦初醒,这些可以调!然后接下来就去试试 TFIDF TfidfVectorizer不同分词力度, char ,char_wb(原来给的是char,但是我看char分出来的东西,什么等于号呀,一些不是词的词都包含其中,我觉得用这个去分类也不会有什么好的结果)。就先把等号去掉,然后用char_wb去分词(也不会空格分进来)。然后还租了服务器,在上面跑了一个多小时。最后切割为22个特征。
这些点 都是我自己觉得的,我也没有心力去跑其他参数,观察两者的分数差别了。
然后就用新数据去调优孤立森林,固定一个参数,然后遍历其他参数,然后森林的话,影响最大的是n_estimators,所以当时就跑了个1000的,当然后续发现是n_estimators 200 ,max_features=8,比较ok,最后也就跑个0.60出头的样子也算是摇摇晃晃进复赛了。
复赛从2分类变成7分类,单纯(放弃思考)的我,选择了用二分类的方式来做,先用几次提交试出来不同分类的数量,然后算出来相对于整体的异常比例,然后用孤立森林,去一次一次的预测。
后来官方还给了一个重要提示——第一个星期只有两个类,第二星期有三个类,四三个星期只有两个类。那按我上面的想法完全可行。我都已经幻想着0.6得分了。
之前在提交全特定样本的时候,我也是观察了一下数据,结合常识,sql_attack多半是对数据库修改的,然后db(数据库字段)如果有参数的话,估计就是了。然后这么思考用几条if else写简单分类了一下,分数0.20。后面在都把比例试出来之后,(我也不知道多分类,根据F1score算出来的数量对不对)反正相较于初赛的0.03的异常比例,复赛好像是0.003
然后我就按着我那个思路,孤立森林分完之后,在异常里面用kmeans聚类。然后打标签,最后没打标签的都是normal,这样跑了个0.21。
之后心有不甘(好像也没啥不甘心的)。总之就是觉得自己对这个异常检测领域,也不熟悉,就知道一个孤立森林。要是知道其他模型,ensemble一下,肯定会更好。
确实被我找到了,一个封装了很全模型的库,统一了接口,而且自带集成SUOD。我好像需要做的就是往detector_list里面写入我想要使用的模型。那我肯定是认为越多越好。于是按照范例一股脑的放进去了。
结果就是有几个模型在百万级数据面前,运行的死慢,点名批评 KNN。试这个错用了一晚上,
————— 2022-10-11 —————
还是那个在复赛的那个
原本也是说,不搞了,搞不出来了
然后换比赛了,集中精力去搞别的了
可是
一顿找,又找到了个集成的github仓库
集成了异常点检测的各种模型
什么线性模型,概率模型,深度学习模型呀
都有
调用方法也是一样的
就只用在 数组里面把名字写上就好了
那既然都有
我肯定要都用呀
然后他们每个模型给出一个值,判断这个点是不是异常点,然后最后再平均一下,得到最终的结果
我就跟着范例去用了一下
以为很快能跑出来
结果跑了一晚上也没有动静
第二天,我放在 autodl上的用大一点的内存,用他里面写的njobs,多线程并行去跑
又是跑了一天(一个小时五毛钱),跑到晚上九点,跑了我快五块钱了。还是没有跑出来
然后我关了,睡觉了。
昨天,我鼓足勇气,依次去把每个模型接口文件都看了看,然后把每个都单独用1000的数据量(相较于我整体200万的数据来说,1000很少很少了)跑了一下。然后也是借此区分出了哪几个模型跑的特别慢。
我想着1000的数据量都是200ms,那我这个列表10个模型也就2s,200 0000,也就是4000s 也就一个小时吧。我就用我工位的电脑跑
然后跑了一晚上,早上一来看
还是没反应
我暂停了,然后看强制中断的日志,来看现在进行到哪里了。发现还在跑一个feature bagging的模型,然后意识到,这个模型是一个ensemble模型,也就是一个继承模型,他里面还套了200个小模型。我吐了
赶快把那个注释了,然后最后又试了许久,确定剩下的都是单模型。
然后然后数据量调大一点,一跑,报memory error
内存不足
只能去服务器上跑
我就租了个1.36元一小时的
CPU15核心的,内存50g
然后我发现那个核心数我并不能都用上
我用的这个集成框架 他是可以约定用几个核心的
我用15他报错
n jobs=9报错
n jobs=5才能用
我想着一个页面只能用5个
我就多开几个页面
然后 发现可是多开
然后就会导致前面的报错
然后我放弃了
就用一个页面
可我觉得太亏
我就换了一个服务器
然后我想到昨天看的博文《kaggle 大师》说,能不用jupyterbook就别用,都用pycharm就行了。
我就把ipynb转成python然后连上服务器去跑。
然后我发现那个核心数那里还是报错
我意识到了
因为我看过那些模型的参数
其中有些模型他也有那个n_jobs那个参数。可能我在最后设定了10,然后前面里面有个模型用了1,导致后面和前面对不上了,所以一直报错
所以我就把那些有n_jobs参数的模型都注释到了(后来测出来的是,目录里面定义的n_jobs不要算到总数里面,只用数一下那些不带n_jobs的模型数量有几个,然后设定就好了)
所以最后是跑的慢的模型不要,占用并行线程的模型不要。留下来的也没几个了。
然后运行了
就报错了
说是模型不接受有nan 和inf的
看了看数据没有空值和无穷大呀
然后去查了
说是有的模型,根据相似度聚类的,他算出来的相似度就是空值(有的还是负相关,负值)。但是最后集成去计算概率的时候,他不接受这些值。
我就去找源码,然后在那个报错的地方,之前把整个矩阵用numpy的那个NANtonum方法,转一下。
(是直接在仓库里面改模型文件 python3.8/site-packages/pyod/models/suod.py)
最后是成功运行了。
现在在工位连着服务器在跑。
跑出来了,然后在异常里面改一下分类再跑一遍,根据预测值划分阈值,确定对应的标签。提交0.16,okok结束了。
然后今天早上,写这个复盘,又想到最后是不是用聚类,然后用kmeans又试了一下。是不是用简单分类,然后不行了,这个真的比我天天自己内耗要难受多了,又要逼着自己去写代码,又要逼着自己去奇思妙想,没水平就在这里止步吧。
再见了您内