文本分类实战--从TFIDF到深度学习(附代码)

本文分享了一场文本分类竞赛的经验,详细介绍了朴素贝叶斯、XGBoost及卷积神经网络的应用与效果对比。

这几周因为在做竞赛所以没怎么看论文刷题写博客,今天抽时间把竞赛用到的东西总结一下。先试水了一个很小众的比赛–文因互联,由AI100举办,参赛队不足20个,赛题类型是文本分类。选择参赛的主要原因是其不像阿里们举办的竞赛那样,分分钟就干一件事就是特征工程和调参,然后数据又多又乱,不适合入门。其次一个原因就是目前我的研究方向就是NLP,之前也做过一个文本分类的东西,所以就参赛了。这里将主要介绍我在比赛中用到的几个模型,从理论到代码实现进行总结,代码我也放在了我的github中。

1,数据集

大家可以到竞赛官网查看赛题并下载数据集,数据集中主要包含下面几个文件,可见数据集很小也很简单,只需要使用training.csv文件进行训练我们的文本分类模型,使用testing.csv进行预测并提交结果即可:
这里写图片描述
下面是训练集的前两行,每一行的第一个数字表示该行文本的类别,后面的描述就是要建模的文本。这个数据集是11个公司的描述数据,我们要根据4774条训练数据去预测2381条数据的类别标签。除此之外,我们还可以看到这些训练数据存在较严重的类别不平衡问题。如下图所示:
这里写图片描述

2,合晟资产是一家专注于股票、债券等二级市场投资,为合格投资者提供专业资产管理服务的企业。公司业务范围包括资产管理、投资咨询和投资顾问服务。公司管理的私募基金产品主要包括股票型、债券型资产管理计划或证券投资基金,管理总资产规模80亿元左右。根据中国证券投资基金业协会数据,公司管理的私募证券投资基金(顾问管理)类规模较大,公司管理规模处于50亿元以上的第一梯队。
2,公司的主营业务为向中小微企业、个体工商户、农户等客户提供贷款服务,自设立以来主营业务未发生过变化。

了解完数据集,接下来我们开始进行文本分类,开始提交结果。

2, 朴素贝叶斯分类法

在这里插句题外话,往往这种竞赛大家喜欢一上来什么都不做先提交一个结果站站场面==也就是提交一个随机结果、均值等。因为我看到这个比赛的时候都已经快结束了,比较匆忙,所以第一次提交的也是直接用随机数生成的,后来还自作多情的按照训练集的类比占比作为每个类别概率生成随机数(结果显示确实有提高),代码如下所示2333:

import numpy as np

with open('output/random_out.csv', 'w') as f:
    for i in range(1, 2382):
        f.write(str(i))
        f.write(',')
        aa = np.random.random()
        b = 0
        if aa <= 0.25:
            b = 3
        elif aa <= 0.5:
            b = 4
        elif aa <= 0.7:
            b =6
        elif aa <= 0.775:
            b=7
        elif aa <= 0.825:
            b = 5
        elif aa <= 0.875:
            b = 8
        elif aa <= 0.925:
            b = 10
        elif aa <= 0.95:
            b = 11
        elif aa <= 0.975:
            b = 2
        elif aa <= 1:
            b = 9
        f.write(str(b))
        f.write('\n')

好,接下来说正经的,我用的第一种方法就是朴素贝叶斯,可以参见我之前的一篇博客,介绍了使用CHI选择特征,TFIDF计算特征权重,朴素贝叶斯分类的整体流程。因为之前做了这样的尝试,所以这里直接套过来看看效果如何,代码入下,这里的代码都是自己实现的,太丑,其实可以直接调用gensim的接口去做,以后有时间改改代码:

N=4774
# 读取停词表
def stop_words():
    stop_words_file = open('stop_words_ch.txt', 'r')
    stopwords_list = []
    for line in stop_words_file.readlines():
        stopwords_list.append(line.decode('gbk')[:-1])
    return stopwords_list

def jieba_fenci(raw, stopwords_list):
    # 使用结巴分词把文件进行切分
    word_list = list(jieba.cut(raw, cut_all=False))
    for word in word_list:
        if word in stopwords_list:
            word_list.remove(word)
    # word_set用于统计A[nClass]
    word_list.remove('\n')
    word_set = set(word_list)
    return word_list, word_set

def process_file(train_path, test_path):
    '''
    本函数用于处理样本集中的所有文件。并返回处理结果所得到的变量
    :param floder_path: 样本集路径
    :return: A:CHI公示中的A值,嵌套字典。用于记录某一类中包含单词t的文档总数。第一层总共9个key,对应9类新闻分类
                第二层则是某一类中所有单词及其包含该单词的文档数(而不是出现次数)。{
   
   {1:{‘hello’:8,‘hai’:7}},{2:{‘apple’:8}}}
            TFIDF:用于计算TFIDF权值。三层嵌套字典。第一层和A一样,key为类别。第二层的key为文件名(这里使用文件编号代替0-99).第三层
                    key为单词,value为盖单词在本文件中出现的次数。用于记录每个单词在每个文件中出现的次数。
            train_set:训练样本集。与测试样本集按7:3比例分开。三元组(文档的单词表,类别,文件编号)
            test_set:测试样本集。三元组(文档的单词表,类别,文件编号)
    '''
    stopwords_list = stop_words()
    # 用于记录CHI公示中
评论 31
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值