网页文本分类题赛后总结(排名第二)
关联比赛: 第二届阿里云安全算法挑战赛
第一次参加阿里天池的比赛,虽然总成绩没能进前十,但是网页题做的还不错(最终排名第二,成绩 0.8312 分)。在这里记录一下网页文本分类题的解题思路和赛后总结:
出题背景是阿里云服务器上存在着很多非法网页,需要通过机器学习算法识别出网页的类别,对非法网页进行打击。原始数据是网页静态 html 代码,但可转换为文本分类问题。训练集的标签已给出,共有 4 个类别:
fake_card(证件卡票):提供伪造证件、发票、证明材料等制作服务;
gambling(赌博类):包括赌博交易、网络博彩、赌博器具等;
sexy(色情类):包括色情传播、文图视频、网络招嫖等;
normal(正常类):不包含以上内容的网页。
算法整体流程图:
关键步骤:1、数据预处理训练数据中,id 字段是经过 hash 处理的,会出现 id 重复的情况,需要根据 id 对数据进行去重;另外对各类型网页 html 文本长度的统计结果如下所示:
网页文本长度大于 200000 的不到网页数据总量的 1%,且基本不包含风险网页,所以对其进行清除,减少后续的计算量;观察出字符长度小于 200 的网页中大部分内容为"404 ERROR","正在等待响应...",'"排队中..."等内容,对模型的训练没有用处,也要进行清除。代码在下方:
--计算 id 的出现次数 select id, risk, html, count(id) over (partition by id) as count from {t1} ;--数据清理 select * from ${t1} where count = 1 and html_length > 200 and html_length < 200000 ;2、网页文本提取 html 字段是网页的源代码,包含了结构化的 html 标签,<style>、<script>等标签中的内容不包含语义信息,参考文献[5]中结论,实验中只对 title、keywords、description、body 标签中的文本进行提取,另外去除文本中的特殊字符,仅保留英文、中文以及常见的标点符号。html 中文本内容的提取通过在 MapReduce 的 map 函数中调用 jsoup 库实现(因为 ODPS 有沙箱隔离的限制,实验中抽取了 jsoup 的核心代码放到自定义的包中打包上传)
package cn.edu.whu.tianchi_htmlclassify;import cn.edu.whu.tianchi_htmlclassify.nodes.Document;import cn.edu.whu.tianchi_htmlclassify.nodes.Element;import cn.edu.whu.tianchi_htmlclassify.select.Elements;import com.aliyun.odps.OdpsException;import com.aliyun.odps.data.Record;import com.aliyun.odps.data.TableInfo;import com.aliyun.odps.mapred.JobClient;import com.aliyun.odps.mapred.MapperBase;import com.aliyun.odps.mapred.conf.JobConf;import com.aliyun.odps.mapred.utils.InputUtils;import com.aliyun.odps.mapred.utils.OutputUtils;import com.aliyun.odps.mapred.utils.SchemaUtils;import java.io.IOException;
public class HtmlExtractor {public static void main(String[] args) throws OdpsException {JobConf job = new JobConf();job.setMapperClass(MapperClass.class);job.setMapOutputKeySchema(SchemaUtils.fromString("id:string"));job.setMapOutputValueSchema(SchemaUtils.fromString("title:string,keywords:string,description:string,bodytext:string"));job.setNumReduceTasks(0);InputUtils.addTable(TableInfo.builder().tableName(args[0]).build(), job);OutputUtils.addTable(TableInfo.builder().tableName(args[1]).build(), job);JobClient.runJob(job);}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MapperClass</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">MapperBase</span> </span>{<span class="hljs-keyword">private</span> Record output;
3、文本分词在中文文本分类中,常用的特征单元有字、词、字串(character n-gram)及其组合,中文中单个字的语义质量不是很好,一般不作为特征单元,词与二字串的效果相似。在天池 PAI 平台上,有基于 AliWS(Alibaba Word Segmenter 的简称)的分词组件,若用户指定了词性标注或语义标注相关参数,则会将分词结果、词性标注结果和语义标注结果一同输出。在这里勾选词性标注,在词的初步过滤中会用到词性。
4、词初步过滤
停用词过滤
使用 https://github.com/JNU-MINT/TextBayesClassifier 中停用词;
词性过滤(仅保留动词、名词)
参考[7]中实验结果,仅适用动词、名词作为特征词。
5、词频统计在对文章进行分词的基础上,按行保序输出对应文章 ID 列(docId)对应文章的词,统计指定文章 ID 列(docId)对应文章内容(docContent)的词频。使用词频统计组件分别对 title、keywords、description、bodytext 进行词频统计,得到文档 i 中词 j 出现在 title、keywords、description、bodytext 中的个数
可以对 title、keywords、description、body 设置不同的权重,测试了不同权重的组合,当四个标签权重都为 1 时分类精度最高,词频权重组合的方法如下所示:
select *, (title_count * 1 + key_count * 1 + des_count * 1 + body_count * 1) as count from ${t1}6、特征词选择特征词的选择在很多博客与论文[1][6]中都有叙述,常见的特征提取方法有文档词频(Document Frequency, DF)、信息增益(Information Gain, IG)、互信息(Mutual Information, MI)、卡方统计(CHI)、期望交叉熵(Expected Cross Entropy)等等, 由于时间限制,我们试验了几种通常情况表现好的方法进行结合:文档词频 + 信息增益 + 卡方增益,对比了几组不同的阈值,得到了较好的分类效果。
文档词频:在训练文本集中对每个词计算其文档频数,若该词的 DF 值小于某个阈值或者大于某个阈值都要进行去除,因为小于某个阈值代表了该词“没有代表性”,大于某个阈值代表了“没有区分度”。
信息增益:信息增益是一种基于熵的评估方法,定义为某个词为分类能够提供的信息量, 其值为不考虑任何词的熵与考虑该词后的熵的差值。计算公式如下:
卡方统计:卡方统计体现特征词与类别之间独立性的缺乏程度,它同时考虑了特征词存在与不存在的情况。卡方统计值越大,独立性越小,相关性越大。计算公式如下:
查看更多内容,欢迎访问天池技术圈官方地址:网页文本分类题赛后总结(排名第二)_天池技术圈-阿里云天池
评论