第三题是个聚类问题,题目只开放了一个文档,该文档有十个句子,最后得出聚类结果
思考:本题没有涉及到很多语义相似,而且有sklearn以及外部文件的限制,所以放弃了词向量,以及bert的使用。
1、通过观察数据,发现特征比较明显,大部分可以通过一个核心关键词就可以确定类别。所以第一种方法:(1)、对文本进行分词,大写转小写,去除标点,数字,以及停用词(2)、算出每个词在文章中的tf。(3)、取出每个句子中最大tf对应的词作为特征词。(4)比较每个句子的特征词,如果一样就归为一类,不一样就新建一类。该方法在A榜中44分,B榜66分。这个方法作为baseline
上述方法具有较大的波动性,如果数据比较特殊,效果会很差。所以尝试使用tf-idf以及聚类方法
2、由于词表与段落数较少,计算idf会不准确,比如:shenzhen在六个句子中都会有出现,而后面五个句子都是属于同一类,所以算是一个强特征,所以我们没有使用idf,而是使用df(不反转)的平方根。因为在去除停用词的前提下, 如果两个句子同时出现了某个词,是能够体现出该两个句子是有很强的相似性的。
具体方法:(1)、对文本进行分词,大写转小写,去除标点,数字,以及停用词。(2),计算tf*df,每个句子取出tf*df前十大对应的单词(从五尝试到十,十的效果好),堆成一个向量。计算每个句子对应的向量,计算余弦相似度。(3),尝试使用kmeans聚类,但是效果不好,而且需要指定类别数。所以自己写了一个聚类方法:
for i in range(len_段落):
for i in range(len_段落):
for j in range(i+1,len_段落):
取与i最相似的句子j,相似性为sim
如果sim大于阈值(0.4)就归为一类,执行以下操作
if(i 或者j有类别数):
就归为一类
elif(i 且j都没有类别数):
新建一类
elif(i 且 j都有类别数):
跳过
如果sim小于阈值,表示没有与此相似的,就新建一类
该方法对于A榜有27分,B榜72分
3、第一名大佬使用了层次聚类的方法,具体的差别就是上面聚类方法:首先各成一类,找到两个最相似的,归为一类,再找到两个最相似的归为一类,其中一个簇有多个类的计算平均距离。计算tfidf对于每个句子的前15%的词进行加权,然后去掉词频为1的词作为特征词。最终分数在82。
大佬链接:https://github.com/yanghb2020/cmb_fintech_2019