精华内容
下载资源
问答
  • 对于数据科学家、开发人员...https://github.com/christos-c/bible-corpus 回顾过去的工作和未来的挑战https://arxiv.org/pdf/2006.07264.pdf 开放翻译服务的工具和资源: https : //github.com/Helsinki-NLP/Opus-
  • russian_news_corpus:俄罗斯大众媒体阻止了文本的语料库。
  • python 中文文本分类

    千次阅读 2018-01-19 22:29:43
    写这篇博文用了很多时间和精力,如果这篇博文对你有帮助,希望您... train_corpus/art/21.txt中,’train_corpus/’是corpus_path,’art’是catelist中的一个成员    ”’       # 获取每个目录(类别)下...

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

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

    手机扫一扫,即可:



    目标读者:初级入门学生

    本文假定,你对python已经有了最基本的掌握。如果你希望能够对python有更多的掌握,可以参考博主的系列博文:

    python高手的自修课



    一,中文文本分类流程:

    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的样例代码:

    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: html_demo.py 
    8. @time: 2017/2/6 12:25 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. from lxml import html  
    13. # 设置utf-8 unicode环境  
    14. reload(sys)  
    15. sys.setdefaultencoding(’utf-8’)  
    16.   
    17. def html2txt(path):  
    18.     with open(path,”rb”) as f:  
    19.         content=f.read()   
    20.     r”’ 
    21.     上面两行是python2.6以上版本增加的语法,省略了繁琐的文件close和try操作 
    22.     2.5版本需要from __future__ import with_statement 
    23.     新手可以参考这个链接来学习http://zhoutall.com/archives/325 
    24.     ”’  
    25.     page = html.document_fromstring(content) # 解析文件  
    26.     text = page.text_content() # 去除所有标签  
    27.     return text  
    28.   
    29. if __name__  ==“__main__”:  
    30.     # htm文件路径,以及读取文件  
    31.     path = ”1.htm”  
    32.     text=html2txt(path)  
    33.     print text   # 输出去除标签后解析结果  
    #

    2,中文分词。

    本小节的目标是:

    1,告诉你中文分词的实际操作。

    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分词使用方法(详细的和更进一步的,可以参考这个链接):

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

    [python] view plain copy
    print ?
    1. import jieba  
    2.   
    3. seg_list = jieba.cut(”我来到北京清华大学”, cut_all=True)  
    4. print(“Full Mode: ” + “/ ”.join(seg_list))  # 全模式  
    5.   
    6. seg_list = jieba.cut(”我来到北京清华大学”, cut_all=False)  
    7. print(“Default Mode: ” + “/ ”.join(seg_list))  # 精确模式  
    8.   
    9. seg_list = jieba.cut(”他来到了网易杭研大厦”)  # 默认是精确模式  
    10. print(“, ”.join(seg_list))  
    11.   
    12. seg_list = jieba.cut_for_search(”小明硕士毕业于中国科学院计算所,后在日本京都大学深造”)  # 搜索引擎模式  
    13. print(“, ”.join(seg_list))  
    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))

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


    2.2.2

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

    ./train_corpus_seg/和./test_corpus_seg/

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


    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: corpus_segment.py 
    8. @time: 2017/2/5 15:28 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. import os  
    13. import jieba  
    14. # 配置utf-8输出环境  
    15. reload(sys)  
    16. sys.setdefaultencoding(’utf-8’)  
    17. # 保存至文件  
    18. def savefile(savepath, content):  
    19.     with open(savepath, ”wb”) as fp:  
    20.         fp.write(content)  
    21.     ”’ 
    22.     上面两行是python2.6以上版本增加的语法,省略了繁琐的文件close和try操作 
    23.     2.5版本需要from __future__ import with_statement 
    24.     新手可以参考这个链接来学习http://zhoutall.com/archives/325 
    25.     ”’  
    26. # 读取文件  
    27. def readfile(path):  
    28.     with open(path, ”rb”) as fp:  
    29.         content = fp.read()  
    30.     return content  
    31.   
    32. def corpus_segment(corpus_path, seg_path):  
    33.     ”’ 
    34.     corpus_path是未分词语料库路径 
    35.     seg_path是分词后语料库存储路径 
    36.     ”’  
    37.     catelist = os.listdir(corpus_path)  # 获取corpus_path下的所有子目录  
    38.     ”’ 
    39.     其中子目录的名字就是类别名,例如: 
    40.     train_corpus/art/21.txt中,’train_corpus/’是corpus_path,’art’是catelist中的一个成员 
    41.     ”’  
    42.   
    43.     # 获取每个目录(类别)下所有的文件  
    44.     for mydir in catelist:  
    45.         ”’ 
    46.         这里mydir就是train_corpus/art/21.txt中的art(即catelist中的一个类别) 
    47.         ”’  
    48.         class_path = corpus_path + mydir + ”/”  # 拼出分类子目录的路径如:train_corpus/art/  
    49.         seg_dir = seg_path + mydir + ”/”  # 拼出分词后存贮的对应目录路径如:train_corpus_seg/art/  
    50.   
    51.         if not os.path.exists(seg_dir):  # 是否存在分词目录,如果没有则创建该目录  
    52.             os.makedirs(seg_dir)  
    53.   
    54.         file_list = os.listdir(class_path)  # 获取未分词语料库中某一类别中的所有文本  
    55.         ”’ 
    56.         train_corpus/art/中的 
    57.         21.txt, 
    58.         22.txt, 
    59.         23.txt 
    60.         … 
    61.         file_list=[‘21.txt’,’22.txt’,…] 
    62.         ”’  
    63.         for file_path in file_list:  # 遍历类别目录下的所有文件  
    64.             fullname = class_path + file_path  # 拼出文件名全路径如:train_corpus/art/21.txt  
    65.             content = readfile(fullname)  # 读取文件内容  
    66.             ”’此时,content里面存贮的是原文本的所有字符,例如多余的空格、空行、回车等等, 
    67.             接下来,我们需要把这些无关痛痒的字符统统去掉,变成只有标点符号做间隔的紧凑的文本内容 
    68.             ”’  
    69.             content = content.replace(”\r\n”, ”“)  # 删除换行  
    70.             content = content.replace(” ”, ”“)#删除空行、多余的空格  
    71.             content_seg = jieba.cut(content)  # 为文件内容分词  
    72.             savefile(seg_dir + file_path, ” ”.join(content_seg))  # 将处理后的文件保存到分词后语料目录  
    73.   
    74.     print “中文语料分词结束!!!”  
    75.   
    76. ”’ 
    77. 如果你对if __name__==”__main__”:这句不懂,可以参考下面的文章 
    78. http://imoyao.lofter.com/post/3492bc_bd0c4ce 
    79. 简单来说如果其他python文件调用这个文件的函数,或者把这个文件作为模块 
    80. 导入到你的工程中时,那么下面的代码将不会被执行,而如果单独在命令行中 
    81. 运行这个文件,或者在IDE(如pycharm)中运行这个文件时候,下面的代码才会运行。 
    82. 即,这部分代码相当于一个功能测试。 
    83. 如果你还没懂,建议你放弃IT这个行业。 
    84. ”’  
    85. if __name__==“__main__”:  
    86.     #对训练集进行分词  
    87.     corpus_path = ”./train_corpus/”  # 未分词分类语料库路径  
    88.     seg_path = ”./train_corpus_seg/”  # 分词后分类语料库路径  
    89.     corpus_segment(corpus_path,seg_path)  
    90.   
    91.     #对测试集进行分词  
    92.     corpus_path = ”./test_corpus/”  # 未分词分类语料库路径  
    93.     seg_path = ”./test_corpus_seg/”  # 分词后分类语料库路径  
    94.     corpus_segment(corpus_path,seg_path)  
    #

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

    首先来看看Bunch:

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

    好了,解释完了。

    是不是很简单?

    在本篇博文中,你对Bunch能够有这种层次的理解,就足够了。如果你想继续详细透彻的理解Bunch,请见博主的另一篇博文《暂时还没写,写完在这里更新链接》


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

    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类形:

    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: corpus2Bunch.py 
    8. @time: 2017/2/7 7:41 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. reload(sys)  
    13. sys.setdefaultencoding(’utf-8’)  
    14. import os#python内置的包,用于进行文件目录操作,我们将会用到os.listdir函数  
    15. import cPickle as pickle#导入cPickle包并且取一个别名pickle  
    16. ”’ 
    17. 事实上python中还有一个也叫作pickle的包,与这里的名字相同了,无所谓 
    18. 关于cPickle与pickle,请参考博主另一篇博文: 
    19. python核心模块之pickle和cPickle讲解 
    20. http://blog.csdn.net/github_36326955/article/details/54882506 
    21. 本文件代码下面会用到cPickle中的函数cPickle.dump 
    22. ”’  
    23. from sklearn.datasets.base import Bunch  
    24. #这个您无需做过多了解,您只需要记住以后导入Bunch数据结构就像这样就可以了。  
    25. #今后的博文会对sklearn做更有针对性的讲解  
    26.   
    27.   
    28. def _readfile(path):  
    29.     ”’读取文件”’  
    30.     #函数名前面带一个_,是标识私有函数  
    31.     # 仅仅用于标明而已,不起什么作用,  
    32.     # 外面想调用还是可以调用,  
    33.     # 只是增强了程序的可读性  
    34.     with open(path, ”rb”) as fp:#with as句法前面的代码已经多次介绍过,今后不再注释  
    35.         content = fp.read()  
    36.     return content  
    37.   
    38. def corpus2Bunch(wordbag_path,seg_path):  
    39.     catelist = os.listdir(seg_path)# 获取seg_path下的所有子目录,也就是分类信息  
    40.     #创建一个Bunch实例  
    41.     bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])  
    42.     bunch.target_name.extend(catelist)  
    43.     ”’ 
    44.     extend(addlist)是python list中的函数,意思是用新的list(addlist)去扩充 
    45.     原来的list 
    46.     ”’  
    47.     # 获取每个目录下所有的文件  
    48.     for mydir in catelist:  
    49.         class_path = seg_path + mydir + ”/”  # 拼出分类子目录的路径  
    50.         file_list = os.listdir(class_path)  # 获取class_path下的所有文件  
    51.         for file_path in file_list:  # 遍历类别目录下文件  
    52.             fullname = class_path + file_path  # 拼出文件名全路径  
    53.             bunch.label.append(mydir)  
    54.             bunch.filenames.append(fullname)  
    55.             bunch.contents.append(_readfile(fullname))  # 读取文件内容  
    56.             ”’append(element)是python list中的函数,意思是向原来的list中添加element,注意与extend()函数的区别”’  
    57.     # 将bunch存储到wordbag_path路径中  
    58.     with open(wordbag_path, ”wb”) as file_obj:  
    59.         pickle.dump(bunch, file_obj)  
    60.     print “构建文本对象结束!!!”  
    61.   
    62. if __name__ == “__main__”:#这个语句前面的代码已经介绍过,今后不再注释  
    63.     #对训练集进行Bunch化操作:  
    64.     wordbag_path = ”train_word_bag/train_set.dat”  # Bunch存储路径  
    65.     seg_path = ”train_corpus_seg/”  # 分词后分类语料库路径  
    66.     corpus2Bunch(wordbag_path, seg_path)  
    67.   
    68.     # 对测试集进行Bunch化操作:  
    69.     wordbag_path = ”test_word_bag/test_set.dat”  # Bunch存储路径  
    70.     seg_path = ”test_corpus_seg/”  # 分词后分类语料库路径  
    71.     corpus2Bunch(wordbag_path, seg_path)  
    #


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

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

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

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


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

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



    但是在我们第2节处理的这些文件中,词向量之间的单词个数并不相同,词向量的涵盖的单词也不尽相同。他们并不在一个空间里,换句话说,就是他们之间没有可比性,例如:

    词向量1:我 喜欢 相国大人,对应的词向量空间是(我,喜欢,相国大人),可以表示为(1,1,1)

    词向量2:她 不 喜欢 我,对应的词向量空间是(她,不,喜欢,我),可以表示为(1,1,1,1)

    两个空间不一样


    因此,接下来我们要做的,就是把所有这些词向量统一到同一个词向量空间中,例如,在上面的例子中,我们可以设置词向量空间为(我,喜欢,相国大人,她,不)

    这样,词向量1和词向量2分别可以表示为(1,1,1,0,0)和(1,1,0,1,1),这样两个向量就都在同一个空间里面了。可以进行比较和各种运算了。


    也许你已经发现了,这样做的一个很糟糕的结果是,我们要把训练集内所有出现过的单词,都作为一个维度,构建统一的词向量空间,即使是中等大小的文本集合,向量维度也很轻易就达到数十万维。为了节省空间,我们首先将训练集中每个文本中一些垃圾词汇去掉。所谓的垃圾词汇,就是指意义模糊的词,或者一些语气助词,标点符号等等,通常他们对文本起不了分类特征的意义。这些垃圾词汇我们称之为停用词。把所有停用词集合起来构成一张停用词表格,这样,以后我们处理文本时,就可以从这个根据表格,过滤掉文本中的一些垃圾词汇了。

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

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


    下面的程序,目的就是要将训练集所有文本文件(词向量)统一到同一个词向量空间中。值得一提的是,在词向量空间中,事实上不同的词,它的权重是不同的,它对文本分类的影响力也不同,为此我们希望得到的词向量空间不是等权重的空间,而是不同权重的词向量空间。我们把带有不同权重的词向量空间叫做“加权词向量空间”,也有的技术文档将其称为“加权向量词袋”,一个意思。


    现在的问题是,如何计算不同词的权重呢?


    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值(看到这里,我估计你压根就没去看那篇文章,所以你可能到现在也不知道 这是个啥玩意儿。。。)


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

    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: vector_space.py 
    8. @time: 2017/2/7 17:29 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. reload(sys)  
    13. sys.setdefaultencoding(’utf-8’)  
    14. # 引入Bunch类  
    15. from sklearn.datasets.base import Bunch  
    16. import cPickle as pickle#之前已经说过,不再赘述  
    17. from sklearn.feature_extraction.text import TfidfVectorizer#这个东西下面会讲  
    18.   
    19. # 读取文件  
    20. def _readfile(path):  
    21.     with open(path, ”rb”) as fp:  
    22.         content = fp.read()  
    23.     return content  
    24.   
    25. # 读取bunch对象  
    26. def _readbunchobj(path):  
    27.     with open(path, ”rb”) as file_obj:  
    28.         bunch = pickle.load(file_obj)  
    29.     return bunch  
    30.   
    31. # 写入bunch对象  
    32. def _writebunchobj(path, bunchobj):  
    33.     with open(path, ”wb”) as file_obj:  
    34.         pickle.dump(bunchobj, file_obj)  
    35.   
    36. #这个函数用于创建TF-IDF词向量空间  
    37. def vector_space(stopword_path,bunch_path,space_path):  
    38.   
    39.     stpwrdlst = _readfile(stopword_path).splitlines()#读取停用词  
    40.     bunch = _readbunchobj(bunch_path)#导入分词后的词向量bunch对象  
    41.     #构建tf-idf词向量空间对象  
    42.     tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})  
    43.     ”’ 
    44.     在前面几节中,我们已经介绍了Bunch。 
    45.     target_name,label和filenames这几个成员都是我们自己定义的玩意儿,前面已经讲过不再赘述。 
    46.     下面我们讲一下tdm和vocabulary(这俩玩意儿也都是我们自己创建的): 
    47.     tdm存放的是计算后得到的TF-IDF权重矩阵。请记住,我们后面分类器需要的东西,其实就是训练集的tdm和标签label,因此这个成员是 
    48.     很重要的。 
    49.     vocabulary是词向量空间的索引,例如,如果我们定义的词向量空间是(我,喜欢,相国大人),那么vocabulary就是这样一个索引字典 
    50.     vocabulary={“我”:0,”喜欢”:1,”相国大人”:2},你可以简单的理解为:vocabulary就是词向量空间的坐标轴,索引值相当于表明了第几 
    51.     个维度。 
    52.     我们现在就是要构建一个词向量空间,因此在初始时刻,这个tdm和vocabulary自然都是空的。如果你在这一步将vocabulary赋值了一个 
    53.     自定义的内容,那么,你是傻逼。 
    54.     ”’  
    55.   
    56.     ”’ 
    57.     与下面这2行代码等价的代码是: 
    58.     vectorizer=CountVectorizer()#构建一个计算词频(TF)的玩意儿,当然这里面不只是可以做这些 
    59.     transformer=TfidfTransformer()#构建一个计算TF-IDF的玩意儿 
    60.     tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus)) 
    61.     #vectorizer.fit_transform(corpus)将文本corpus输入,得到词频矩阵 
    62.     #将这个矩阵作为输入,用transformer.fit_transform(词频矩阵)得到TF-IDF权重矩阵 
    63.  
    64.     看名字你也应该知道: 
    65.     Tfidf-Transformer + Count-Vectorizer  = Tfidf-Vectorizer 
    66.     下面的代码一步到位,把上面的两个步骤一次性全部完成 
    67.  
    68.     值得注意的是,CountVectorizer()和TfidfVectorizer()里面都有一个成员叫做vocabulary_(后面带一个下划线) 
    69.     这个成员的意义,与我们之前在构建Bunch对象时提到的自己定义的那个vocabulary的意思是一样的,相当于词向量 
    70.     空间的坐标轴。显然,我们在第45行中创建tfidfspace中定义的vocabulary就应该被赋值为这个vocabulary_ 
    71.  
    72.     他俩还有一个叫做vocabulary(后面没有下划线)的参数,这个参数和我们第45中讲到的意思是一样的。 
    73.     那么vocabulary_和vocabulary的区别是什么呢? 
    74.     vocabulary_:是CountVectorizer()和TfidfVectorizer()的内部成员,表示最终得到的词向量空间坐标 
    75.     vocabulary:是创建CountVectorizer和TfidfVectorizer类对象时,传入的参数,它是我们外部输入的空间坐标,不写的话,函数就从 
    76.     输入文档中自己构造。 
    77.     一般情况它俩是相同的,不一般的情况没遇到过。 
    78.     ”’  
    79.     #构建一个快乐地一步到位的玩意儿,专业一点儿叫做:使用TfidfVectorizer初始化向量空间模型  
    80.     #这里面有TF-IDF权重矩阵还有我们要的词向量空间坐标轴信息vocabulary_  
    81.     vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5)  
    82.     ”’ 
    83.     关于参数,你只需要了解这么几个就可以了: 
    84.     stop_words: 
    85.     传入停用词,以后我们获得vocabulary_的时候,就会根据文本信息去掉停用词得到 
    86.     vocabulary: 
    87.     之前说过,不再解释。 
    88.     sublinear_tf: 
    89.     计算tf值采用亚线性策略。比如,我们以前算tf是词频,现在用1+log(tf)来充当词频。 
    90.     smooth_idf: 
    91.     计算idf的时候log(分子/分母)分母有可能是0,smooth_idf会采用log(分子/(1+分母))的方式解决。默认已经开启,无需关心。 
    92.     norm: 
    93.     归一化,我们计算TF-IDF的时候,是用TF*IDF,TF可以是归一化的,也可以是没有归一化的,一般都是采用归一化的方法,默认开启. 
    94.     max_df: 
    95.     有些词,他们的文档频率太高了(一个词如果每篇文档都出现,那还有必要用它来区分文本类别吗?当然不用了呀),所以,我们可以 
    96.     设定一个阈值,比如float类型0.5(取值范围[0.0,1.0]),表示这个词如果在整个数据集中超过50%的文本都出现了,那么我们也把它列 
    97.     为临时停用词。当然你也可以设定为int型,例如max_df=10,表示这个词如果在整个数据集中超过10的文本都出现了,那么我们也把它列 
    98.     为临时停用词。 
    99.     min_df: 
    100.     与max_df相反,虽然文档频率越低,似乎越能区分文本,可是如果太低,例如10000篇文本中只有1篇文本出现过这个词,仅仅因为这1篇 
    101.     文本,就增加了词向量空间的维度,太不划算。 
    102.     当然,max_df和min_df在给定vocabulary参数时,就失效了。 
    103.     ”’  
    104.   
    105.     #此时tdm里面存储的就是if-idf权值矩阵  
    106.     tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)  
    107.     tfidfspace.vocabulary = vectorizer.vocabulary_  
    108.   
    109.     _writebunchobj(space_path, tfidfspace)  
    110.     print “if-idf词向量空间实例创建成功!!!”  
    111.   
    112. if __name__ == ‘__main__’:  
    113.     stopword_path = ”train_word_bag/hlt_stop_words.txt”#停用词表的路径  
    114.     bunch_path = ”train_word_bag/train_set.dat”  #导入训练集Bunch的路径  
    115.     space_path = ”train_word_bag/tfdifspace.dat”  # 词向量空间保存路径  
    116.     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词向量空间上:

    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: test.py 
    8. @time: 2017/2/8 11:39 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. reload(sys)  
    13. sys.setdefaultencoding(’utf-8’)  
    14. # 引入Bunch类  
    15. from sklearn.datasets.base import Bunch  
    16. import cPickle as pickle  
    17. from sklearn.feature_extraction.text import TfidfVectorizer  
    18.   
    19. def _readfile(path):  
    20.     with open(path, ”rb”) as fp:  
    21.         content = fp.read()  
    22.     return content  
    23.   
    24. def _readbunchobj(path):  
    25.     with open(path, ”rb”) as file_obj:  
    26.         bunch = pickle.load(file_obj)  
    27.     return bunch  
    28.   
    29. def _writebunchobj(path, bunchobj):  
    30.     with open(path, ”wb”) as file_obj:  
    31.         pickle.dump(bunchobj, file_obj)  
    32.   
    33. def vector_space(stopword_path,bunch_path,space_path,train_tfidf_path):  
    34.   
    35.     stpwrdlst = _readfile(stopword_path).splitlines()  
    36.     bunch = _readbunchobj(bunch_path)  
    37.     tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})  
    38.   
    39.     #导入训练集的TF-IDF词向量空间  
    40.     trainbunch = _readbunchobj(train_tfidf_path)  
    41.     tfidfspace.vocabulary = trainbunch.vocabulary  
    42.   
    43.     vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5,vocabulary=trainbunch.vocabulary)  
    44.     tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)  
    45.     _writebunchobj(space_path, tfidfspace)  
    46.     print “if-idf词向量空间实例创建成功!!!”  
    47.   
    48. if __name__ == ‘__main__’:  
    49.     stopword_path = ”train_word_bag/hlt_stop_words.txt”#停用词表的路径  
    50.     bunch_path = ”test_word_bag/test_set.dat”   # 词向量空间保存路径  
    51.     space_path = ”test_word_bag/testspace.dat”   # TF-IDF词向量空间保存路径  
    52.     train_tfidf_path=”train_word_bag/tfdifspace.dat”  
    53.     vector_space(stopword_path,bunch_path,space_path,train_tfidf_path)  
    #

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

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


    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: TFIDF_space.py 
    8. @time: 2017/2/8 11:39 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. reload(sys)  
    13. sys.setdefaultencoding(’utf-8’)  
    14.   
    15. from sklearn.datasets.base import Bunch  
    16. import cPickle as pickle  
    17. from sklearn.feature_extraction.text import TfidfVectorizer  
    18.   
    19. def _readfile(path):  
    20.     with open(path, ”rb”) as fp:  
    21.         content = fp.read()  
    22.     return content  
    23.   
    24. def _readbunchobj(path):  
    25.     with open(path, ”rb”) as file_obj:  
    26.         bunch = pickle.load(file_obj)  
    27.     return bunch  
    28.   
    29. def _writebunchobj(path, bunchobj):  
    30.     with open(path, ”wb”) as file_obj:  
    31.         pickle.dump(bunchobj, file_obj)  
    32.   
    33. def vector_space(stopword_path,bunch_path,space_path,train_tfidf_path=None):  
    34.   
    35.     stpwrdlst = _readfile(stopword_path).splitlines()  
    36.     bunch = _readbunchobj(bunch_path)  
    37.     tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label, filenames=bunch.filenames, tdm=[], vocabulary={})  
    38.   
    39.     if train_tfidf_path is not None:  
    40.         trainbunch = _readbunchobj(train_tfidf_path)  
    41.         tfidfspace.vocabulary = trainbunch.vocabulary  
    42.         vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5,vocabulary=trainbunch.vocabulary)  
    43.         tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)  
    44.   
    45.     else:  
    46.         vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.5)  
    47.         tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)  
    48.         tfidfspace.vocabulary = vectorizer.vocabulary_  
    49.   
    50.     _writebunchobj(space_path, tfidfspace)  
    51.     print “if-idf词向量空间实例创建成功!!!”  
    52.   
    53. if __name__ == ‘__main__’:  
    54.   
    55.     stopword_path = ”train_word_bag/hlt_stop_words.txt”  
    56.     bunch_path = ”train_word_bag/train_set.dat”  
    57.     space_path = ”train_word_bag/tfdifspace.dat”  
    58.     vector_space(stopword_path,bunch_path,space_path)  
    59.   
    60.     bunch_path = ”test_word_bag/test_set.dat”  
    61.     space_path = ”test_word_bag/testspace.dat”  
    62.     train_tfidf_path=”train_word_bag/tfdifspace.dat”  
    63.     vector_space(stopword_path,bunch_path,space_path,train_tfidf_path)  
    #


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


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


    [python] view plain copy
    print ?
    1. #!/usr/bin/env python  
    2. # -*- coding: UTF-8 -*-  
    3. ”“” 
    4. @version: python2.7.8  
    5. @author: XiangguoSun 
    6. @contact: sunxiangguodut@qq.com 
    7. @file: NBayes_Predict.py 
    8. @time: 2017/2/8 12:21 
    9. @software: PyCharm 
    10. ”“”  
    11. import sys  
    12. reload(sys)  
    13. sys.setdefaultencoding(’utf-8’)  
    14.   
    15. import cPickle as pickle  
    16. from sklearn.naive_bayes import MultinomialNB  # 导入多项式贝叶斯算法  
    17.   
    18.   
    19. # 读取bunch对象  
    20. def _readbunchobj(path):  
    21.     with open(path, ”rb”) as file_obj:  
    22.         bunch = pickle.load(file_obj)  
    23.     return bunch  
    24.   
    25. # 导入训练集  
    26. trainpath = ”train_word_bag/tfdifspace.dat”  
    27. train_set = _readbunchobj(trainpath)  
    28.   
    29. # 导入测试集  
    30. testpath = ”test_word_bag/testspace.dat”  
    31. test_set = _readbunchobj(testpath)  
    32.   
    33. # 训练分类器:输入词袋向量和分类标签,alpha:0.001 alpha越小,迭代次数越多,精度越高  
    34. clf = MultinomialNB(alpha=0.001).fit(train_set.tdm, train_set.label)  
    35.   
    36. # 预测分类结果  
    37. predicted = clf.predict(test_set.tdm)  
    38.   
    39. for flabel,file_name,expct_cate in zip(test_set.label,test_set.filenames,predicted):  
    40.     if flabel != expct_cate:  
    41.         print file_name,“: 实际类别:”,flabel,“ –>预测类别:”,expct_cate  
    42.   
    43. print “预测完毕!!!”  
    44.   
    45. # 计算分类精度:  
    46. from sklearn import metrics  
    47. def metrics_result(actual, predict):  
    48.     print ‘精度:{0:.3f}’.format(metrics.precision_score(actual, predict,average=‘weighted’))  
    49.     print ‘召回:{0:0.3f}’.format(metrics.recall_score(actual, predict,average=‘weighted’))  
    50.     print ‘f1-score:{0:.3f}’.format(metrics.f1_score(actual, predict,average=‘weighted’))  
    51.   
    52. metrics_result(test_set.label, predicted)  
    #


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


     

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


    6,评价与小结

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

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

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

    2,文本分类算法的研究

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


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

    https://github.com/sunxiangguo/chinese_text_classification

    需要说明的是,在工程代码和本篇博文中,细心的你已经发现了,我们所有的路径前面都有一个点“. /”,这主要是因为我们不知道您会将工程建在哪个路径内,因此这个表示的是你所在项目的目录,本篇博文所有路径都是相对路径。因此你需要自己注意一下。工程里面语料库是空的,因为上传资源受到容量的限制。你需要自己添加。

    7,进一步的讨论:

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

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

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



    8,At last



    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 system. Apparently, 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

    展开全文
  • IMS开放语料库工作台是用于管理和查询带有语言注释的大型文本语料库(100 M个单词或更多)的工具的集合。 它的核心组件是灵活高效的查询处理器CQP,它可以在终端会话中交互使用,例如作为后端,例如来自Perl脚本或...
  • 布朗语料库是美国英语的首个文本语料库,它取自不同主题的报纸文本、书籍以及政府文件,包含 1,014,312 个单词的它主要用于语言建模。 cats.csv brown-meta.json brown.csv Brown Corpus 布朗语料库_datasets....
  • 欢迎使用最大的专家注释语料库,以自由文本形式进行复杂定义提取。 尘埃落定-该数据与 (DeftEval)相关,我们将在SemEval会议日程安排上发布完整的数据集。 提供培训和开发数据,并且在2020年2月2日SemEval评估期...
  • 文本本身在corpus目录中。 manifest.csv文件包含语料库中的文件名以及相关的元数据。 下载语料库 可以在这里下载语料库: : 再现语料库 您可以使用提供的代码来重现语料库。 对于GitHub存储库,文本本身太大。 ...
  • 文本挖掘相关介绍 1什么是文本挖掘 2NLP 3 分词 4 OCR 5 常用算法 6 文本挖掘处理流程 7 相应R包简介 8 文本处理 词干化stemming snowball包 记号化Tokenization RWeka包 中文分词 Rwordseg包 9 tm包常用操作介绍 ...


    文本挖掘相关介绍

    1、什么是文本挖掘

    文本挖掘是抽取有效、新颖、有用、可理解的、散布在文本文件中的有价值知识,并且利用这些知识更好地组织信息的过程。

    在文本挖掘领域中,文本自动分类,判同,情感分析是文本挖掘比较常见的应用文本分类技术主要应用在百度新闻,谷歌新闻等新闻网站,对新闻内容进行自动分类,并且实现根据用户专业倾向的文档推荐;搜索引擎去重,论文抄袭判别系统等。情感分析技术主要应用在电商评论分析系统,政府和媒体舆情监测系统等。语意理解技术应用在机器翻译、聊天机器人等。

    2、NLP

    文本挖掘可以视为NLP(Natural language processing,自然语言处理)的一个子领域,目标是在大量非结构化文本中整理析取出有价值的内容。由于人类语言具有很高的复杂性,例如不同语言间语法不同,组成方式不同,还有语言种类的多样性,使得NLP是目前机器学习领域最困难的技术之一,里面的难点大部分成为各个应用领域(搜索引擎,情感识别,机器写作等等)的核心障碍,是实现高度智能机器人的关键技术。NLP大部分方法适用于不同的语种,也有部分只适合特定语种。

    NLP通常包含两方面内容:词法、语法。词法的经典问题为分词、拼写检查、语音识别等;语法的经典问题有词类识别、词义消歧、结构分析等;语音识别领域经典问题有语言识别、语音指令、电话监听、语音生成等。

    3、 分词

    在英语等语言中,词与词之间存在着空格,因此在进行处理过程中不需要对其进行分词处理,但由于汉语等语言中词与词之间没有存在分隔,因此需要对其进行分词处理。分词处理能够避免不分词所引发的全表扫描,全表扫描效率低且内存消耗大。

    4、 OCR

    OCR : optional character recognition 印刷体识别和手写体识别、字形析取
    应用:车牌识别、名片识别等

    5、 常用算法

    (算法需要一定的数学和统计学基础)
    贝叶斯分类器
    隐马尔科夫过程
    有限状态自动机(FSA):用于文本判同等

    6、 文本挖掘处理流程

    文本挖掘处理流程

    7、 相应R包简介

    语音与语音处理: emu包
    词库数据库: wordnet包(英文库)
    关键字提取和通用字符串操作: RKEA包;gsubfn包,tau包
    自然语言处理: openNLP包,RWeka包;snowball包(分词);Rstem包;KoNLP包
    文本挖掘: tm包(相对完整和综合);lsa包;topicmodels包;RTextTools包;textact包;zipfR包;……

    8、 文本处理

    1.词干化stemming snowball包

    2.记号化Tokenization RWeka包

    3.中文分词 Rwordseg包

    Rwordseg包需下载安装,网址:
    https://r-forge.r-project.org/R/?group_id=1054
    在上面网址中下载Rwordseg 如果是64位的话就要下载.zip文件
    中文分词比较有名的包非Rwordseg和jieba莫属,他们采用的算法大同小异,但有一个地方有所差别:Rwordseg在分词之前会去掉文本中所有的符号,这样就会造成原本分开的句子前后相连,本来是分开的两个字也许连在一起就是一个词了。
    而jieba分词包不会去掉任何符号,而且返回的结果里面也会有符号。

    9、 tm包常用操作介绍

    1.DirSource:处理目录
    2.VectorSource:由文档构成向量
    3.DataframeSource:数据框,就像CSV 文件
    4.Map操作:对文档内容应用转换函数
    5.Xml转化为纯文本
    6.去除多余空白
    7.去除停用词
    8.填充
    9.Reduce操作:将多个转换函数的输出合并成一个

    tm包具体操作

    tm包版本问题:代码基于tm包0.6版本
    关于版本差异问题,详见:https://cran.r-project.org/web/packages/tm/news.html

    1.建立语料库

    建立动态语料库 Corpus(x,……)
    Corpus(x, readerControl = list(reader=x$DefaultReader,language="en"),|…… )
    建立静态语料库 Pcorpus(x,……)
    PCorpus(x, readerControl = list(reader=x$DefaultReader,language="en"),dbControl = list(dbName="",dbType="DB1"),…… )

    x参数有如下三种选择:
    DirSource
    VectorSource
    DataframeSource
    (可以在readercontrol中的language中改变参数,建立各种语言的语料库,详见https://zh.wikipedia.org/zh/ISO_639-1%E4%BB%A3%E7%A0%81%E8%A1%A8)
    另外,reader中可选参数如下,可以通过选择不同的参数读取不同形式的文件:
    这里写图片描述

    例:

    #利用DirSource
    ovid1<-Corpus(DirSource("d:/Program Files/R/R-3.3.3/library/tm/texts/txt"), 
                  readerControl = list(language = "lat"))
    inspect(ovid1)
    #inspect可输出语料库的内容
    #利用VectorSource
    docs <- c("This is a text.", "This another one.")
    ovid2 <- Corpus(VectorSource(docs))
    inspect(ovid2)
    #利用DataframeSource
    data <- read.csv("D:/data/Finance Report 2012.csv")
    ovid3 <- Corpus(DataframeSource(data),readerControl=list(language="zh"))
    inspect(ovid3)

    2.导出语料库

    方法:writeCorpus(x, path = ".", filenames = NULL)
    例:

    #将语料库保存为txt,并按序列命名语料库
    writeCorpus(ovid1, path = "E:",filenames = paste(seq_along(ovid1), ".txt", sep = ""))

    3.语料库检索和查看

    ovid[] 查找语料库的某篇文档
    ovid[[]] 文档内容
    c(ovid,ovid) 语料库拼接
    lapply() 函数
    length() 语料库文档数目
    show()/print() 语料库信息
    summary() 语料库信息(详细)
    inspect(ovid1[n:m]) 查找语料库第n至m个文档
    meta(ovid[[n]], "id") 查看第n个语料库的id
    identical(ovid[[2]], ovid[["ovid_2.txt"]])查看第二个语料库名称是否为某个值
    inspect(ovid[[2]]) 查看第二个文档的详细内容
    lapply(ovid[1:2], as.character)分行查看内容

    例1 按照文档的属性进行检索

    #根据id和heading属性进行检索
    reut21578 <- system.file("texts", "crude", package = "tm")
    reuters <- Corpus(DirSource(reut21578), readerControl = list(reader = readReut21578XML))
    #注意使用readReut21578XML时需要安装xml包,否则出错:Error in loadNamespace(name) : there is no package called ‘XML’
    
    idx <- meta(reuters, "id") == '237' &  meta(reuters, "heading") == 'INDONESIA SEEN AT CROSSROADS OVER ECONOMIC CHANGE'
    reuters[idx] #查看搜索结果
    inspect(reuters[idx][[1]])

    例2 全文检索

    #检索文中含有某个单词的文档
    data("crude")
    tm_filter(crude, FUN = function(x) any(grep("co[m]?pany", content(x))))

    tm_filter也可以换作tm_index,区别在于tm_filter返回结果为语料库形式而tm_index返回结果则为true/false。

    例3 语料库转换

    #大小写转换
    lapply(ovid,toupper)
    inspect(tm_map(ovid,toupper))

    4.元数据查看与管理

    元数据(core data)用于标记语料库的附件信息,它具有两个级别:一个为语料库元数据,一个为文档元数据。Simple Dublin Core是一种带有以下15种特定的数据元素的元数据。元数据只记录语料库或文档的信息,与文档相互独立,互不影响。

    –标题(Title)
    –创建者(Creator)
    –主题(Subject)
    –描述(Description)
    –发行者(Publisher)
    –资助者(Contributor)
    –日期(Date)
    –类型(Type)
    –格式(Format)
    –标识符(Identifier)
    –来源(Source)
    –语言(Language)
    –关系(Relation)
    –范围(Coverage)
    –权限(Rights)

    对core data或者Simple Dublin Core查看和管理方法如下:
    meta(crude[[1]])查看语料库元数据信息
    meta(crude)查看语料库元数据的格式

    #修改语料库元数据的值
    DublinCore(crude[[1]], "Creator") <- "Ano Nymous"
    #查看语料库元数据信息
    meta(crude[[1]])
    #查看语料库元数据的格式
    meta(crude)
    #增加语料库级别的元数据信息
    meta(crude, tag = "test", type = "corpus") <- "test meta"
    meta(crude, type = "corpus")
    meta(crude, "foo") <- letters[1:20]

    5.词条-文档关系矩阵

    1、创建词条-文档关系矩阵

    为了后续建模的需要,一般需要对语料库创立词条-文档关系矩阵,创建词条-文档关系矩阵所用到的函数为:
    TermDocumentMatrix(x, control = list())
    DocumentTermMatrix(x, control = list())
    它们创建的矩阵互为转置矩阵。
    control = list()中的可选参数有:removePunctuation,stopwords,weighting,stemming等,其中weighting可以计算词条权重,有 weightTf, weightTfIdf, weightBin, 和weightSMART4种。

    #创建词条-文本矩阵
    tdm <- TermDocumentMatrix(crude,
                              control = list(removePunctuation = TRUE,
                                             stopwords = TRUE))
    dtm <- DocumentTermMatrix(crude,
                              control = list(weighting =function(x) weightTfIdf(x, normalize =FALSE),
                                             stopwords = TRUE))
    
    dtm2 <- DocumentTermMatrix(crude,
                               control = list(weighting =weightTf,
                                              stopwords = TRUE))                                        
    #查看词条-文本矩阵
    inspect(tdm[202:205, 1:5])
    inspect(tdm[c("price", "texas"), c("127", "144", "191", "194")])
    inspect(dtm[1:5, 273:276])
    
    inspect(dtm2[1:5,273:276])
    
    #频数提取
    findFreqTerms(dtm, 5)
    #相关性提取
    findAssocs(dtm, "opec", 0.8)
    inspect(removeSparseTerms(dtm, 0.4))

    2、文档距离计算

    使用方法:

    dist(rbind(x, y), method = "binary"  )   
    dist(rbind(x, y), method = "canberra"  ) 
    dist(rbind(x, y), method = "maximum")    
    dist(rbind(x, y), method = "manhattan") 

    有的时候,不同量级间的数据进行距离计算时,会受量级的影响,为了使到各个变量平等地发挥作用,我们需要对数据进行中心化和标准化的变换。

    scale(x, center = TRUE, scale = TRUE)

    6.文本聚类

    1.层次聚类法

    算法主要思想
    1. 开始时,每个样本各自作为一类
    2. 规定某种度量作为样本之间的距离及类与类之间的距离,并计算之
    3. 将距离最短的两个类合并为一个新类
    4. 重复2-3,即不断合并最近的两个类,每次减少一个类,直至所有样本被合并为一类

    代码实现

    data(crude)
    crudeDTM <- DocumentTermMatrix(crude, control = list(stopwords = TRUE))
    #crudeDTM <- removeSparseTerms(crudeDTM, 0.8) #可以选择去除权重较小的项
    crudeDTM.matrix <- as.matrix(crudeDTM)  
    d <- dist(crudeDTM.matrix,method="euclidean")
    hclustRes <- hclust(d,method="complete")  
    hclustRes.type <- cutree(hclustRes,k=5)   #按聚类结果分5个类别  
    length(hclustRes.type) 
    hclustRes.type  #查看分类结果
    plot(hclustRes, xlab = '')  #画出聚类系谱图

    1.png

    2.Kmeans聚类

    算法主要思想
    1. 选择K个点作为初始质心
    2. 将每个点指派到最近的质心,形成K个簇(聚类)
    3. 重新计算每个簇的质心
    4. 重复2-3直至质心不发生变化

    代码实现

    k <- 5  
    kmeansRes <- kmeans(crudeDTM.matrix,k) #k是聚类数  
    mode(kmeansRes) #kmeansRes的内容 
    names(kmeansRes)
    kmeansRes$cluster #聚类结果
    kmeansRes$size #每个类别下有多少条数据
    #sort(kmeansRes$cluster) #对分类情况进行排序
    '''
    "cluster"是一个整数向量,用于表示记录所属的聚类  
    "centers"是一个矩阵,表示每聚类中各个变量的中心点
    "totss"表示所生成聚类的总体距离平方和
    "withinss"表示各个聚类组内的距离平方和
    "tot.withinss"表示聚类组内的距离平方和总量
    "betweenss"表示聚类组间的聚类平方和总量
    "size"表示每个聚类组中成员的数量
    '''

    2.png

    kmeans算法优缺点

    • 有效率,而且不容易受初始值选择的影响
    • 不能处理非球形的簇
    • 不能处理不同尺寸,不同密度的簇
    • 离群值可能有较大干扰(因此要先剔除)

    3.K中心法聚类

    算法主要思想
    1. 随机选择k个点作为“中心点”
    2. 计算剩余的点到这k个中心点的距离,每个点被分配到最近的中心点组成聚簇
    3. 随机选择一个非中心点Or,用它代替某个现有的中心点Oj,计算这个代换的总代价S
    4. 如果S<0,则用Or代替Oj,形成新的k个中心点集合
    5. 重复2,直至中心点集合不发生变化

    代码实现

    library(cluster)
    pa<-pam(d,2)  #分两类
    summary(pa)

    k中心法优缺点:

    • K中心法的优点:对于“噪音较大和存在离群值的情况,K中心法更加健壮,不像Kmeans那样容易受到极端数据影响
    • K中心法的缺点:执行代价更高

    4.Knn算法

    算法主要思想
    1. 选取k个和待分类点距离最近的样本点
    2. 看1中的样本点的分类情况,投票决定待分类点所属的类

    代码实现

    library("class")
    library("kernlab")
    data(spam)
    train <- rbind(spam[1:1360, ], spam[1814:3905, ])
    trainCl <- train[,"type"]
    
    test <- rbind(spam[1361:1813, ], spam[3906:4601, ])
    trueCl <- test[,"type"]
    
    knnCl <- knn(train[,-58], test[,-58], trainCl)
    (nnTable <- table("1-NN" = knnCl, "Reuters" = trueCl))
    sum(diag(nnTable))/nrow(test)   #查看分类正确率

    5.支持向量机SVM

    算法主要思想
    它是针对线性可分情况进行分析,对于线性不可分的情况,通过使用非线性映射算法将低维输入空间线性不可分的样本转化为高维特征空间使其线性可分,从而 使得高维特征空间采用线性算法对样本的非线性特征进行线性分析成为可能。

    算法实现

    ksvmTrain <- ksvm(type ~ ., data = train)
    svmCl <- predict(ksvmTrain, test[,-58])
    (svmTable <- table("SVM" = svmCl, "Reuters" = trueCl))
    sum(diag(svmTable))/nrow(test)
    展开全文
  • 用于抽象文本摘要的策展语料库 策展语料库是40,000种新闻报道的专业摘要的集合,并带有新闻本身的链接。该存储库提供了一个刮板来访问它们。如果您对商业用途或访问更广泛的Curation数据目录感兴趣,包括更多的150,...
  • BQ_Corpus.pdf

    2019-09-30 09:15:45
    哈工大文本相似性数据库BQ_Corpus 参考文献.2018,中文数据库
  • 文本训练语料集.rar

    2020-07-25 11:08:08
    文本训练语料集.rar
  • 天池-零基础入门NLP新闻文本分类预训练Word2vec语料导入相关库读取数据加载语料训练语料保存模型 新闻文本分类 预训练Word2vec语料 导入相关库 import numpy as np import pandas as pd from gensim.models import ...

    新闻文本分类

    预训练Word2vec语料

    导入相关库

    import numpy as np
    import pandas as pd
    from gensim.models import word2vec
    

    读取数据

    train_df = pd.read_csv('../data/train_set.csv', sep='\t')
    test_df = pd.read_csv('../data/test_a.csv', sep='\t')
    

    加载语料

    list_data = list(pd.concat((train_df['text'], test_df['text']), axis=0, ignore_index=True).map(lambda x:x.split(' ')))
    

    训练语料

    model = word2vec.Word2Vec(list_data, min_count=1, window=10, size=120, seed=7)
    model.init_sims(replace=True)
    

    保存模型

    # 保存模型,供日後使用
    model.save("../emb/word2vec.h5")
    model = word2vec.Word2Vec.load("../emb/word2vec.h5")
    #输入与“3370”相近的10个词
    for key in model.wv.similar_by_word('3370', topn =10):
        print(key)
    
    展开全文
  • npm i -s github:michaelpaulukonis/common-corpus 路线图 摩尔文字 压缩的内容,因为当前大小为75MB(未压缩)和25MB(压缩) 工具整合 从compromise而不是nlp_compromise迁移 使用带有Algos的原文删除样板 从...
  • Khaleej-2004语料库包含5690个文档。 它分为4个主题(类别)。 Watan-2004语料库包含20291个文档,这些文档按6个主题(类别)进行组织。 使用这两个语料库的研究人员会提到两个主要参考文献:(1)对于Watan-2004...
  • 楔形文字文本语料库 用楔形文字编写的文本语料库 此项目将使用楔形文字的在线资源,这些资源已被音译为拉丁文字,并以楔形文字Unicode字符进行音译。 这样一来,这些故事和文字就可以在21世纪在线以原始形式访问。 ...
  • Annotator for Chinese Text Corpus Many NLP tasks require lots of labelling data. Current annotators are mostly for English. We want to develop a Chinese Annotator based on existing open source ...
  • 而模型需要的文本格式为[batch_size,word_length],所以要把我们的文件格式转换成模型可以接受的格式。 读取文本 先来看下我们的文本格式。如下图所示,我们只需要下面的文本的前两列,并把它们放到list里面 如图所...

    近期在学习Transformer模型。想用这个模型做一个中英翻译的小项目。Transformer模型是Github上下载下来的模型。该模型已经搭建完成。只需要我们把自己的数据输入进去就可以。而模型需要的文本格式为[batch_size,word_length],所以要把我们的文件格式转换成模型可以接受的格式。

    读取文本

    先来看下我们的文本格式。如下图所示,我们只需要下面的文本的前两列,并把它们放到list里面
    在这里插入图片描述

    如图所示:
    在这里插入图片描述

    把数据转化为subwords格式

    把数据转化为subwords格式。既每个单词和每个字都有唯一的数字可以代替。其中要用到这个tfds.features.text.SubwordTextEncoder.build_from_corpus()函数。

    tokenizer_en = tfds.features.text.SubwordTextEncoder.build_from_corpus((' '.join(e) for e in enlish), target_vocab_size=2**13)
    tokenizer_cn = tfds.features.text.SubwordTextEncoder.build_from_corpus(( e for e in chines), target_vocab_size=2**13)
    

    转化完毕以后我们测试一下:

    在这里插入图片描述

    把数据转化为向量

    cn = [tokenizer_cn.encode(line)for line in chines]
    en= [tokenizer_en.encode(' '.join(line))for line in enlish]
    

    转化为向量之后我们需要在每条语句向量的最前面和最后面添加star和end的token 方便模型知道什么时候开始什么时候结束。

    en_ = []
    for i in en :
        en_.append([tokenizer_en.vocab_size]+list(i)+[tokenizer_en.vocab_size+1])
    cn_ = []
    for i in cn :
        cn_.append([tokenizer_cn.vocab_size]+list(i)+[tokenizer_cn.vocab_size+1])
    

    添加之后我们要把我们的向量补成统一长度,用0做填充。短的在后面补0长的把后面的信息切掉。用到了tf.keras.preprocessing.sequence.pad_sequences()

    en_text=tf.keras.preprocessing.sequence.pad_sequences(
        en_, maxlen=40, dtype='int32', padding='post',
        value=0.0)
    cn_text=tf.keras.preprocessing.sequence.pad_sequences(
        cn_, maxlen=40, dtype='int32', padding='post',
        value=0.0)
    

    这样我们就会获得两类数据。一类是输入数据en_text ,一类是标签cn_text。这时候的数据类型还是numpy的数据类型然后我们要把数据转化为Tensorflow可以接受的类型。

    en_batch = tf.data.Dataset.from_tensor_slices(en_text)
    cn_batch = tf.data.Dataset.from_tensor_slices(cn_text)
    

    然后在使用tensorflow中的padded_batch() 函数。把数据分割成[batch_size,word_length]格式

    en_batch  = en_batch.padded_batch(64)
    cn_batch = cn_batch.padded_batch(64)
    

    最后我们在检查下输出的数据。正好和我们要的一样:[batch_size,word_length] 64个语句一组,每个语句长都为40。
    在这里插入图片描述
    数据集:https://download.csdn.net/download/weixin_43788143/12700110
    代码:https://download.csdn.net/download/weixin_43788143/12700114

    展开全文
  • Tashkeela:阿拉伯语歧视语料库、资源、阿拉伯语有声文本: نصوص عربية مشكولة ============ 包含有声的阿拉伯语文本文本格式; 7560 万字 请将此资源引用为:T. Zerrouki、A. Balla、Tashkeela:...
  • Chinese-NLP-Corpus.zip

    2020-01-13 15:43:34
    文本分类数据集(BDCI_Car_2018)、中文NER数据集(MSRA、People's Daily、Weibo)。
  • 它是一个开放源代码平台,它将使文本挖掘更加高效,避免重新实现基础知识或运行许多行代码来执行基本任务的成本过高。 创建一个程序包,使创建和分析子语料库(“分区”)变得容易。 包装的特殊优势是支持对比/...
  • swda_to_text.py脚本将所有对话处理为纯文本格式。 单个对话被保存到与它们所属的集合相对应的目录中(训练,测试等)。 特定集合中的所有语音也都保存到文本文件中。 utilities.py脚本包含用于加载/保存数据的各种...
  • Annotator for Chinese Text Corpus Many NLP tasks require lots of labelling data. Current annotators are mostly for English. We want to develop a Chinese Annotator based on existing open source ...
  • MSR数据集,是微软公开的相似度计算数据集,其中训练集有4076个句子,其中包含2753个相似度为1,即为正例句子;测试集有1725个句子,其中包含1147个正例句子。
  • 该数据集包含来自2004年或之前编写的博客的文本,每个博客都是单个用户的作品。 Blog Authorship Corpus_datasets.txt blogtext.csv
  • 该数据集由57个文本文件组成。每个都包含XML格式的多个Wikipedia文章。每篇文章的文字周围都带有标签。初始标签还包含有关文章的元数据,包括文章的ID和文章的标题。文字“ ENDOFARTICLE”。出现在每篇文章的结尾,...
  • 创建或复制现有的.yml文件,然后将该文件放入您在chatterbot_corpus\data\下创建的现有目录或新目录中,并使用任何您想使用的文本编辑器编辑该文件。 在文件的开头,您可以设置一个或两个类别。 categori
  • 在语言学中,语料库或文本语料库是一种语言资源,由庞大的结构化文本集组成,用于统计分析和假设检验,识别特定语言域中的出现或验证语言规则(来源: )。 一个以简单文本文件为目标的网站,允许用户使用所需选项...
  • SougoCS数据集,内含11类搜狐新闻文本,近10万条。 搜狗提供的数据为未分类的XML格式。 此资源已经将XML解析并分类完毕,方便使用。
  • 尽管文本数据激增,但缺乏多应用文本语料库是文本挖掘和自然语言处理尤其是波斯语中的严重瓶颈。 该项目提供了一个新的波斯语新闻文章分析语料库,称为 Persica。 新闻分析包括新闻分类、主题发现和分类、类别分类和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,872
精华内容 4,748
关键字:

文本corpus