此次比赛,达观数据提供了一批长文本数据和分类信息,希望选手动用自己的智慧,结合当下最先进的NLP和人工智能技术,深入分析文本内在结构和语义信息,构建文本分类模型,实现精准分类。
评分算法 :binary-classification
评分标准 :采用各个品类F1指标的算术平均值,它是Precision 和 Recall 的调和平均数。
F 1 = 1 n ∑ i = 1 m 2 ⋅ P i ⋅ R i P i + R i F_1=\frac{1}{n}\sum_{i=1}^{m}\frac{2·P_i·R_i}{P_i+R_i} F1=n1i=1∑mPi+Ri2⋅Pi⋅Ri
其中, P i P_i Pi是表示第 i i i个种类对应的Precision, R i R_i Ri是表示第 i i i个种类对应Recall。
每一行对应一篇文章。文章分别在“字”和“词”的级别上做了脱敏处理。共有四列:
训练集:(102277, 4)
测试集:(102277, 3)
数据 | id | article | word_seg | class |
---|---|---|---|---|
train_set(训练模型) | 文章的索引 | 文章正文在“字”级别上的表示,即字符相隔正文 | 在“词”级别上的表示,即词语相隔正文 | 这篇文章的标注 |
test_set(用于测试) | 文章的索引 | 文章正文在“字”级别上的表示,即字符相隔正文 | 在“词”级别上的表示,即词语相隔正文 | 待预测 |
首先,应该是分析数据得到其中的特征,但比赛数据是经过脱敏后的数据,所以就没分析。
问题1:
训练数据与测试数据有2G多,在pycharm里运行demo时一直报错Process finished with exit code -1073740940 (0xC0000374),
解决办法:
pandas包更新到最新版
pycharm中后缀为vmoptions的配置文件里Xms、Xmx的值调大
问题2: 读取文件报异常 field larger than field limit (131072)
解决办法:使用如下代码
import sys,csv
maxInt = sys.maxsize
decrement = True
while decrement:
# decrease the maxInt value by factor 10
# as long as the OverflowError occurs.
decrement = False
try:
csv.field_size_limit(maxInt)
except OverflowError:
maxInt = int(maxInt/10)
decrement = True
问题3: 读取文件报异常2 OSError:Initializing from file failed
解决办法:
读取文件时加上参数 engine=‘python’
将读取文件引擎改为python (默认情况下是c)
问题4: 原始数据的列名可能会出现乱码
解决办法:
df_train.columns = ['id','article','word_seg',"class"]
df_test.columns = ['id','article','word_seg']
直接提取了tf(词频)、hash(哈希)、tfidf(term frequency–inverse document frequency)词频逆文本频率、lsa(潜在语义特征)、Doc2vec等特征。还有一个特征是LDA(线性判别式分析),由于要生成这个特征的时间太长所以放弃了,即使把tf特征筛选之后生成LDA特征,时间也是不能接受。
Tfidf特征代表的是词的重要程度,直觉上这个特征一定比tf特征要好,所以最开始使用的这个特征。之前常听Word2vec。所以当时查了一下Word2vec 和Doc2vec的区别(忘了··)---------------------
word2vec根据给定上下文,预测上下文的其他单词。
Doc2Vec 或者叫做 paragraph2vec, sentence embeddings,是一种非监督式算法,可以获得 sentences/paragraphs/documents 的向量表达,是 word2vec 的拓展。学出来的向量可以通过计算距离来找 sentences/paragraphs/documents 之间的相似性,可以用于文本聚类,对于有标签的数据,还可以用监督学习的方法进行文本分类,例如经典的情感分析问题。
TF-IDF可以有效评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。因为它综合表征了该词在文档中的重要程度和文档区分度。但在文本分类中单纯使用TF-IDF来判断一个特征是否有区分度是不够的。
由于生成多个特征所以考虑了特征融合。回头看数据,数据中把文章分成“词”表示和“字”表示,之前的实验都是建立在“词”表示文章的基础上,所以接下来也把“字”表示文章加入实验中。
特征 | 模型 | 验证集分数 | 耗时(min) | 比赛A榜得分 |
---|---|---|---|---|
lsa + vec2vec + tf.idf | SVM | 0.7789 | 173.31 | 0.775902 |
tfidf + tfidf_article | SVM | 0.7800 | 25.19 | 0.7760 |
tfidf_article + lsa +vec2vec +tf.idf | SVM | 0.7800 | 363.96 | 0.77***6 |
Dec2vec+ tfidf | lgb | 0.7698 | 2456.92 | ~~ |
调整了SVM 的参数C 。C值越大,拟合非线性的能力越强。
网格搜索,随机搜索,遗传算法
C | 分数 |
---|---|
1 | 0.7800 |
2 | 0.7798 |
~ | ~ |
10 | 0.7780 |
lsa特征可以把tfidf特征降维,可以找到词在句子中的含义(具体作用有点忘了),因为不用词在不同句子中的意思也不一样。降维也可以提高运行速度。下面是lsa特征在不同模型中的对比。
特征 | 模型 | 分数 | 耗时(min) |
---|---|---|---|
lsa | SVM | 0.7227 | 0.88 |
lsa | lr | 0.7038 | 1.85 |
lsa | NB | 0.7227 | 52 |
lsa | rf | 0.6428 | 0.74 |
lsa | Knn | 0.7227 | 2.7 |
lsa | xgboost | 0.7026 | 164.88 |
实验很耗时,最好做实验之前有个良好的规划,多问为什么要做这个实验?接下来要怎么实验?并对实验的结果有序进行记录。
不熟练理论基础,有关NLP的知识都是遇到不懂的现查现用,导致很多知识记得不牢固,过段时间就忘记了。
接下来会完善上面不会的知识,弄懂代码背后的理论依据才是正确的道路。
展望一下未来的实验,可能会先学一下多种模型融合,在Top10的PPT展示中几乎都是多种深度学习和机器学习的模型融合,这可能是未来的一个方向。
项目代码