ideadata大数据视界吧 关注:17贴子:334
  • 8回复贴,共1

文本分类指南(上)

只看楼主收藏回复



1楼2016-12-05 16:37回复
    最近的工作涉及到文本分类问题,查阅了很多文章和资料后,大概清楚了文本分类的整体流程。根据查阅到的资料,初步编写了一个文本分类程序,在程序的编写和工程实践中遇到了各种各样容易忽视的问题。本篇文章将结合实际工程经验,把文本分类的步骤、流程与问题进行简单的介绍和总结。
    一、 文本分类简介
    自动文本分类(Automatic Text Categorization),或者简称为文本分类,是指计算机将一篇文章归于预先给定的某一类或某几类的过程。例如,我们访问新浪网站的首页,就会有“新闻、军事、社会、国际、财经、股票、基金、外汇、科技、手机、探索”等一个个栏目,将不同内容的文章和这些导航栏目相关联就对应了文本分类的过程。可见,文本分类一大主要应用范围是根据文章内容主题进行文本分类,称之为“依据主题的分类”。当然这只是文本分类的一部分应用,还有许多其他有趣的问题可以用文本分类来解决。例如,文本分类还可以用于判断文章的写作风格,作者态度(积极?消极?),甚至判断作者真伪(例如检验《盗墓笔记》中《秦岭神树》这一篇章是不是南派三叔亲笔所写?)。总而言之,凡是与文本有关,与分类有关,不管从什么角度出发,依据的是何特征,都可以叫做文本分类。


    2楼2016-12-05 16:38
    回复
      2025-06-05 03:30:35
      广告
      二、文本向量表示
      计算机进行文本分类,首要任务就是需要将文本数据转换成计算机能理解的0和1组成数字语言,这时向量空间模型(VSM:Vector Space Model)就派上了用场。简而言之,向量空间模型就是把对文本内容的处理简化为向量空间中的向量运算,并且它以空间上的相似度表达语义的相似度,直观易懂。
      那怎么才能将文本转换成向量呢?简单而又形象的词袋模型(BOW)登场了。BOW(Bag of words model)假定对于一个文本,忽略其词序和语法、句法,将其仅仅看做是一个词集合,或者说是词的一个组合,文本中每个词的出现都是独立的,不依赖于其他词是否出现。或者说当这篇文章的作者在任意一个位置选择一个词汇都不受前面句子的影响而独立选择的。但是(BOW)这种文档表示模型,基本上完全忽略了除词的信息以外所有的部分,这使得它能表达的信息量存在上限。


      5楼2016-12-05 16:38
      回复
        接下来的工作就要进行构建Bag of words模型了,假设词典的大小为9,即有9个词w1,w2,......,w9,对应于以下三篇文章D1,D2和D3。考虑最简单的向量生成情况,当词典中的词在文档中出现时标记为1,否则为0,则统计所得的词表(表格内容为杜撰,为了便于演示用法)如下:

        可以得到文章D1“今天天气真好”的向量为(1,0,1,0,1,0,0,0,0);
        可以得到文章D2“今天您吃了吗”的向量为(1,1,0,1,0,0,0,0,1);
        可以得到文章D3“您编写的代码真好”的向量为(0,1,0,0,1,1,1,1,0);


        6楼2016-12-05 16:38
        回复
          三、特征词选取
          有了以上文本的向量形式,是不是就可以直接拿着这些向量去给计算机进行分类训练了呢,答案当然是NO!首先,汉语的词汇规模至少在20万这个量级水平,假设有20万条文章语料供模型训练,那么每次训练都要处理20万*20万维的巨大矩阵。许多分类器的算法复杂度都是和矩阵的维度指数相关的,这么大维度的矩阵训练一次就可能需要大半天的时间,如果计算机配置比较低甚至直接出现内存溢出的错误。其次,在一篇文章的众多词语中,有些词对于分类显然是没有帮助的。例如上面文章D1与D2中,词语“今天”显然是一个没有区分度的词语,而词语“天气”和“吃”就有很好的区分度。如果分类的时候只采取“天气”和“吃”这两个词作为特征词汇向量,文章D1与D2的文本向量就降维至(1,0)与(0,1)。此时显然文章有更好的区分度,向量都正交了嘛,同时通过特征值筛选这一步骤向量维度从9降为了2,不仅降低了计算复杂度,也提高了分类的准确度。


          7楼2016-12-05 16:39
          回复
            如果有些特点你没看出来,那我说一说,首先,A+B+C+D=N(这不废话嘛)。其次,A+C的意思其实就是说“属于IT类的文章数量”,因此,它就等于M,同时,B+D就等于N-M。然后根据以下公式计算“码农”的卡方值:


            根据卡方检验定义,此时检验值为14,大于门限值6.635,可以确认“码农”与“IT”类有99.99%显著水平的相关,即文章出现词语“码农”我们可以大概率认为其属于“IT”类文本。计算机可以用“码农”作为特征词来筛选文本是不是“IT”,此时计算机终于有了一点点人类智慧水平了。
            计算出来的卡方值越大说明相关度越大,例如,考虑如下极端例子:“今天”与类别“IT”:


            9楼2016-12-05 16:39
            回复
              通过以上表格可以看出词语“今天”在不同类别文本中均匀分布。AD-BC等于0了,卡方值为0,说明“今天”与类别“IT”没什么关系,不能作为区分类别“IT”的特征词。实际工程中,我们可以结合训练语料的规模与特点,选取每一类别中卡方值计算度最高的前topN个词作为分类的特征词,下面是在搜狗的小规模分类语料的top10特征词示例:


              10楼2016-12-05 16:40
              回复
                四、 特征权重计算
                在之前的示例中,文档向量的生成是按照特征词是否出现简单的赋值为0、1,这样的数学描述认为在一篇文章中各个词语的重要程度是相同的,这明显是不合理的,应该是越重要的词赋予更高权重。例如俗话说重要的事情说三遍,如果有一个词在文章中反复出现了好多次,那么直觉上将这个词赋予比1更大的权重值更为合理。但是,有些常用词类似于“今天”总会在文章多次出现,认为这些词很重要又明显不合适。为了解决特征词权重的选取问题,工程上最常用也是比较好用的是TFIDF算法,下面简单介绍一下:
                TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的区分能力,是文章的关键词语。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF逆向文件频率(Inverse Document Frequency)。
                TF表示词条在文档d中出现的频率。是一个词语普遍重要性的度量。
                于在某一特定文件里的词语来说,它的重要性可表示为:

                以上式子中分子是该词在文件中的出现次数,而分母则是在文件中所有字词的出现次数之和。
                某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到:

                其中|D|:语料库中的文件总数。
                至此,分类器的训练数据准备工作算是完成了,下面总结一下数据准备过程中工程应用会遇到的小问题(坑)。


                11楼2016-12-05 16:40
                回复
                  2025-06-05 03:24:35
                  广告
                  五、工程问题处理
                  1. 分词
                  分词从实用主义的角度来讲,主要在于维护词典。HMM还是CRF对最终结果的贡献并不如词典的贡献可见。另外针对应用场景,可能还需要自己额外做一些事情。比如说针对保险相关的分类任务,需要基于正则的分词把保险产品“富德生命人寿”变成一个词,而不是“富德”“生命人寿”。这种分词粒度上的小trick是根据具体的应用场景定的。
                  2. 特征筛选
                  特征词筛选过程中一定要注意数据的清洗和过滤,选择合适的停用词表,去掉低频词汇,否则你筛选的特征词中可能会出现类似于“的”、“一一一一一”、“@几天”等出乎意料的废词。拿这些特征来训练分类器,必然不会有好的结果。
                  3. 特征重要度
                  除了TF-IDF之外,根据应用场景的不同,有不同的特征重要度的要求。如Query中给名词和专有名词有加大的权重,而在例如口碑评价中“呵呵”这种语气词也很重要,不能按照常规处理把语气词放入停用词而不采用,反而应该赋予更高的权重值。
                  4. 模型大小优化
                  有的时候工程需求对模型大小有要求,比如说即使在云端整个系统也有内存要求,希望优化。这时候主要有两个方法:
                  a. 特征选择。 加大特征选择的强度,比如说原来选Top 5000的,现在选Top 1000,这个可类比为主成分分析,会降低模型的指标数据,所以是有损的。
                  b. 精简模型。 可以删除一些最终模型中的权重特别小或者为0的特征,再基于剩下来的特征重新训练个新模型。
                  5. 提高运行效率
                  根据经验,当语料规模超过5万的时候,就需要注意运行效率的优化。提高运行效率可以从编程技巧和处理流程两方面来优化。
                  1)编程技巧。在数据准备阶段会处理大量文本数据,用java编程时要注意尽量减少生成new String类,采用StringBuilder类来处理中间字符串操作。文档语料进行分词处理时,建立词的检索词典,这样可以将一篇文章用词的检索数值(Integer)来存储替代字符串(String)存储,压缩了空间和计算复杂度。在特征筛选后,根据特征词检索值查找词典即可还原出特征词汇。
                  2)流程处理。数据准备工作可以拆为分词、特征选择、文本向量计算三部分来分别完成。每个分步过程之间通过一些数据记录文件进行数据交互。这样避免一次性将所有流程数据加入到内存引起的内存溢出错误或者大量触发jvm垃圾回收机制引发的处理性能下降。


                  12楼2016-12-05 16:40
                  回复