精华内容
下载资源
问答
  • python 中文文本分类

    万次阅读 多人点赞 2017-02-06 11:31:21
    写这篇博文用了很多时间和精力,如果这...即已经分好文本资料(例如:语料库里是一系列txt文章,这些文章按照主题归入到不同分类的目录中,如 .\art\21.txt) 推荐语料库:复旦中文文本分类语料库,下载链接: ...

    写这篇博文用了很多时间和精力,如果这篇博文对你有帮助,希望您可以打赏给博主相国大人。哪怕只捐1毛钱,也是一种心意。通过这样的方式,也可以培养整个行业的知识产权意识。我可以和您建立更多的联系,并且在相关领域提供给您更多的资料和技术支持。

    赏金将用于拉萨儿童图书公益募捐

    手机扫一扫,即可:



    目标读者:初级入门学生。本文假定,你对python已经有了最基本的掌握。

    如果你希望能够对python有更多的掌握,可以参考博主的系列博文:

    python高手的自修课


    本文提供了python2.7和python3.6的代码,博客内容的讲解使用的是python2.7,在博客后面给出的源代码github链接中,我们给出了python2.7和python3.6的代码。其中github的master分支是python3.6,github的python2.7分支是python2.7.


    一,中文文本分类流程:

    1. 预处理
    2. 中文分词
    3. 结构化表示--构建词向量空间
    4. 权重策略--TF-IDF
    5. 分类器
    6. 评价

    二,具体细节

    1,预处理

    1.1得到训练集语料库

    即已经分好类的文本资料(例如:语料库里是一系列txt文章,这些文章按照主题归入到不同分类的目录中,如 .\art\21.txt)
    推荐语料库:复旦中文文本分类语料库,下载链接:http://download.csdn.net/detail/github_36326955/9747927

    将下载的语料库解压后,请自己修改文件名和路径,例如路径可以设置为 ./train_corpus/,
    其下则是各个类别目录如:./train_corpus/C3-Art,……,\train_corpus\C39-Sports

    1.2得到测试语料库

    也是已经分好类的文本资料,与1.1类型相同,只是里面的文档不同,用于检测算法的实际效果。测试预料可以从1.1中的训练预料中随机抽取,也可以下载独立的测试语料库,复旦中文文本分类语料库测试集链接:http://download.csdn.net/detail/github_36326955/9747929
    路径修改参考1.1,例如可以设置为 ./test_corpus/

    1.3其他

    你可能希望从自己爬取到的网页等内容中获取新文本,用本节内容进行实际的文本分类,这时候,你可能需要将html标签去除来获取文本格式的文档,这里提供一个基于python 和lxml的样例代码:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: html_demo.py
    @time: 2017/2/6 12:25
    @software: PyCharm
    """
    import sys
    from lxml import html
    # 设置utf-8 unicode环境
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    def html2txt(path):
        with open(path,"rb") as f:
            content=f.read() 
        r'''
        上面两行是python2.6以上版本增加的语法,省略了繁琐的文件close和try操作
        2.5版本需要from __future__ import with_statement
        新手可以参考这个链接来学习http://zhoutall.com/archives/325
        '''
        page = html.document_fromstring(content) # 解析文件
        text = page.text_content() # 去除所有标签
        return text
    
    if __name__  =="__main__":
        # htm文件路径,以及读取文件
        path = "1.htm"
        text=html2txt(path)
        print text	 # 输出去除标签后解析结果

    2,中文分词

    2.1概述

    第1小节预处理中的语料库都是没有分词的原始语料(即连续的句子,而后面的工作需要我们把文本分为一个个单词),现在需要对这些文本进行分词,只有这样,才能在 基于单词的基础上,对文档进行结构化表示。
    中文分词有其特有的难点(相对于英文而言),最终完全解决中文分词的算法是基于概率图模型的条件随机场(CRF)。(可以参考博主的另一篇博文)
    当然,在实际操作中,即使你对于相关算法不甚了解,也不影响你的操作,中文分词的工具有很多。但是比较著名的几个都是基于java的,这里推荐python的第三方库jieba(所采用的算法就是条件随机场)。对于非专业文档绰绰有余。如果你有强迫症,希望得到更高精度的分词工具,可以使用开源项目Anjs(基于java),你可以将这个开源项目与python整合。
    关于分词库的更多讨论可以参考这篇文章: https://www.zhihu.com/question/19651613

    你可以通过pip安装jieba:打开cmd,切换到目录  .../python/scripts/,执行命令:pip install jieba
    或者你也可以在集成开发平台上安装jieba,例如,如果你用的是pycharm,可以点击file-settings-project:xxx-Projuect Interpreter.其他平台也都有类似的安装方法。

    2.2分词操作

    不要担心下面的代码你看不懂,我会非常详细的进行讲解,确保python入门级别水平的人都可以看懂:
    2.2.1

    首先讲解jieba分词使用方法(详细的和更进一步的,可以参考这个链接):

    jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型
    jieba.cut_for_search 方法接受两个参数:需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细
    待分词的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。注意:不建议直接输入 GBK 字符串,可能无法预料地错误解码成 UTF-8
    jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode),或者用
    jieba.lcut 以及 jieba.lcut_for_search 直接返回 list
    jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定义分词器,可用于同时使用不同词典。jieba.dt 为默认分词器,所有全局分词相关函数都是该分词器的映射。

    实例代码:

    import jieba
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
    print("Full Mode: " + "/ ".join(seg_list))  # 全模式
    
    seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
    print("Default Mode: " + "/ ".join(seg_list))  # 精确模式
    
    seg_list = jieba.cut("他来到了网易杭研大厦")  # 默认是精确模式
    print(", ".join(seg_list))
    
    seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")  # 搜索引擎模式
    print(", ".join(seg_list))

    输出:
    
    【全模式】: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
    
    【精确模式】: 我/ 来到/ 北京/ 清华大学
    
    【新词识别】:他, 来到, 了, 网易, 杭研, 大厦    (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了)
    
    【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大


    2.2.2

    接下来,我们将要通过python编程,来将1.1节中的 ./train_corpus/原始训练语料库和1.2节中的./test_corpus/原始测试语料库进行分词,分词后保存的路径可以设置为

    ./train_corpus_seg/和./test_corpus_seg/

    代码如下,思路很简单,就是遍历所有的txt文本,然后将每个文本依次进行分词。你唯一需要注意的就是写好自己的路径,不要出错。下面的代码已经给出了非常详尽的解释,初学者也可以看懂。如果你还没有明白,或者在运行中出现问题(其实根本不可能出现问题,我写的代码,质量很高的。。。),都可以发邮件给我,邮件地址在代码中,或者在博文下方评论中给出。

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: corpus_segment.py
    @time: 2017/2/5 15:28
    @software: PyCharm
    """
    import sys
    import os
    import jieba
    # 配置utf-8输出环境
    reload(sys)
    sys.setdefaultencoding('utf-8')
    # 保存至文件
    def savefile(savepath, content):
        with open(savepath, "wb") as fp:
            fp.write(content)
        '''
        上面两行是python2.6以上版本增加的语法,省略了繁琐的文件close和try操作
        2.5版本需要from __future__ import with_statement
        新手可以参考这个链接来学习http://zhoutall.com/archives/325
        '''
    # 读取文件
    def readfile(path):
        with open(path, "rb") as fp:
            content = fp.read()
        return content
    
    def corpus_segment(corpus_path, seg_path):
        '''
        corpus_path是未分词语料库路径
        seg_path是分词后语料库存储路径
        '''
        catelist = os.listdir(corpus_path)  # 获取corpus_path下的所有子目录
        '''
        其中子目录的名字就是类别名,例如:
        train_corpus/art/21.txt中,'train_corpus/'是corpus_path,'art'是catelist中的一个成员
        '''
    
        # 获取每个目录(类别)下所有的文件
        for mydir in catelist:
            '''
            这里mydir就是train_corpus/art/21.txt中的art(即catelist中的一个类别)
            '''
            class_path = corpus_path + mydir + "/"  # 拼出分类子目录的路径如:train_corpus/art/
            seg_dir = seg_path + mydir + "/"  # 拼出分词后存贮的对应目录路径如:train_corpus_seg/art/
    
            if not os.path.exists(seg_dir):  # 是否存在分词目录,如果没有则创建该目录
                os.makedirs(seg_dir)
    
            file_list = os.listdir(class_path)  # 获取未分词语料库中某一类别中的所有文本
            '''
            train_corpus/art/中的
            21.txt,
            22.txt,
            23.txt
            ...
            file_list=['21.txt','22.txt',...]
            '''
            for file_path in file_list:  # 遍历类别目录下的所有文件
                fullname = class_path + file_path  # 拼出文件名全路径如:train_corpus/art/21.txt
                content = readfile(fullname)  # 读取文件内容
                '''此时,content里面存贮的是原文本的所有字符,例如多余的空格、空行、回车等等,
                接下来,我们需要把这些无关痛痒的字符统统去掉,变成只有标点符号做间隔的紧凑的文本内容
                '''
                content = content.replace("\r\n", "")  # 删除换行
                content = content.replace(" ", "")#删除空行、多余的空格
                content_seg = jieba.cut(content)  # 为文件内容分词
                savefile(seg_dir + file_path, " ".join(content_seg))  # 将处理后的文件保存到分词后语料目录
    
        print "中文语料分词结束!!!"
    
    '''
    如果你对if __name__=="__main__":这句不懂,可以参考下面的文章
    http://imoyao.lofter.com/post/3492bc_bd0c4ce
    简单来说如果其他python文件调用这个文件的函数,或者把这个文件作为模块
    导入到你的工程中时,那么下面的代码将不会被执行,而如果单独在命令行中
    运行这个文件,或者在IDE(如pycharm)中运行这个文件时候,下面的代码才会运行。
    即,这部分代码相当于一个功能测试。
    如果你还没懂,建议你放弃IT这个行业。
    '''
    if __name__=="__main__":
        #对训练集进行分词
        corpus_path = "./train_corpus/"  # 未分词分类语料库路径
        seg_path = "./train_corpus_seg/"  # 分词后分类语料库路径
        corpus_segment(corpus_path,seg_path)
    
        #对测试集进行分词
        corpus_path = "./test_corpus/"  # 未分词分类语料库路径
        seg_path = "./test_corpus_seg/"  # 分词后分类语料库路径
        corpus_segment(corpus_path,seg_path)

    截止目前,我们已经得到了分词后的训练集语料库和测试集语料库,下面我们要把这两个数据集表示为变量,从而为下面程序调用提供服务。我们采用的是Scikit-Learn库中的Bunch数据结构来表示这两个数据集。你或许对于Scikit-Learn和Bunch并不是特别了解,而官方的技术文档有两千多页你可能也没耐心去看,好在你们有相国大人。下面我们 以这两个数据集为背景,对Bunch做一个非常通俗的讲解,肯定会让你一下子就明白。

    首先来看看Bunch:

    Bunch这玩意儿,其实就相当于python中的字典。你往里面传什么,它就存什么。

    好了,解释完了。

    是不是很简单?

    接下来,让我们看看的我们的数据集(训练集)有哪些信息:

    1,类别,也就是所有分类类别的集合,即我们./train_corpus_seg/和./test_corpus_seg/下的所有子目录的名字。我们在这里不妨把它叫做target_name(这是一个列表)

    2,文本文件名。例如./train_corpus_seg/art/21.txt,我们可以把所有文件名集合在一起做一个列表,叫做filenames

    3,文本标签(就是文本的类别),不妨叫做label(与2中的filenames一一对应)

    例如2中的文本“21.txt”在./train_corpus_seg/art/目录下,则它的标签就是art。

    文本标签与1中的类别区别在于:文本标签集合里面的元素就是1中类别,而文本标签集合的元素是可以重复的,因为./train_corpus_seg/art/目录下有好多文本,不是吗?相应的,1中的类别集合元素显然都是独一无二的类别。

    4,文本内容(contens)。

    上一步代码我们已经成功的把文本内容进行了分词,并且去除掉了所有的换行,得到的其实就是一行词袋。


    那么,用Bunch表示,就是:

    from sklearn.datasets.base import Bunch
    bunch = Bunch(target_name=[],label=[],filenames=[],contents=[]) 

    我们在Bunch对象里面创建了有4个成员:
    target_name:是一个list,存放的是整个数据集的类别集合。
    label:是一个list,存放的是所有文本的标签。
    filenames:是一个list,存放的是所有文本文件的名字。
    contents:是一个list,分词后文本文件(一个文本文件只有一行)


    如果你还没有明白,看一下下面这个图,你总该明白了:

    Bunch:


    下面,我们将文本文件转为Bunch类形:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: corpus2Bunch.py
    @time: 2017/2/7 7:41
    @software: PyCharm
    """
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    import os#python内置的包,用于进行文件目录操作,我们将会用到os.listdir函数
    import cPickle as pickle#导入cPickle包并且取一个别名pickle
    '''
    事实上python中还有一个也叫作pickle的包,与这里的名字相同了,无所谓
    关于cPickle与pickle,请参考博主另一篇博文:
    python核心模块之pickle和cPickle讲解
    http://blog.csdn.net/github_36326955/article/details/54882506
    本文件代码下面会用到cPickle中的函数cPickle.dump
    '''
    from sklearn.datasets.base import Bunch
    #这个您无需做过多了解,您只需要记住以后导入Bunch数据结构就像这样就可以了。
    #今后的博文会对sklearn做更有针对性的讲解
    
    
    def _readfile(path):
        '''读取文件'''
        #函数名前面带一个_,是标识私有函数
        # 仅仅用于标明而已,不起什么作用,
        # 外面想调用还是可以调用,
        # 只是增强了程序的可读性
        with open(path, "rb") as fp:#with as句法前面的代码已经多次介绍过,今后不再注释
            content = fp.read()
        return content
    
    def corpus2Bunch(wordbag_path,seg_path):
        catelist = os.listdir(seg_path)# 获取seg_path下的所有子目录,也就是分类信息
        #创建一个Bunch实例
        bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
        bunch.target_name.extend(catelist)
        '''
        extend(addlist)是python list中的函数,意思是用新的list(addlist)去扩充
        原来的list
        '''
        # 获取每个目录下所有的文件
        for mydir in catelist:
            class_path = seg_path + mydir + "/"  # 拼出分类子目录的路径
            file_list = os.listdir(class_path)  # 获取class_path下的所有文件
            for file_path in file_list:  # 遍历类别目录下文件
                fullname = class_path + file_path  # 拼出文件名全路径
                bunch.label.append(mydir)
                bunch.filenames.append(fullname)
                bunch.contents.append(_readfile(fullname))  # 读取文件内容
                '''append(element)是python list中的函数,意思是向原来的list中添加element,注意与extend()函数的区别'''
        # 将bunch存储到wordbag_path路径中
        with open(wordbag_path, "wb") as file_obj:
            pickle.dump(bunch, file_obj)
        print "构建文本对象结束!!!"
    
    if __name__ == "__main__":#这个语句前面的代码已经介绍过,今后不再注释
        #对训练集进行Bunch化操作:
        wordbag_path = "train_word_bag/train_set.dat"  # Bunch存储路径
        seg_path = "train_corpus_seg/"  # 分词后分类语料库路径
        corpus2Bunch(wordbag_path, seg_path)
    
        # 对测试集进行Bunch化操作:
        wordbag_path = "test_word_bag/test_set.dat"  # Bunch存储路径
        seg_path = "test_corpus_seg/"  # 分词后分类语料库路径
        corpus2Bunch(wordbag_path, seg_path)

    3,结构化表示--向量空间模型

    在第2节中,我们对原始数据集进行了分词处理,并且通过绑定为Bunch数据类型,实现了数据集的变量表示。也许你对于什么是词向量并没有清晰的概念,这里有一篇非常棒的文章《Deep Learning in NLP (一)词向量和语言模型》,简单来讲,词向量就是词向量空间里面的一个向量。

    你可以类比为三维空间里面的一个向量,例如:

    如果我们规定词向量空间为:(我,喜欢,相国大人),这相当于三维空间里面的(x,y,z)只不过这里的x,y,z的名字变成了“我”,“喜欢”,“相国大人”


    现在有一个词向量是:我 喜欢  喜欢相国大人

    表示在词向量空间中就变为:(1,2,1),归一化后可以表示为:(0.166666666667 0.333333333333 0.166666666667)表示在刚才的词向量空间中就是这样:



    接下来我们要做的,就是把所有这些词统一到同一个词向量空间中。

    为了节省空间,我们首先将训练集中每个文本中一些垃圾词汇去掉。所谓的垃圾词汇,就是指意义模糊的词,或者一些语气助词,标点符号等等,通常他们对文本起不了分类特征的意义。这些垃圾词汇我们称之为停用词。把所有停用词集合起来构成一张停用词表格,这样,以后我们处理文本时,就可以从这个根据表格,过滤掉文本中的一些垃圾词汇了。

    你可以从这里下载停用词表:hlt_stop_words.txt

    存放在这里路径中:train_word_bag/hlt_stop_words.txt


    下面的程序,目的就是要将训练集所有文本文件统一到同一个词向量空间中。

    下面的一节主要目标是希望得到两个东西:

    1.词典(单词和单词对应的序号)

    2.权重矩阵tdm,其中,权重矩阵是一个二维矩阵,tdm[i][j]表示,第j个词(即词典中的序号)在第i个类别中的IF-IDF值(下文有讲解)。

    事实上,tdm的每一列都是一个单词在各个类别中的全职。我们把这每一列当作词向量。



    4,权重策略--TF-IDF

    什么是TF-IDF?今后有精力我会在这里更新补充,现在,先给你推荐一篇非常棒的文章《使用scikit-learn工具计算文本TF-IDF值


    下面,我们假定你已经对TF-IDF有了最基本的了解。请你动动你的小脑袋瓜想一想,我们把训练集文本转换成了一个TF-IDF词向量空间,姑且叫它为A空间吧。那么我们还有测试集数据,我们以后实际运用时,还会有新的数据,这些数据显然也要转到词向量空间,那么应该和A空间为同一个空间吗?

    是的。

    即使测试集出现了新的词汇(不是停用词),即使新的文本数据有新的词汇,只要它不是训练集生成的TF-IDF词向量空间中的词,我们就都不予考虑。这就实现了所有文本词向量空间“大一统”,也只有这样,大家才在同一个世界里。才能进行下一步的研究。


    下面的程序就是要将训练集所有文本文件(词向量)统一到同一个TF-IDF词向量空间中(或者叫做用TF-IDF算法计算权重的有权词向量空间)。这个词向量空间最终存放在train_word_bag/tfdifspace.dat中。

    这段代码你可能有点看不懂,因为我估计你可能比较懒,还没看过TF-IDF(尽管我刚才已经给你推荐那篇文章了)。你只需要明白,它把一大坨训练集数据成功的构建了一个TF-IDF词向量空间,空间的各个词都是出自这个训练集(去掉了停用词)中,各个词的权值也都一并保存了下来,叫做权重矩阵。

    需要注意的是,你要明白,权重矩阵是一个二维矩阵,a[i][j]表示,第j个词在第i个类别中的IF-IDF值(看到这里,我估计你压根就没去看那篇文章,所以你可能到现在也不知道 这是个啥玩意儿。。。)


    请记住权重矩阵这个词,代码解释中我会用到。

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: vector_space.py
    @time: 2017/2/7 17:29
    @software: PyCharm
    """
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    # 引入Bunch类
    from sklearn.datasets.base import Bunch
    import cPickle as pickle#之前已经说过,不再赘述
    from sklearn.feature_extraction.text import TfidfVectorizer#这个东西下面会讲
    
    # 读取文件
    def _readfile(path):
        with open(path, "rb") as fp:
            content = fp.read()
        return content
    
    # 读取bunch对象
    def _readbunchobj(path):
        with open(path, "rb") as file_obj:
            bunch = pickle.load(file_obj)
        return bunch
    
    # 写入bunch对象
    def _writebunchobj(path, bunchobj):
        with open(path, "wb") as file_obj:
            pickle.dump(bunchobj, file_obj)
    
    #这个函数用于创建TF-IDF词向量空间
    def vector_space(stopword_path,bunch_path,space_path):
    
        stpwrdlst = _readfile(stopword_path).splitlines()#读取停用词
        bunch = _readbunchobj(bunch_path)#导入分词后的词向量bunch对象
        #构建tf-idf词向量空间对象
        tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})
        '''
        在前面几节中,我们已经介绍了Bunch。
        target_name,label和filenames这几个成员都是我们自己定义的玩意儿,前面已经讲过不再赘述。
        下面我们讲一下tdm和vocabulary(这俩玩意儿也都是我们自己创建的):
        tdm存放的是计算后得到的TF-IDF权重矩阵。请记住,我们后面分类器需要的东西,其实就是训练集的tdm和标签label,因此这个成员是
        很重要的。
        vocabulary是词典索引,例如
        vocabulary={"我":0,"喜欢":1,"相国大人":2},这里的数字对应的就是tdm矩阵的列
        我们现在就是要构建一个词向量空间,因此在初始时刻,这个tdm和vocabulary自然都是空的。如果你在这一步将vocabulary赋值了一个
        自定义的内容,那么,你是傻逼。
        '''
    
        '''
        与下面这2行代码等价的代码是:
        vectorizer=CountVectorizer()#构建一个计算词频(TF)的玩意儿,当然这里面不只是可以做这些
        transformer=TfidfTransformer()#构建一个计算TF-IDF的玩意儿
        tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))
        #vectorizer.fit_transform(corpus)将文本corpus输入,得到词频矩阵
        #将这个矩阵作为输入,用transformer.fit_transform(词频矩阵)得到TF-IDF权重矩阵
    
        看名字你也应该知道:
        Tfidf-Transformer + Count-Vectorizer  = Tfidf-Vectorizer
        下面的代码一步到位,把上面的两个步骤一次性全部完成
    
        值得注意的是,CountVectorizer()和TfidfVectorizer()里面都有一个成员叫做vocabulary_(后面带一个下划线)
        这个成员的意义,与我们之前在构建Bunch对象时提到的自己定义的那个vocabulary的意思是一样的,只不过一个是私有成员,一个是外部输入,原则上应该保持一致。显然,我们在第45行中创建tfidfspace中定义的vocabulary就应该被赋值为这个vocabulary_
    
        '''
        #构建一个快乐地一步到位的玩意儿,专业一点儿叫做:使用TfidfVectorizer初始化向量空间模型
        #这里面有TF-IDF权重矩阵还有我们要的词向量空间坐标轴信息vocabulary_
        vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5)
        '''
        关于参数,你只需要了解这么几个就可以了:
        stop_words:
        传入停用词,以后我们获得vocabulary_的时候,就会根据文本信息去掉停用词得到
        vocabulary:
        之前说过,不再解释。
        sublinear_tf:
        计算tf值采用亚线性策略。比如,我们以前算tf是词频,现在用1+log(tf)来充当词频。
        smooth_idf:
        计算idf的时候log(分子/分母)分母有可能是0,smooth_idf会采用log(分子/(1+分母))的方式解决。默认已经开启,无需关心。
        norm:
        归一化,我们计算TF-IDF的时候,是用TF*IDF,TF可以是归一化的,也可以是没有归一化的,一般都是采用归一化的方法,默认开启.
        max_df:
        有些词,他们的文档频率太高了(一个词如果每篇文档都出现,那还有必要用它来区分文本类别吗?当然不用了呀),所以,我们可以
        设定一个阈值,比如float类型0.5(取值范围[0.0,1.0]),表示这个词如果在整个数据集中超过50%的文本都出现了,那么我们也把它列
        为临时停用词。当然你也可以设定为int型,例如max_df=10,表示这个词如果在整个数据集中超过10的文本都出现了,那么我们也把它列
        为临时停用词。
        min_df:
        与max_df相反,虽然文档频率越低,似乎越能区分文本,可是如果太低,例如10000篇文本中只有1篇文本出现过这个词,仅仅因为这1篇
        文本,就增加了词向量空间的维度,太不划算。
        当然,max_df和min_df在给定vocabulary参数时,就失效了。
        '''
    
        #此时tdm里面存储的就是if-idf权值矩阵
        tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
        tfidfspace.vocabulary = vectorizer.vocabulary_
    
        _writebunchobj(space_path, tfidfspace)
        print "if-idf词向量空间实例创建成功!!!"
    
    if __name__ == '__main__':
        stopword_path = "train_word_bag/hlt_stop_words.txt"#停用词表的路径
        bunch_path = "train_word_bag/train_set.dat"  #导入训练集Bunch的路径
        space_path = "train_word_bag/tfdifspace.dat"  # 词向量空间保存路径
        vector_space(stopword_path,bunch_path,space_path)

    上面的代码运行之后,会将训练集数据转换为TF-IDF词向量空间中的实例,保存在train_word_bag/tfdifspace.dat中,具体来说,这个文件里面有两个我们感兴趣的东西,一个是vocabulary,即词向量空间坐标,一个是tdm,即训练集的TF-IDF权重矩阵。


    接下来,我们要开始第5步的操作,设计分类器,用训练集训练,用测试集测试。在做这些工作之前,你一定要记住,首先要把测试数据也映射到上面这个TF-IDF词向量空间中,也就是说,测试集和训练集处在同一个词向量空间(vocabulary相同),只不过测试集有自己的tdm,与训练集(train_word_bag/tfdifspace.dat)中的tdm不同而已。

    同一个世界,同一个梦想。

    至于说怎么弄,请看下节。


    5,分类器

    这里我们采用的是朴素贝叶斯分类器,今后我们会详细讲解它。

    现在,你即便不知道这是个啥玩意儿,也一点不会影响你,这个分类器我们有封装好了的函数,MultinomialNB,这玩意儿获取训练集的权重矩阵和标签,进行训练,然后获取测试集的权重矩阵,进行预测(给出预测标签)。


    下面我们开始动手实践吧!


    首先,我们要把测试数据也映射到第4节中的那个TF-IDF词向量空间上:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: test.py
    @time: 2017/2/8 11:39
    @software: PyCharm
    """
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    # 引入Bunch类
    from sklearn.datasets.base import Bunch
    import cPickle as pickle
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    def _readfile(path):
        with open(path, "rb") as fp:
            content = fp.read()
        return content
    
    def _readbunchobj(path):
        with open(path, "rb") as file_obj:
            bunch = pickle.load(file_obj)
        return bunch
    
    def _writebunchobj(path, bunchobj):
        with open(path, "wb") as file_obj:
            pickle.dump(bunchobj, file_obj)
    
    def vector_space(stopword_path,bunch_path,space_path,train_tfidf_path):
    
        stpwrdlst = _readfile(stopword_path).splitlines()
        bunch = _readbunchobj(bunch_path)
        tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})
    
        #导入训练集的TF-IDF词向量空间
        trainbunch = _readbunchobj(train_tfidf_path)
        tfidfspace.vocabulary = trainbunch.vocabulary
    
        vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5,vocabulary=trainbunch.vocabulary)
        tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
        _writebunchobj(space_path, tfidfspace)
        print "if-idf词向量空间实例创建成功!!!"
    
    if __name__ == '__main__':
        stopword_path = "train_word_bag/hlt_stop_words.txt"#停用词表的路径
        bunch_path = "test_word_bag/test_set.dat"   # 词向量空间保存路径
        space_path = "test_word_bag/testspace.dat"   # TF-IDF词向量空间保存路径
        train_tfidf_path="train_word_bag/tfdifspace.dat"
        vector_space(stopword_path,bunch_path,space_path,train_tfidf_path)

    你已经发现了,这段代码与第4节几乎一模一样,唯一不同的就是在第39~41行中,我们导入了第4节中训练集的IF-IDF词向量空间,并且第41行将训练集的vocabulary赋值给测试集的vocabulary,第43行增加了入口参数vocabulary,原因在上一节中都已经说明,不再赘述。

    考虑到第4节和刚才的代码几乎完全一样,因此我们可以将这两个代码文件统一为一个:


    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: TFIDF_space.py
    @time: 2017/2/8 11:39
    @software: PyCharm
    """
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    from sklearn.datasets.base import Bunch
    import cPickle as pickle
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    def _readfile(path):
        with open(path, "rb") as fp:
            content = fp.read()
        return content
    
    def _readbunchobj(path):
        with open(path, "rb") as file_obj:
            bunch = pickle.load(file_obj)
        return bunch
    
    def _writebunchobj(path, bunchobj):
        with open(path, "wb") as file_obj:
            pickle.dump(bunchobj, file_obj)
    
    def vector_space(stopword_path,bunch_path,space_path,train_tfidf_path=None):
    
        stpwrdlst = _readfile(stopword_path).splitlines()
        bunch = _readbunchobj(bunch_path)
        tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})
    
        if train_tfidf_path is not None:
            trainbunch = _readbunchobj(train_tfidf_path)
            tfidfspace.vocabulary = trainbunch.vocabulary
            vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5,vocabulary=trainbunch.vocabulary)
            tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
    
        else:
            vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5)
            tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
            tfidfspace.vocabulary = vectorizer.vocabulary_
    
        _writebunchobj(space_path, tfidfspace)
        print "if-idf词向量空间实例创建成功!!!"
    
    if __name__ == '__main__':
    
        stopword_path = "train_word_bag/hlt_stop_words.txt"
        bunch_path = "train_word_bag/train_set.dat"
        space_path = "train_word_bag/tfdifspace.dat"
        vector_space(stopword_path,bunch_path,space_path)
    
        bunch_path = "test_word_bag/test_set.dat"
        space_path = "test_word_bag/testspace.dat"
        train_tfidf_path="train_word_bag/tfdifspace.dat"
        vector_space(stopword_path,bunch_path,space_path,train_tfidf_path)


    哇哦,你好棒!现在连注释都不用,就可以看懂代码了。。。

    对测试集进行了上述处理后,接下来的步骤,变得如此轻盈和优雅。


    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    """
    @version: python2.7.8 
    @author: XiangguoSun
    @contact: sunxiangguodut@qq.com
    @file: NBayes_Predict.py
    @time: 2017/2/8 12:21
    @software: PyCharm
    """
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    import cPickle as pickle
    from sklearn.naive_bayes import MultinomialNB  # 导入多项式贝叶斯算法
    
    
    # 读取bunch对象
    def _readbunchobj(path):
        with open(path, "rb") as file_obj:
            bunch = pickle.load(file_obj)
        return bunch
    
    # 导入训练集
    trainpath = "train_word_bag/tfdifspace.dat"
    train_set = _readbunchobj(trainpath)
    
    # 导入测试集
    testpath = "test_word_bag/testspace.dat"
    test_set = _readbunchobj(testpath)
    
    # 训练分类器:输入词袋向量和分类标签,alpha:0.001 alpha越小,迭代次数越多,精度越高
    clf = MultinomialNB(alpha=0.001).fit(train_set.tdm, train_set.label)
    
    # 预测分类结果
    predicted = clf.predict(test_set.tdm)
    
    for flabel,file_name,expct_cate in zip(test_set.label,test_set.filenames,predicted):
        if flabel != expct_cate:
            print file_name,": 实际类别:",flabel," -->预测类别:",expct_cate
    
    print "预测完毕!!!"
    
    # 计算分类精度:
    from sklearn import metrics
    def metrics_result(actual, predict):
        print '精度:{0:.3f}'.format(metrics.precision_score(actual, predict,average='weighted'))
        print '召回:{0:0.3f}'.format(metrics.recall_score(actual, predict,average='weighted'))
        print 'f1-score:{0:.3f}'.format(metrics.f1_score(actual, predict,average='weighted'))
    
    metrics_result(test_set.label, predicted)


    出错的这个,是我故意制造的,(因为实际分类精度100%,不能很好的说明问题)
    效果图:


    请注意,上面的截图中的结果,未必会跟你的一样。我之所以有这么高的准确率,一方面是把每个数据集做了精简的处理。另一方面是调试了TF-IDF的阈值。 

    当然,你也可以采用其他分类器,比如KNN


    6,评价与小结

    评价部分的实际操作我们已经在上一节的代码中给出了。这里主要是要解释一下代码的含义,以及相关的一些概念。

    截止目前,我们已经完成了全部的实践工作。接下来,你或许希望做的是:

    1,分词工具和分词算法的研究

    2,文本分类算法的研究

    这些内容,博主会在今后的时间里,专门研究并写出博文。


    整个工程的完整源代码到这里下载:

    https://github.com/sunxiangguo/chinese_text_classification

    需要说明的是,在工程代码和本篇博文中,细心的你已经发现了,我们所有的路径前面都有一个点“. /”,这主要是因为我们不知道您会将工程建在哪个路径内,因此这个表示的是你所在项目的目录,本篇博文所有路径都是相对路径。github代码有两个分支分别是master和python2.7分支。


    三,进一步的讨论

    我们的这些工作究竟实不实用?这是很多人关心的问题。事实上,本博文的做法,是最经典的文本分类思想。也是你进一步深入研究文本分类的基础。在实际工作中,用本文的方法,已经足够胜任各种情况了。

    那么,我们也许想问,有没有更好,更新的技术?答案是有的。未来,博主会集中介绍两种技术:
    1.利用LDA模型进行文本分类
    2.利用深度学习进行文本分类

    利用深度学习进行文本分类,要求你必须对深度学习的理论有足够多的掌握。
    为此,你可以参考博主的其他博文,
    例如下面的这个系列博文《 卷积神经网络CNN理论到实践》。
    这是一些列的博文。与网上其他介绍CNN的博文不同的是:
    1. 我们会全方位,足够深入的为你讲解CNN的知识。包括很多,你之前在网上找了很多资料也没搞清楚的东西。
    2. 我们会利用CNN做文本分类的实践。
    3. 我们会绘制大量精美的示意图。保证博文的高质量和美观。

    welcome!

    Xiangguo Sun 
    sunxiangguodut@qq.com 
    http://blog.csdn.net/github_36326955 

    Welcome to my blog column: Dive into ML/DL!

    (click here to blog column Dive into ML/DL)

    这里写图片描述

    I devote myself to dive into typical algorithms on machine learning and deep learning, especially the application in the area of  computational personality .

    My research interests include computational personality, user portrait, online social network, computational society, and ML/DL. In fact you can find the internal connection between these concepts: 

    这里写图片描述

    In this blog column, I will introduce some typical algorithms about machine learning and deep learning used in OSNs(Online Social Networks), which means we will include NLP, networks community, information diffusion,and individual recommendation systemApparently, our ultimate target is to dive into user portrait , especially the issues on your personality analysis.


    All essays are created by myself, and copyright will be reserved by me. You can use them for non-commercical intention and if you are so kind to donate me, you can scan the QR code below. All donation will be used to the library of charity for children in Lhasa.


    赏金将用于拉萨儿童图书公益募捐
    社会公益,听IT人的声音

    手机扫一扫,即可: 

    附:《春天里,我们的拉萨儿童图书馆,需要大家的帮助


    click here to blog column Dive into ML/DL

    展开全文
  • fastText原理和文本分类实战,看这一篇就够了

    万次阅读 多人点赞 2019-03-19 11:19:48
    fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点: 1、fastText在保持高精度的情况下加快了训练速度和测试速度 2、fastText不需要预训练好的词向量,fastText会自己训练词向量 3、fastText...

    前言:若需获取本文全部的手书版原稿资料,扫码关注公众号,回复: FastText 即可获取。

    原创不易,转载请告知并注明出处!扫码关注公众号【机器学习与自然语言处理】,定期发布知识图谱,自然语言处理、机器学习等知识,添加微信号【17611428102】进讨论群,加好友时备注来自CSDN。
    机器学习与自然语言处理

    Word2vec, Fasttext, Glove, Elmo, Bert, Flair pre-train Word Embedding源码+数据Github网址: 词向量预训练实现Github


    fastText原理篇

    一、fastText简介

    fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点:
    1、fastText在保持高精度的情况下加快了训练速度和测试速度
    2、fastText不需要预训练好的词向量,fastText会自己训练词向量
    3、fastText两个重要的优化:Hierarchical Softmax、N-gram

    二、fastText模型架构

    fastText模型架构和word2vec中的CBOW很相似, 不同之处是fastText预测标签而CBOW预测的是中间词,即模型架构类似但是模型的任务不同。下面我们先看一下CBOW的架构:
    在这里插入图片描述
    word2vec将上下文关系转化为多分类任务,进而训练逻辑回归模型,这里的类别数量|V|词库大小。通常的文本数据中,词库少则数万,多则百万,在训练中直接训练多分类逻辑回归并不现实。word2vec中提供了两种针对大规模多分类问题的优化手段, negative sampling 和hierarchical softmax。在优化中,negative sampling 只更新少量负面类,从而减轻了计算量。hierarchical softmax 将词库表示成前缀树,从树根到叶子的路径可以表示为一系列二分类器,一次多分类计算的复杂度从|V|降低到了树的高度

    fastText模型架构:其中x1,x2,…,xN−1,xN表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的cbow相似,cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别
    在这里插入图片描述

    三、层次softmax

    softmax函数常在神经网络输出层充当激活函数,目的就是将输出层的值归一化到0-1区间,将神经元输出构造成概率分布,主要就是起到将神经元输出值进行归一化的作用,下图展示了softmax函数对于输出值z1=3,z2=1,z3=-3的归一化映射过程
    在这里插入图片描述
    在标准的softmax中,计算一个类别的softmax概率时,我们需要对所有类别概率做归一化,在这类别很大情况下非常耗时,因此提出了分层softmax(Hierarchical Softmax),思想是根据类别的频率构造霍夫曼树来代替标准softmax,通过分层softmax可以将复杂度从N降低到logN,下图给出分层softmax示例:
    在这里插入图片描述
    在层次softmax模型中,叶子结点的词没有直接输出的向量,而非叶子节点都有响应的输在在模型的训练过程中,通过Huffman编码,构造了一颗庞大的Huffman树,同时会给非叶子结点赋予向量。我们要计算的是目标词w的概率,这个概率的具体含义,是指从root结点开始随机走,走到目标词w的概率。因此在途中路过非叶子结点(包括root)时,需要分别知道往左走和往右走的概率。例如到达非叶子节点n的时候往左边走和往右边走的概率分别是:
    在这里插入图片描述
    以上图中目标词为w2为例,
    在这里插入图片描述
    到这里可以看出目标词为w的概率可以表示为:
    在这里插入图片描述
    其中θn(w,j)是非叶子结点n(w,j)的向量表示(即输出向量);h是隐藏层的输出值,从输入词的向量中计算得来;sign(x,j)是一个特殊函数定义
    在这里插入图片描述
    此外,所有词的概率和为1,即
    在这里插入图片描述
    最终得到参数更新公式为:
    在这里插入图片描述

    四、N-gram特征

    n-gram是基于语言模型的算法,基本思想是将文本内容按照子节顺序进行大小为N的窗口滑动操作,最终形成窗口为N的字节片段序列。而且需要额外注意一点是n-gram可以根据粒度不同有不同的含义,有字粒度的n-gram和词粒度的n-gram,下面分别给出了字粒度和词粒度的例子:
    在这里插入图片描述
    在这里插入图片描述
    对于文本句子的n-gram来说,如上面所说可以是字粒度或者是词粒度,同时n-gram也可以在字符级别工作,例如对单个单词matter来说,假设采用3-gram特征,那么matter可以表示成图中五个3-gram特征,这五个特征都有各自的词向量,五个特征的词向量和即为matter这个词的向其中“<”和“>”是作为边界符号被添加,来将一个单词的ngrams与单词本身区分开来:
    在这里插入图片描述
    从上面来看,使用n-gram有如下优点
    1、为罕见的单词生成更好的单词向量:根据上面的字符级别的n-gram来说,即是这个单词出现的次数很少,但是组成单词的字符和其他单词有共享的部分,因此这一点可以优化生成的单词向量
    2、在词汇单词中,即使单词没有出现在训练语料库中,仍然可以从字符级n-gram中构造单词的词向量
    3、n-gram可以让模型学习到局部单词顺序的部分信息, 如果不考虑n-gram则便是取每个单词,这样无法考虑到词序所包含的信息,即也可理解为上下文信息,因此通过n-gram的方式关联相邻的几个词,这样会让模型在训练的时候保持词序信息

    但正如上面提到过,随着语料库的增加,内存需求也会不断增加,严重影响模型构建速度,针对这个有以下几种解决方案:
    1、过滤掉出现次数少的单词
    2、使用hash存储
    3、由采用字粒度变化为采用词粒度



    fastText实战篇

    fastText实战篇来自对fastText官方文档的翻译,官网网址为:fasttext学习官网,英文阅读能力好的强烈建议直接读原文,下面翻译可以提供给不想读英文文档的读者,翻译能力有限,有错请指正!

    一、Fasttext介绍

    1、什么是fastText

    fastText是一个高效学习单词表示和句子分类

    2、fastText环境要求

    fastText需要运行在Mac OS或Linux上,因为fastText使用了C++11,因此需要很好支持C++11的编译器,支持的编译器包括:
    (1) gcc-4.6.3 或者更新版本
    (2) clang-3.3 或者更新版本

    编译是使用Makefile执行的,因此你需要有一个工作的make,对于单词相似度评估脚本则需要如下环境:
    (1) python2.6 或者更新
    (2) numpy 和 spicy

    3、在本地快速搭建fastText

    为了搭建fastText,打开命令窗口依次执行以下命令:

    $ git clone https://github.com/facebookresearch/fastText.git
    $ cd fastText
    $ make
    

    上述命令将为所有类和主二进制fastText生成目标文件,如果你不打算使用默认的系统范围编译器,可以更新Makefile(CC和include)开头定义的两个宏

    二、fastText教程-文本分类

    文本分类对许多应用来说都是一个核心问题,例如:垃圾邮件分类、情感分析以及智能问答等。在此教程中,详细阐述通过fastText如何搭建一个文本分类模型

    1、什么是文本分类

    文本分类的目的是将文档(例如电子邮件、帖子、文本消息,产品评论等)分给一个或多个类别,表示这些类别可以是评价分数,垃圾邮件、非垃圾邮件,或者是文档所用的语言。目前,构建此类分类器最主要的方法是机器学习,机器学习方法从实例中学习分类规则,为了构建分类器,我们需要带标签的数据,标签数据指的数据包括文档和此文档所对应的类别(或称标记或标签),例如,我们可以构建一个分类器,该分类器将cooking自动分为几个标签如:pot、bowl、baking

    2、安装fastText

    首先我们需要做的便是安装搭建fastText,需要系统支持c++ 11的c++编译器,先从GitHub上下载fastText到本地(版本在更新,可以到GitHub上查看最近版本进行下载):

    $ wget https://github.com/facebookresearch/fastText/archive/v0.1.0.zip
    

    然后将下载的zip文件夹进行解压,解压后进入目录对fastText项目执行make命令进行编译(因此这里便需要你的系统有支持c++11的编译器)

    $ unzip v0.1.0.zip
    $ cd fastText-0.1.0
    $ make
    

    在根目录下运行名为fasttext的二进制文件,便会打印出fastText支持的各种不同的命令,如:supervised进行模型训练,quantize量化模型以减少内存使用,test进行模型测试,predict预测最可能的标签等,运行结果如下所示:

    >> ./fasttext
    usage: fasttext <command> <args>
    
    The commands supported by fasttext are:
    
      supervised              train a supervised classifier
      quantize                quantize a model to reduce the memory usage
      test                    evaluate a supervised classifier
      predict                 predict most likely labels
      predict-prob            predict most likely labels with probabilities
      skipgram                train a skipgram model
      cbow                    train a cbow model
      print-word-vectors      print word vectors given a trained model
      print-sentence-vectors  print sentence vectors given a trained model
      nn                      query for nearest neighbors
      analogies               query for analogies
      
    
    上述的命令包括:
    supervised: 训练一个监督分类器
    quantize:量化模型以减少内存使用量
    test:评估一个监督分类器
    predict:预测最有可能的标签 
    predict-prob:用概率预测最可能的标签
    skipgram:训练一个 skipgram 模型
    cbow:训练一个 cbow 模型
    print-word-vectors:给定一个训练好的模型,打印出所有的单词向量
    print-sentence-vectors:给定一个训练好的模型,打印出所有的句子向量
    nn:查询最近邻居
    analogies:查找所有同类词
    

    在本节fastText文本分类中,我们主要使用SUPERVISED、TEST和PREDICT命令,在下一小节中我们主要介绍FASTTEXT关于学习单词向量的模型

    3、获取数据及数据预处理

    正如上面所说,我们需要带有标签的数据去训练我们的监督学习的分类器,本教程中,我们使用cooking相关数据构建我们的分类器,因此首先我们下载数据,数据网址为stackexchange,进行如下命令操作:

    >> wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz
    >> tar xvzf cooking.stackexchange.tar.gz
    >> head cooking.stackexchange.txt
    

    通过head命令便可看到文档形式,文档的每一行都包含一个标签,标签后面跟着相应的单词短语,所有的标签都以__label__前缀开始,这事fastText便是标签和单词短语的方式,训练的模型便是预测文档中给定单词短语预测其对应的标签

    在训练分类器之前,我们需要将数据分割成训练集和验证集,我们将使用验证集来评估学习到的分类器对新数据的性能好坏,先通过下面命令来查看文档中总共含有多少数据:

    >> wc cooking.stackexchange.txt 
       15404  169582 1401900 cooking.stackexchange.txt
    

    可以看到我们数据中总共包含了15404个示例,我们把文档分成一个包含12404个示例的训练集和一个包含3000个示例的验证集,执行如下命令:

    >> head -n 12404 cooking.stackexchange.txt > cooking.train
    >> tail -n 3000 cooking.stackexchange.txt > cooking.valid
    
    4、使用fastText快速搭建分类器

    上面数据已经准备好了,接下来我们便开始训练我们的模型,首先执行如下命令进行模型的训练:

    >> ./fasttext supervised -input cooking.train -output model_cooking
    Read 0M words
    Number of words:  14598
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 75109  lr: 0.000000  loss: 5.708354  eta: 0h0m 
    

    -input命令选项指示训练数据,-output选项指示的是保存的模型的位置,在训练结束后,文件model_cooking.bin是在当前目录中创建的,model_cooking.bin便是我们保存训练模型的文件

    模型训练好之后,我们可以交互式测试我们的分类器,即单独测试某一个句子所属的类别,可以通过以下命令进行交互式测试:

    >> ./fasttext predict model_cooking.bin -
    

    输入以上命令后,命令行会提示你输入句子,然后我们可以进行如下句子测试:

    Which baking dish is best to bake a banana bread ?

    上面句子可以得到预测的标签是baking,显然这个预测结果是正确的,我们再进行尝试

    Why not put knives in the dishwasher?

    上面句子预测的标签是food-safety,可以看出是不相关的,显然预测的不正确,为了验证学习到的分类模型的好坏,我们在验证集上对它进行测试,观察模型的精准率precision和召回率recall:

    >> ./fasttext test model_cooking.bin cooking.valid                 
    N  3000
    P@1  0.124
    R@1  0.0541
    Number of examples: 3000
    
    5、精准率Precision和召回率Recall

    精准率Precision指的是预测为正样本中有多少是真正的正样本,召回率Recall指的是样本中的正样本有多少被预测正确了,因此精准率看的是预测为某一类的样本中有多少是真正的属于这一类的,而召回率看的是在分类任务中某一类样本是否完全被预测正确,下面通过一个例子来更清楚的认识这个概念,以下面句子为例:

    Why not put knives in the dishwasher?

    上面句子的正式标签有三个,分别是:equipment, cleaning and knives

    然后我们通过模型对上面句子进行预测,执行如下命令:

    >> ./fasttext predict model_cooking.bin - 5
    

    预测得到的结果分别是:food-safety, baking, equipment, substitutions, bread

    可以看出五个预测的标签中只预测正确了一个标签equipment,我们来看,预测的样本中正确的样本所占的比例即是精准率,因此精准率为1/5=0.2;而真实标签中有多少预测正确了即是召回率,因此召回率为1/3=0.33,这样我们应该能明白精准率和召回率的概念了,想更加详细的了解精准率和召回率,请参考维基百科精准率和召回率

    6、模型优化

    上面通过使用默认参数运行fastText训练得到的模型在分类新问题上效果很差,接下来我们通过更改默认参数来提高性能

    (1) 方案一:数据预处理

    查看数据,我们发现有些单词包含大写字母和标点符号,因此改善模型性能的第一步就是应用一些简单的预处理,预处理可以使用命令行工具例如sed、tr来对文本进行简单的标准化操作,执行命令如下:

    >> cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
    >> head -n 12404 cooking.preprocessed.txt > cooking.train
    >> tail -n 3000 cooking.preprocessed.txt > cooking.valid 
    

    接下来我们在预处理的数据集上进行模型训练并进行测试,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 82041  lr: 0.000000  loss: 5.671649  eta: 0h0m h-14m 
    
    >> ./fasttext test model_cooking.bin cooking.valid 
    N  3000
    P@1  0.164
    R@1  0.0717
    Number of examples: 3000
    

    观察上面的结果,由于对数据预处理,词典变小了,由原来的14K个单词变成了9K,精准率也上升了4%,因此数据预处理起到了一定的效果

    (2) 方案二:更多的训练次数和更大的学习率

    在默认情况下,fastText在训练期间对每个训练用例仅重复使用五次,这太小,因为我们的训练集只有12k训练样例,因此我们可以通过-epoch选项增加每个样例的使用次数,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -epoch 25 
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 77633  lr: 0.000000  loss: 7.147976  eta: 0h0m
    

    然后测试模型查看效果:

    >> ./fasttext test model_cooking.bin cooking.valid                                        
    N  3000
    P@1  0.501
    R@1  0.218
    Number of examples: 3000
    

    从上面测试效果可以看出,精准率和召回率都有了大幅度提升,可见增加每个样例的使用次数对于数据集少的情况下效果提升明显。另一个增强算法能力是改变模型的学习速度即学习速率,这对应于处理每个示例后模型的更改程度,当学习率为0时意味着模型根本不会发生改变,因此不会学到任何东西,良好的学习率值在0.1-1.0的范围内,下面我们通过设置算法学习率为learning rate = 1.0进行模型训练:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0  
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 81469  lr: 0.000000  loss: 6.405640  eta: 0h0m
    
    >> ./fasttext test model_cooking.bin cooking.valid                         
    N  3000
    P@1  0.563
    R@1  0.245
    Number of examples: 3000
    

    可以看到效果比上面增加epoch还要好,下面我们来将二者结合起来:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 76394  lr: 0.000000  loss: 4.350277  eta: 0h0m
    
    >> ./fasttext test model_cooking.bin cooking.valid                                   
    N  3000
    P@1  0.585
    R@1  0.255
    Number of examples: 3000
    

    下面我们来增加一些新的方式来进一步提升模型的性能,看方案三

    (3) 方案三:word n-grams

    此方案中,我们使用单词bigrams而不是仅仅是unigrams来提高模型的性能,这对于词序很重要的分类问题尤其重要,例如情感分析。n-gram是基于语言模型的算法,基本思想是将文本内容按照子节顺序进行大小为N的窗口滑动操作,最终形成窗口为N的字节片段序列。训练模型命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 75366  lr: 0.000000  loss: 3.226064  eta: 0h0m 
    
    >> ./fasttext test model_cooking.bin cooking.valid                                                 
    N  3000
    P@1  0.599
    R@1  0.261
    Number of examples: 3000
    

    通过几个步骤,可以看出我们将模型精准率从12.4%提升到了59.9%,总结一下主要包含以下步骤:
    (1) 数据预处理
    (2) 更改样本训练次数epochs(使用参数 –epoch,标准范围[5, 50])
    (3) 更改学习率learning rate(使用参数 –lr,标准范围[0.1-1])
    (4) 使用word n-grams(使用参数 –wordNgrams,标准范围[1-5])

    7、什么是Bigram

    unigram指的是单个不可分割的单元和标记,通常用做模型的输入,并且在不同的模型中unigram可以是单词或是字母,在fastText中,我们是在单词级别上进行训练模型,因此unigram是单词。类似的,bigram值的是两个连续的单词的串联,n-grams指的便是n个单词的串联。举个例子,现在有这样一句话:Last donut of the night,如果是unigrams则是last,donut,of,the,night,而对于bigrams指的是last donut,donut of,of the,the night

    8、提升训练速度

    目前我们在几千个示例中训练我们的模型,训练只需要几秒钟,但如果数据集增大,标签增多,这时模型训练便会变慢,一个让训练变快的方案便是使用分层softmax,而不是使用常规softmax,使用分层softmax是使用参数 –loss hs实现,命令如下:

    >> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2 -bucket 200000 -dim 50 -loss hs
    Read 0M words
    Number of words:  9012
    Number of labels: 734
    Progress: 100.0%  words/sec/thread: 2199406  lr: 0.000000  loss: 1.718807  eta: 0h0m 
    

    此时对于我们当前的数据集,训练速度应该不超过1秒

    9、总结

    本教程中我们简单介绍了如何使用fastText来训练强大的分类器,同时介绍了一些重要的参数选项,通过调参来进行模型优化


    三、fastText教程-单词表示词向量

    现在机器学习中一个十分流行的做法便是用向量表示单词,即词向量化wordEmbedding,这些向量可以捕捉到有关语言的一些隐藏信息,例如语法信息,语义信息等,好的词向量表示可以提升分类器的性能,在本教程中,我们展示如何使用fastText工具来构建词向量,安装fastText过程请参考上一讲

    1、获取数据

    为了计算词向量,我们需要一个大的文本语料库,根据语料库的不同,单词向量也将捕捉到不同的信息,在本教程中,我们关注Wikipedia的文章,当然也可以考虑其他语料库来源,例如新闻活着Webcrawl,下载Wikipedia语料库执行如下命令:

    wget https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
    

    下载Wikipedia语料库需要挺长时间,如果不使用Wikipedia全部语料库信息,我们可以在Wikipedia前10亿字节信息进行词向量学习,此数据可以在Matt Mahoney网站上下载

    $ mkdir data
    $ wget -c http://mattmahoney.net/dc/enwik9.zip -P data
    $ unzip data/enwik9.zip -d data
    

    这样我们便获得了Wikipedia的部分数据,因为Wikipedia语料库中包含大量的HTML/XML数据,因此需要对数据进行预处理,我们可以使用与fastText自带的wikifil.pl脚本对其进行预处理,这个脚本最初由Matt Mahoney创建,因此可以在下面网址上找到:http://mattmahoney.net/,执行如下命令对数据进行预处理:

    $ perl wikifil.pl data/enwik9 > data/fil9
    

    我们可以执行如下命令检查我们的文件数据:

    $ head -c 80 data/fil9
    anarchism originated as a term of abuse first used against early working class
    

    可以观察到我们的文本经过了很好的处理,接下来可以用文本来学习词向量

    2、训练词向量

    数据集已经取到了,现在我们可以使用如下的简单命令在上述数据集上训练我们的词向量

    $ mkdir result
    $ ./fasttext skipgram -input data/fil9 -output result/fil9
    

    分解上述命令:./fasttext使用skipgram模型调用二进制fastText可执行文件,当然也可以使用cbow模型,-input表示输入数据路径,-output表示训练的词向量模型所在路径,当fastText运行时,屏幕会显示进度和估计的完成时间,程序完成后,结果目录应该出现如下两个文件,可通过下面命令查看:

    $ ls -l result
    -rw-r-r-- 1 bojanowski 1876110778 978480850 Dec 20 11:01 fil9.bin
    -rw-r-r-- 1 bojanowski 1876110778 190004182 Dec 20 11:01 fil9.vec
    

    fil9.bin文件是一个二进制文件,它存储了整个fastText模型,随后可以进行加载,fil9.vec文件是一个包含单词向量的文本文件,每一行对应词汇表中的每个单词,可通过如下命令查看fil9.vec中的信息

    $ head -n 4 result/fil9.vec
    218316 100
    the -0.10363 -0.063669 0.032436 -0.040798 0.53749 0.00097867 0.10083 0.24829 ...
    of -0.0083724 0.0059414 -0.046618 -0.072735 0.83007 0.038895 -0.13634 0.60063 ...
    one 0.32731 0.044409 -0.46484 0.14716 0.7431 0.24684 -0.11301 0.51721 0.73262 ...
    

    从上面结果可见,第一行显示的是单词向量和向量维度,接下来几行是词汇表中所有单词的单词向量,顺序是按照频率降低的顺序进行排序

    3、skipgram VS cbow

    fastText为计算单词表示提供了两种模型:skipgram和cbow,这和word2vec一样,cbow全称:Continuous-bag-of-words,skipgram模型运行机理是通过附近的词来预测目标单词,而cbow模型则是根据目标词的上下文来预测目标词,这里的上下文指的便是目标词周围的固定大小窗口中包含的单词包,下面通过例子便能够体会到上下文的含义。例如:给出这样一个句子:

    Poets have been mysteriously silient on the subject of cheese

    其目标词是slient,skipgram模型是通过目标词附近的词去预测slient,例如subjector, mysteriously, 而cbow模型则是通过目标词的上下文词来预测slient,如:{been, mysteriously, on, the},并且使用单词的向量预测目标,下面一个示例图展示了二者的差异,使用的句子是

    I am selling these fine leather jackets

    在这里插入图片描述

    上面已经使用skipgram模型对数据集进行了训练,如果想用cbow模型训练之行如下命令

    ./fasttext cbow -input data/fil9 -output result/fil9
    

    从实际效果中看,我们会发现skipgram模型对于单词信息的处理效果要优于cbow模型

    4、模型参数调优

    上面的训练都是使用的默认的参数运行fastText,但根据数据的不同,这些参数可能不是最优的,让我们介绍一下子向量的一些关键参数。

    模型中最重要的两个参数是:词向量大小维度、subwords范围的大小,词向量维度越大,便能获得更多的信息但同时也需要更多的训练数据,同时如果它们过大,模型也就更难训练速度更慢,默认情况下使用的是100维的向量,但在100-300维都是常用到的调参范围。subwords是一个单词序列中包含最小(minn)到最大(maxn)之间的所有字符串(也即是n-grams),默认情况下我们接受3-6个字符串中间的所有子单词,但不同的语言可能有不同的合适范围

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -minn 2 -maxn 5 -dim 300
    

    下面介绍另外两个参数:epoch、learning rate、epoch根据训练数据量的不同,可以进行更改,epoch参数即是控制训练时在数据集上循环的次数,默认情况下在数据集上循环5次,但当数据集非常大时,我们也可以适当减少训练的次数,另一个参数学习率,学习率越高模型收敛的速度就越快,但存在对数据集过度拟合的风险,默认值时0.05,这是一个很好的折中,当然在训练过程中,也可以对其进行调参,可调范围是[0.01, 1],下面命令便尝试对这两个参数进行调整:

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -epoch 1 -lr 0.5
    

    最后fastText是多线程的,默认情况下使用12个线程,如果你的机器只有更少的CPU核数,也可以通过如下参数对使用的CPU核数进行调整

    $ ./fasttext skipgram -input data/fil9 -output result/fil9 -thread 4
    
    5、打印词向量

    直接从fil9.vec文件中搜索和打印词向量是十分麻烦的,但幸运的是fastText提供了打印词向量的功能,我们可以通过fastText中print-word-vectors功能打印词向量,例如,我们可以使用以下命令打印单词asparagus、pidgey和yellow单词的词向量:

    $ echo "asparagus pidgey yellow" | ./fasttext print-word-vectors result/fil9.bin
    asparagus 0.46826 -0.20187 -0.29122 -0.17918 0.31289 -0.31679 0.17828 -0.04418 ...
    pidgey -0.16065 -0.45867 0.10565 0.036952 -0.11482 0.030053 0.12115 0.39725 ...
    ·0.040719 -0.30155 ...
    

    一个很好的功能是我们可以查询到未出现在数据中的单词,实际上,单词是由字符串的总和组成,只要未知的单词是由已知的字串构成,就可以得到单词的词向量,举个例子下面尝试一下查询拼写出错的单词:

    $ echo "enviroment" | ./fasttext print-word-vectors result/fil9.bin
    

    结果仍然可以查询到词向量,但是至于效果怎么样,我们可以在下一节找到答案

    6、临近词向量查询

    检查单词向量质量的一种简单的方法是查看此此单词的临近词,可以通过临近词比较来查看词向量对于语义的表达。最临近词向量查询可以通过fastText提供的nn功能来实现,例如我们可以通过运行一下命令来查询单词10个最近邻居:

    $ ./fasttext nn result/fil9.bin
    Pre-computing word vectors... done.
    

    然后命令行便会提示我们输入需要查询的词,我们尝试一下asparagus

    Query word? asparagus
    beetroot 0.812384
    tomato 0.806688
    horseradish 0.805928
    spinach 0.801483
    licorice 0.791697
    lingonberries 0.781507
    asparagales 0.780756
    lingonberry 0.778534
    celery 0.774529
    beets 0.773984
    

    从上面结果可以看出效果不错,查询词之间由很大的共性,再尝试查询pidgey,结果如下

    Query word? pidgey
    pidgeot 0.891801
    pidgeotto 0.885109
    pidge 0.884739
    pidgeon 0.787351
    pok 0.781068
    pikachu 0.758688
    charizard 0.749403
    squirtle 0.742582
    beedrill 0.741579
    charmeleon 0.733625
    

    上面提到了如果单词拼写出错可能影响词向量的查询,那如果单词拼写错误,如果查询其临近词结果如何,下面展示一下效果:

    Query word? enviroment
    enviromental 0.907951
    environ 0.87146
    enviro 0.855381
    environs 0.803349
    environnement 0.772682
    enviromission 0.761168
    realclimate 0.716746
    environment 0.702706
    acclimatation 0.697196
    ecotourism 0.697081
    

    可以看出虽然单词拼写出错,但是查询结果还是捕获到了单词的主要信息,拼写出错的单词也与合理的单词匹配,虽然还是有一些影响,但整体方向是正确的。

    为了找到词向量临近的单词,我们需要计算的单词之间的相似度得分。模型训练的单词是由连续的单词向量表示,因此我们可以对其进行相似度的比较,一般情况下,我们使用余弦相似度去衡量两个单词之间的相似度,我们可以计算词汇表中任意单词和所有其他单词之间的相似度,并显示10个最相似单词,当然被查询单词本身肯定排在顶部,相似度为1

    7、单词类比

    在相似度问题中,有时会进行单词类比,例如我们训练的模型能够知道法国是什么,并且知道柏林对于德国来说意味着什么。这个在fastText中是可以做到的,利用单词类比这个功能即可实现,例如下面我们输入三个单词,然后输出单词的类比单词:

    $ ./fasttext analogies result/fil9.bin
    Pre-computing word vectors... done.
    Query triplet (A - B + C)? berlin germany france
    paris 0.896462
    bourges 0.768954
    louveciennes 0.765569
    toulouse 0.761916
    valenciennes 0.760251
    montpellier 0.752747
    strasbourg 0.744487
    meudon 0.74143
    bordeaux 0.740635
    pigneaux 0.736122
    

    上面模型类比功能提供的最可能结果是巴黎,显然是十分准确,下面我们再来看一个不太明显的例子:

    Query triplet (A - B + C)? psx sony nintendo
    gamecube 0.803352
    nintendogs 0.792646
    playstation 0.77344
    sega 0.772165
    gameboy 0.767959
    arcade 0.754774
    playstationjapan 0.753473
    gba 0.752909
    dreamcast 0.74907
    famicom 0.745298
    

    从上面结果可以看出模型认为psx是索尼的游戏手柄,因此nintendo任天堂类比的是gamecube,这个类比也比较合理。当然类比的质量也取决于训练模型的数据集,类比的结果也仅仅在数据集的范围内

    8、 字符n-grams重要性

    利用subword-level信息也即是n-grams对于构建未知单词词向量很有趣,例如Wikipedia中不存在gearshift这个单词,但是我们仍然能够查询到它的临近单词:

    Query word? gearshift
    gearing 0.790762
    flywheels 0.779804
    flywheel 0.777859
    gears 0.776133
    driveshafts 0.756345
    driveshaft 0.755679
    daisywheel 0.749998
    wheelsets 0.748578
    epicycles 0.744268
    gearboxes 0.73986
    

    效果还可以,因为大多数被检索到的单词共享大量的子串,当然也有些特殊的单词比较特殊,例如cogwheel,我们可以看到subword-level对于未知单词查询所起到的效果,但是如果我们在训练模型的时候没有使用subwords这个参数,结果会如何,下面我们便进行尝试,运行以下命令训练没有subwords的模型:

    $ ./fasttext skipgram -input data/fil9 -output result/fil9-none -maxn 0
    

    此时训练的模型保存在result/fil9-non.vec和result/fil9-non.bin,为了表明不加subwords模型的不同,我们再举一个wikipedia中不常见的单词如:accomodation,就类似于accommodation住宿这个单词,下面给出其相似词的查询结果:

    $ ./fasttext nn result/fil9-none.bin
    Query word? accomodation
    sunnhordland 0.775057
    accomodations 0.769206
    administrational 0.753011
    laponian 0.752274
    ammenities 0.750805
    dachas 0.75026
    vuosaari 0.74172
    hostelling 0.739995
    greenbelts 0.733975
    asserbo 0.732465
    

    可以看出结果中的词没有任何意义,大多数词都是不想关的,我们再用使用了subwords的模型测试accomodation的相似词,结果便有明显的差别:

    Query word? accomodation
    accomodations 0.96342
    accommodation 0.942124
    accommodations 0.915427
    accommodative 0.847751
    accommodating 0.794353
    accomodated 0.740381
    amenities 0.729746
    catering 0.725975
    accomodate 0.703177
    hospitality 0.701426
    

    上面结果准确捕捉到相似度很高的accommodation这个单词,同时我们还捕获到语义相关的词如:便利设施amenities和寄宿lodging,因此训练模型加上subwords参数对模型效果有很大的提升

    9、 结论

    在小节中,详细展示了如果在wikipedia上获得词向量,对于其他语言也都可以同样运行,下面网址提供了fastText在词向量上的多个预训练模型,可以参考使用预训练模型网址


    四、常用命令备忘录

    词向量的学习-使用fastText学习词向量执行以下命令:

    $ ./fasttext skipgram -input data.txt -output model
    

    取得词向量-将模型学习得词向量打印到文件中执行如下命令:

    $ ./fasttext print-word-vectors model.bin < queries.txt
    

    文本分类-训练一个文本分类模型执行如下命令:

    $ ./fasttext supervised -input train.txt -output model
    

    当一个模型训练结束后,我们可以通过在测试集上计算精准率Precision和召回率Recall进行模型评估,执行如下命令:

    $ ./fasttext test model.bin test.txt 1
    

    为了直接预测一段文本最可能的k个标签,执行如下命令:

    $ ./fasttext predict model.bin test.txt k
    

    为了直接预测一段文本的k个最可能的标签及其相关概率大小,可以执行如下命令:

    $ ./fasttext predict-prob model.bin test.txt k
    

    如果想要计算句子或段落的向量表示,执行如下命令:

    $ ./fasttext print-sentence-vectors model.bin < text.txt
    

    为了创建一个内存更小的模型可以执行如下命令

    $ ./fasttext quantize -output model
    

    所有其他的命令都类似下面test命令

    $ ./fasttext test model.ftz test.txt
    

    五、模型可选参数列表及默认值

    $ ./fasttext supervised
    Empty input or output path.
    
    The following arguments are mandatory:
      -input              training file path
      -output             output file path
    
      The following arguments are optional:
      -verbose            verbosity level [2]
    
      The following arguments for the dictionary are optional:
      -minCount           minimal number of word occurrences [5]
      -minCountLabel      minimal number of label occurrences [0]
      -wordNgrams         max length of word ngram [1]
      -bucket             number of buckets [2000000]
      -minn               min length of char ngram [3]
      -maxn               max length of char ngram [6]
      -t                  sampling threshold [0.0001]
      -label              labels prefix [__label__]
    
      The following arguments for training are optional:
      -lr                 learning rate [0.05]
      -lrUpdateRate       change the rate of updates for the learning rate [100]
      -dim                size of word vectors [100]
      -ws                 size of the context window [5]
      -epoch              number of epochs [5]
      -neg                number of negatives sampled [5]
      -loss               loss function {ns, hs, softmax} [ns]
      -thread             number of threads [12]
      -pretrainedVectors  pretrained word vectors for supervised learning []
      -saveOutput         whether output params should be saved [0]
    
      The following arguments for quantization are optional:
      -cutoff             number of words and ngrams to retain [0]
      -retrain            finetune embeddings if a cutoff is applied [0]
      -qnorm              quantizing the norm separately [0]
      -qout               quantizing the classifier [0]
      -dsub               size of each sub-vector [2]
    

    默认值可能因模型不同,例如单词表示模型skip gram和cbow使用默认的minCount为5


    六、fastText中常见问题汇总

    1、什么是fastText

    fastText是一个用于文本分类和词向量表示的库,它能够把文本转化成连续的向量然后用于后续具体的语言任务,目前教程较少!

    2、为什么训练的模型非常大

    fastText对字和字符串使用hash表,hash表的大小将直接影响模型的大小,可以通过选项-hash来减少词汇hash表的大小,一个可选的好参数时20000。另一个影响模型大小重要的因素是训练向量的维度大小(-dim),如果维度缩小模型将大大减小,但同时也会很大程度影响模型的性能,因为向量维度越大则捕获的信息越多,当然还有一种将模型变小的方法是使用量化选项(-quantize),命令如下所示:

    ./fasttext quantize -output model
    
    3、模型中使用单词短语而不是单个单词最佳方式是什么

    目前使用单词短语或句子最好的方式是使用词向量的bow(bag of words),另一种方式例如New York,我们可以将其处理成New_York也会有帮助

    4、为什么fastText甚至可以为语料库中未出现的单词产生词向量

    fastText一个重要的特性便是有能力为任何单词产生词向量,即使是未出现的,组装的单词。主要是因为fastText是通过包含在单词中的子字符substring of character来构建单词的词向量,正文中也有论述,因此这种训练模型的方式使得fastText可以为拼写错误的单词或者连接组装的单词产生词向量

    5、为什么分层softmax在效果上比完全softmax略差

    分层softmax是完全softmax的一个近似,分层softmax可以让我们在大数据集上高效的建立模型,但通常会以损失精度的几个百分点为代价,

    6、可以在GPU上运行fastText项目吗

    目前fastText仅仅可运行在CPU上,但这也是其优势所在,fastText的目的便是要成为一个高效的CPU上的分类模型,可以允许模型在没有CPU的情况下构建

    7、可以使用python语言或者其他语言使用fastText嘛

    目前在GitHub上有很少的关于fastText的其他语言实现的非官方版本,但可以负责任的说,是可以用tensorflow实现的

    8、可以在连续的数据集上使用fastText吗

    不可以,fastText仅仅是用于离散的数据集,因此无法直接在连续的数据集上使用,但是可以将连续的数据离散化后使用fastText

    9、数据中存在拼写错误,我们需要对文本进行规范化处理吗

    如果出现的频率不高,没有必要,对模型效果不会有什么影响

    10、在模型训练时遇到了NaN,为什么会这样

    这种现象是可能出现的,很大原因是因为你的学习率太高了,可以尝试降低一下学习率直到不再出现NaN

    11、系统无法编译fastText,怎么处理

    尝试更新一下编译器版本,很大可能就是因为编译器太旧了

    12、如何完全重现fastText的运行结果,为什么每次运行的结果都有些差异

    当多次运行fastText时,因为优化算法异步随机梯度下降算法或Hogwild,所以每次得到的结果都会略有不同,如果想要fastText运行结果复现,则必须将参数thread设置为1,这样你就可以在每次运行时获得完成相同的性能

    展开全文
  • 卷积神经网络文本分类

    万次阅读 2018-03-24 10:14:23
    卷积神经网络(CNN)在图像处理领域取得了很大的成绩,它的卷积和池化结构能很好提取图像的信息,而在 NLP 领域循环神经网络(RNN)则使用的更多,RNN 及其各种变种因拥有记忆功能使得它们更擅长处理上下文。...

    前言

    卷积神经网络(CNN)在图像处理领域取得了很大的成绩,它的卷积和池化结构能很好提取图像的信息,而在 NLP 领域循环神经网络(RNN)则使用的更多,RNN 及其各种变种因拥有记忆功能使得它们更擅长处理上下文。但 NLP 领域很多方面使用 CNN 取得了出色的效果,比如语义分析、查询检索、文本分类等任务。这篇文章看看如何用 CNN 进行文本分类。

    模型结构

    模型结构可以通过下图一层层来看,总共由4部分组成,包括了输入层、卷积层、池化层和全连接层。
    这里写图片描述

    输入层

    图中最左边的部分即为输入层,总的来说输入层就是句子对应的矩阵。一般不会使用 ont-hot 向量来表示单词,而是使用 k 维的分布式词向量。那么对于一个长度为 n 的句子,则构成一个 n × k 的矩阵。

    所以,可以设

    展开全文
  • 我本次对4类文本进行分类((所有截图代码和数据集最后附带免费下载地址)) 主要步骤: 1.各种读文件,写文件 2.使用jieba分词将中文文本切割 3.对处理之后的文本开始用TF-IDF算法进行单词权值的计算 4....

    我本次对4类文本进行分类((所有截图代码和数据集最后附带免费下载地址)

     

    主要步骤:

     1.各种读文件,写文件

     2.使用jieba分词将中文文本切割

     3.对处理之后的文本开始用TF-IDF算法进行单词权值的计算

     4.去掉停用词

     5.贝叶斯预测种类

     

    文本预处理:

     除去噪声,如:格式转换,去掉符号,整体规范化

     遍历的读取一个文件下的每个文本

    中文分词

    中文分词就是将一句话拆分为各个词语,因为中文分词在不同的语境中歧义较大,所以分词极其重要。
    原型:我今天中午吃的小面。

    分词:我、今天、中午、吃、的、小面。

    其中  我、的   两个分词属于停用词(停用词后面讲)

    我们本次才用jieba分词来进行辅助,那么jieba分词有这么几个类型

    1.精确模式,试图将句子最精确的起开,适合文本分析。
    2.全模式,把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义。

    3.搜索引擎模式,再将却模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词

            #精确模式: 我/ 去过/ 清华大学/ 和/ 北京大学/ 。
            #全模式: 我/ 去过/ 清华/ 清华大学/ 华大/ 大学/ 和/ 北京/ 北京大学/ 大学/ / 
            #搜索引擎模式: 我/ 去过/ 清华/ 华大/ 大学/ 清华大学/ 和/ 北京/ 大学/ 北京大学/ 。 

    本程序使用的是(默认)精准模式,当然jieba还有很多种模式,大家可以自行查阅

     

    TF-IDF逆文本频率指数

     概念:是一种统计方法,用以评估一个词对于一个语料库中一份文件的重要程度。词的重要性随着在文件中出现              的次数正比增加,同时随着它在语料库其他文件中出现的频率反比下降。
               就是说一个词在某一文档中出现次数比较多,其他文档没有出现,说明该词对该文档分类很重要。

               然而如果其他文档也出现比较多,说明该词区分性不大,就用IDF来降低该词的权重。

    数学算法:

                TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比
                TF-IDF = TF (词频)   *   IDF(逆文档频率)
                词频:TF = 词在文档中出现的次数 / 文档中总词数

                逆文档频率:IDF = log(语料库中文档总数 / 包含该词的文档数  +1 )     

    避开停用词:

                      

      

    贝叶斯分类

    朴素贝叶斯分类算法核心:       

        

    表达形式:

    测试集

                              我手动打乱了里面的分类,这样看他能不能预测出来

    代码实现:

    #!D:/workplace/python
    # -*- coding: utf-8 -*-
    # @File  : homework3.py
    # @Author: WangYe
    # @Date  : 2018/4/22
    # @Software: PyCharm
    # 微博文字的性别识别
    import jieba
    import os
    import pickle  # 持久化
    from numpy import *
    from sklearn import feature_extraction
    from sklearn.feature_extraction.text import TfidfTransformer  # TF-IDF向量转换类
    from sklearn.feature_extraction.text import TfidfVectorizer  # TF_IDF向量生成类
    from sklearn.utils import Bunch
    from sklearn.naive_bayes import MultinomialNB  # 多项式贝叶斯算法
    
    
    def readFile(path):
        with open(path, 'r', errors='ignore') as file:  # 文档中编码有些问题,所有用errors过滤错误
            content = file.read()
            return content
    
    
    def saveFile(path, result):
        with open(path, 'w', errors='ignore') as file:
            file.write(result)
    
    
    def segText(inputPath, resultPath):
        fatherLists = os.listdir(inputPath)  # 主目录
        for eachDir in fatherLists:  # 遍历主目录中各个文件夹
            eachPath = inputPath + eachDir + "/"  # 保存主目录中每个文件夹目录,便于遍历二级文件
            each_resultPath = resultPath + eachDir + "/"  # 分词结果文件存入的目录
            if not os.path.exists(each_resultPath):
                os.makedirs(each_resultPath)
            childLists = os.listdir(eachPath)  # 获取每个文件夹中的各个文件
            for eachFile in childLists:  # 遍历每个文件夹中的子文件
                eachPathFile = eachPath + eachFile  # 获得每个文件路径
              #  print(eachFile)
                content = readFile(eachPathFile)  # 调用上面函数读取内容
                # content = str(content)
                result = (str(content)).replace("\r\n", "").strip()  # 删除多余空行与空格
                # result = content.replace("\r\n","").strip()
    
                cutResult = jieba.cut(result)  # 默认方式分词,分词结果用空格隔开
                saveFile(each_resultPath + eachFile, " ".join(cutResult))  # 调用上面函数保存文件
    
    
    def bunchSave(inputFile, outputFile):
        catelist = os.listdir(inputFile)
        bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
        bunch.target_name.extend(catelist)  # 将类别保存到Bunch对象中
        for eachDir in catelist:
            eachPath = inputFile + eachDir + "/"
            fileList = os.listdir(eachPath)
            for eachFile in fileList:  # 二级目录中的每个子文件
                fullName = eachPath + eachFile  # 二级目录子文件全路径
                bunch.label.append(eachDir)  # 当前分类标签
                bunch.filenames.append(fullName)  # 保存当前文件的路径
                bunch.contents.append(readFile(fullName).strip())  # 保存文件词向量
        with open(outputFile, 'wb') as file_obj:  # 持久化必须用二进制访问模式打开
            pickle.dump(bunch, file_obj)
            #pickle.dump(obj, file, [,protocol])函数的功能:将obj对象序列化存入已经打开的file中。
            #obj:想要序列化的obj对象。
            #file:文件名称。
            #protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本
    def readBunch(path):
        with open(path, 'rb') as file:
            bunch = pickle.load(file)
            #pickle.load(file)
            #函数的功能:将file中的对象序列化读出。
        return bunch
    
    
    def writeBunch(path, bunchFile):
        with open(path, 'wb') as file:
            pickle.dump(bunchFile, file)
    
    
    def getStopWord(inputFile):
        stopWordList = readFile(inputFile).splitlines()
        return stopWordList
    
    
    def getTFIDFMat(inputPath, stopWordList, outputPath):  # 求得TF-IDF向量
        bunch = readBunch(inputPath)
        tfidfspace = Bunch(target_name=bunch.target_name,label=bunch.label, filenames=bunch.filenames, tdm=[],
                           vocabulary={})
        # 初始化向量空间
        vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5)
        transformer = TfidfTransformer()  # 该类会统计每个词语的TF-IDF权值
        # 文本转化为词频矩阵,单独保存字典文件
        tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
        tfidfspace.vocabulary = vectorizer.vocabulary_   #获取词汇
        writeBunch(outputPath, tfidfspace)
    
    def getTestSpace(testSetPath, trainSpacePath, stopWordList, testSpacePath):
        bunch = readBunch(testSetPath)
        # 构建测试集TF-IDF向量空间
        testSpace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[],
                          vocabulary={})
        # 导入训练集的词袋
        trainbunch = readBunch(trainSpacePath)
        # 使用TfidfVectorizer初始化向量空间模型  使用训练集词袋向量
        vectorizer = TfidfVectorizer(stop_words=stopWordList, sublinear_tf=True, max_df=0.5,
                                     vocabulary=trainbunch.vocabulary)
        transformer = TfidfTransformer()
        testSpace.tdm = vectorizer.fit_transform(bunch.contents)
        testSpace.vocabulary = trainbunch.vocabulary
        # 持久化
        writeBunch(testSpacePath, testSpace)
    
    def bayesAlgorithm(trainPath, testPath):
        trainSet = readBunch(trainPath)
        testSet = readBunch(testPath)
        clf = MultinomialNB(alpha=0.001).fit(trainSet.tdm, trainSet.label)
        #alpha:0.001 alpha 越小,迭代次数越多,精度越高
        #print(shape(trainSet.tdm))  #输出单词矩阵的类型
        #print(shape(testSet.tdm))
        predicted = clf.predict(testSet.tdm)
        total = len(predicted)
        rate = 0
        for flabel, fileName, expct_cate in zip(testSet.label, testSet.filenames, predicted):
            if flabel != expct_cate:
                rate += 1
                print(fileName, ":实际类别:", flabel, "-->预测类别:", expct_cate)
        print("erroe rate:", float(rate) * 100 / float(total), "%")
    
    
    # 分词,第一个是分词输入,第二个参数是结果保存的路径
    segText("C:/Users/wy/Desktop/data/", "C:/Users/wy/Desktop/segResult/")
    bunchSave("C:/Users/wy/Desktop/segResult/", "C:/Users/wy/Desktop/train_set.dat")  # 输入分词,输出分词向量
    stopWordList = getStopWord("C:/Users/wy/Desktop/stop/stopword.txt")  # 获取停用词
    getTFIDFMat("C:/Users/wy/Desktop/train_set.dat", stopWordList, "C:/Users/wy/Desktop/tfidfspace.dat")  # 输入词向量,输出特征空间
    
    # 训练集
    segText("C:/Users/wy/Desktop/test1/", "C:/Users/wy/Desktop/test_segResult/")  # 分词
    bunchSave("C:/Users/wy/Desktop/test_segResult/", "C:/Users/wy/Desktop/test_set.dat")
    getTestSpace("C:/Users/wy/Desktop/test_set.dat", "C:/Users/wy/Desktop/tfidfspace.dat", stopWordList, "C:/Users/wy/Desktop/testspace.dat")
    bayesAlgorithm("C:/Users/wy/Desktop/tfidfspace.dat", "C:/Users/wy/Desktop/testspace.dat")

    结果截图:

    从结果看出,手动添加的错误都预测出来了,谢谢大家~

    参考文献:https://www.jianshu.com/p/915b0ab166e5

    数据集+代码百度云(数据集和代码尽量放一起,注意修改文件路径,不想修改路径的就看下面的新博客,有相对路径的代码):

    数据集链接:https://pan.baidu.com/s/1NSRC33fvqwfMmyb_E85WGg 
    提取码:0uln

    代码链接:https://pan.baidu.com/s/1Crla7bbGBPBwJw97-q1s_A 
    提取码:l01w 

    --------------------------------------------------分割线2019.5.29日更新---------------------------------------------------------------------------------------

    有很多同学加我微信问道dat文件的内容以及想查看词向量,词频矩阵等等详细信息,或者有同学对我代码的路径非常不熟悉很难修改为自己的路径,也有同学出现python的一些小bug,这里放出一个新的博客链接,我将文件的路径换为相对路径,并将dat文件转换为txt文件输出,方便大家查阅或者学习NLP的知识,还放出了大家运行我代码可能出现的一些基础问题,欢迎大家查看,留言,评论,共同学习。新博客我保证你代码一下载下来什么都不用改就能运行(只要python环境没问题)

    新博客链接:https://blog.csdn.net/qq_28626909/article/details/90669715

    --------------------------------------------------分割线 2019.6.20日更新---------------------------------------------------------------------------------------

    竟然有人私聊问我要我当时做这个玩意儿当时的PPT!!!而且还说当天晚上就要交作业!!!来不及自己做了!!!!

    PPT下载链接:https://download.csdn.net/download/qq_28626909/11250009 (CSDN积分下载,积分多的麻烦给我送点)

    没CSDN积分的百度云下载:

    链接:https://pan.baidu.com/s/17hT5UTB9VM0nWhrfVfkkzg 
    提取码:810f 

    PPT是2018年做的,而且当时水平有限,应急交作业的就拿去吧,我已经把我学校的水印还有我个人信息都去掉了。有时间的还是自己好好做一个吧,毕竟我PPT很水的。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    -------------------------------------------------分割线2020.11.29日更新---------------------------------------------------------------------------------------

    许多人对于这个输出错误率不是非常认同,希望看到一种输入一段话,然后直接输出类别的那种,例如下图:

    所以,我更新了博客,点击即可,只换代码,数据什么的都不用动。

    链接:https://blog.csdn.net/qq_28626909/article/details/110356190

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    由于提问评论人太多,这里我留下个人微信:wy1119744330     

    添加好友请备注姓名+单位 (我也会告诉你我的名字)例如:张三(xx大学)

    加的人太多了,我得改备注了,不然分不清楚了

    我也是菜鸟一个,如果数据集或者代码有什么问题欢迎留言,我都会回复的~

    展开全文
  • python实现文本分类

    万次阅读 多人点赞 2018-05-23 11:13:38
    一、中文文本分类流程:1. 预处理2. 中文分词3. 结构化表示-构建词向量空间4.权重策略-TF-IDF5. 分类器6. 评价二、具体细节1.预处理 1.1. 得到训练集语料库 本文采用复旦中文文本分类语料库,下载链接:...
  • 自然语言处理——文本分类概述

    万次阅读 2018-11-05 19:50:59
    内容提要分类概述分类流程数据采集爬虫技术页面处理文本预处理英文处理中文处理停用词去除文本表示特征选择 分类概述   分类(Classification)是指自动对数据进行标注。人们在日常生活中通过经验划分类别。但是要...
  • 本文分步介绍了用C#如何从文本文件 (.txt) 检索信息,然后使用 ArrayList 向用户显示该信息。 要求 Microsoft Visual C# 2005 或 Microsoft Visual C# .NET 在 Visual C# 2005 或 Visual C# .NET 中读取文本...
  • NLP-使用CNN进行文本分类

    万次阅读 多人点赞 2018-04-20 22:39:57
    CNN最初用于处理图像问题,但是在自然语言处理中,使用CNN进行文本分类也可以取得不错的效果。 在文本中,每个词都可以用一个行向量表示,一句话就可以用一个矩阵来表示,那么处理文本就与处理图像是类似的了。 ...
  • R语言做文本挖掘 Part4文本分类

    千次阅读 2015-03-18 16:30:34
    Part4文本分类 Part3文本聚类里讲到过,分类跟聚类的简单差异。...训练集准备是一个很繁琐的功能,暂时没发现什么省力的办法,根据文本内容去手动整理。这里还是使用的某品牌的官微数据,根据微博内容,我将它微博
  • 文本分类常用算法比较

    万次阅读 2015-04-03 16:10:48
    本文对文本分类中的常用算法进行了小结,比较它们之间的优劣,为算法的选择提供依据。  一、决策树(Decision Trees) 优点:  1、决策树易于理解和解释.人们在通过解释后都有能力去理解决策树所表达的意义。 ...
  • 文本分类六十年

    千次阅读 2020-11-27 19:29:08
    作者| Lucy出品 | AI科技大本营文本分类是自然语言处理中最基本而且非常有必要的任务,大部分自然语言处理任务都可以看作是个分类任务。近年来,深度学习所取得的前所未有的成功,使得该...
  • 自然语言处理实战:新闻文本分类(附代码)

    千次阅读 多人点赞 2020-08-13 18:06:15
    自然语言处理实战:新闻文本分类 ——本文比赛来源于天池零基础入门NLP - 新闻文本分类。 目录自然语言处理实战:新闻文本分类一、赛题理解1、学习目标2、赛题数据3、数据标签4、评测指标5、数据读取6、解题思路二...
  • Text-CNN 文本分类

    万次阅读 多人点赞 2017-09-05 09:39:30
    TextCNN 是利用卷积神经网络对文本进行分类的算法,由 Yoon Kim 在 “Convolutional Neural Networks for Sentence Classification” 一文 (见参考[1]) 中提出. 是2014年的算法. 图1-1 参考[1] 中的论文配图 ...
  • A Survey on Text Classification: From Shallow to Deep Learning ...根据所涉及的文本以及用于特征提取和分类的模型创建用于文本分类的分类法。然后,详细讨论这些类别中的每一个类别,涉及支持预测测试的技术.
  • 静态文本类 - CStatic 显示文本 2.按钮 - CButton 按钮,功能,嘿嘿 3.编辑框类 - CEdit 接收输入 4.滚动条 - CScrollBar 滚动窗口 5.列表框类 - CListBox 同时显示多条信息 6.组合...
  • 搜索引擎:文本分类——TF/IDF算法

    千次阅读 2015-10-06 12:43:13
    但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处. 在...
  • 【论文复现】使用RCNN进行文本分类

    千次阅读 2018-11-26 12:56:31
    继续之前的文本分类任务系列,前面介绍了几种:CNN,RNN,fasttext。今天的主角是RCNN 对了,顺带可以了解一下RNN与CNN在NLP中的区别于共同点,这个问题在昨天面试中也被问到了。这也是今天这篇论文提出的原因之一吧...
  • 使用python和sklearn的中文文本多分类实战开发

    万次阅读 多人点赞 2019-03-02 00:32:15
    文本分类一般可以分为二分类、多分类、多标签分类三种情况,二分类是指将一组文本分成两个(0或1),比较常见的应用如垃圾邮件分类、电商网站的用户评价数据的正负面分类等,多分类是指将文本分成若干个中的某一个,...
  • 文本分类的算法总结

    万次阅读 2017-04-25 09:23:29
    本文对文本分类中的常用算法进行了小结,比较它们之间的优劣,为算法的选择提供依据。 一、决策树(Decision Trees) 优点: 1、决策树易于理解和解释.人们在通过解释后都有能力去理解决策树所表达的意义。 2、...
  • java实现查找文本内容替换功能示例

    万次阅读 2016-07-18 18:24:17
    文本替换几乎是所有文本编辑器都支持的功能,但是要限制在编辑其中才可以执行该功能。本实例实现了制定文本文件的内容替换,并且不需要再编辑其中打开文本文件 思路: 先看视图层,要有一个JButton控件用来...
  • RichTextBox控件除了执行TextBox控件的所有功能之外,还可以显示字体、颜色和链接,从文件加载文本和嵌入的图像,撤销和重复编辑操作以及查找指定的字符。 1、在RichTextBox控件中显示滚动条 通过设置RichTextBox...
  • 基于Text-CNN模型的中文文本分类实战

    千次阅读 多人点赞 2019-03-21 11:06:17
    Text-CNN 1.文本分类 转眼学生生涯就结束了,在家待就业期间正好有一段空闲期,可以对曾经感兴趣的一些知识点进行总结。 ...本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个...文本分类是自...
  • 文本数据的机器学习自动分类方法

    万次阅读 2017-10-08 21:45:00
    ...本文为第一部分,着重介绍文本预处理以及特征抽取的方法。...随着互联网技术的迅速发展与普及,如何对...而在这些数据中,文本数据又是数量最大的一。“文本分类是指在给定分类体系下,根据文本内容自动确
  • CNN在中文文本分类的应用

    万次阅读 多人点赞 2016-11-25 22:45:18
    通常,图像处理的任务是借助CNN来完成的,其特有的卷积、池化结构能够提取图像中各种不同程度的纹理、结构,并最终结合全连接网络实现信息的汇总和输出。RNN由于其记忆功能为处理NLP中的上下文提供了途径。
  • 1 文本分类 是自然语言处理(NLP)领域里一项基本任务。而文本呢的长度过长对文本智能解析带来了巨大的挑战。 用传统的监督学习模型对一段文文本进行分类的基本过程: 一段原始文本→(数据预处理)→处理后的...
  • 从1961-2020年文本分类自浅入深的发展 摘要。 文本分类是自然语言处理中最基本的任务。由于深度学习的空前成功,过去十年中该领域的研究激增。已有的文献提出了许多方法,数据集和评估指标,从而需要对这些内容进行...
  • 文本分析是指文本中抽取特征词进行量化以表示文本信息文本一般指文字。 它是自然语言处理的一个小分支,自然语言处理还包括语音识别(常见的)等。 目的: 先决条件:将无结构化的原始文本转化为结构化的,...
  • 1. 概述 广义的分类(classification或者categorization)有两种含义:一种含义是有指导的学习(supervised learning)过程,另一种是无指导的学习...给定分类体系,将文本集中的每个文本分到某个或者某几

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 501,890
精华内容 200,756
关键字:

信息类文本的功能