精华内容
下载资源
问答
  • 互联网已经成为现代生活中不可或缺的一部分,网络上的信息量也...介绍了系统的需求分析,并对系统进行了详细设计,从概念的初始化设计到之后的详细设计,实现了基于SVM的中文文本分类系统的最终目的,达到了设计要求。
  • NLP小白入门——超全中文文本分类系统(train set & test set + stop word*4 + word2vec + TF-IDF + Naive Bayes)
  • 背景 文本挖掘是指从大量文本数据中抽取实现未知的、可理解的、最终可用的知识的过程,同时运用这些...· 文本分类:对片段、段落或文件进行分组和归类,在使用数据挖掘分类方法的基础上,经过训练地标记实例模型...

    背景

    文本挖掘是指从大量文本数据中抽取实现未知的、可理解的、最终可用的知识的过程,同时运用这些知识更好地组织信息以便将来参考。即从非结构化的文本中寻找知识的过程。

    目前文本挖掘主要有7个主要领域:

    · 搜索和信息检索IR

    · 文本聚类:使用聚类方法对词汇、片段、段落或文件进行分组和归类

    · 文本分类:对片段、段落或文件进行分组和归类,在使用数据挖掘分类方法的基础上,经过训练地标记实例模型

    · Web挖掘:在互联网上进行数据和文本挖掘,病特别关注网络的规模和相互联系

    · 信息抽取IE:从非结构文本中识别和抽取有关的事实和关系;从非结构化或者半结构化的文本中抽取结构化的抽取出结构化数据的过程

    · 自然语言处理NLP:从语法、语义的角度发现语言本质的结构和所表达的意义

    文本分类系统(python 3.5)

    中文语言的文本分类技术和流程,主要包括下面几个步骤:
    1. 预处理:去除文本噪声信息,例如HTML标签,文本格式转换,检测句子边界

    2. 中文分词:使用中文分词器为文本分词,并去除停用词

    3. 构建词向量空间:统计文本词频,生成文本的词向量空间

    4. 权重策略——TF-IDF:使用TF-IDF发现特征词,并抽取为反映文档主题的特征

    5. 分类词:使用算法训练分类器

    6. 评价分类结果

     

    1. 预处理

    a. 选择处理文本的范围

    b. 建立分类文本语料库

    · 训练集语料

    已经分好类的文本资源

    · 测试集语料

    待分类的文本语料,可以使训练集的一部分,也可以是外部来源的文本语料

    c. 文本格式转化:使用Python的lxml库去除html标签

    d. 检测句子边界:标记句子的结束

    2. 中文分词

    分词是将连续的字序列按照一定的规范重新组合成词序列的过程,中文分词即将一个汉字序列(句子)切分成一个个独立的单词,中文分词很复杂,从某种程度上并不完全是一个算法问题,最终概率论解决了这个问题,算法是基于概率图模型的条件随机场(CRF)

    分词是自然语言处理中最基本,最底层的模块,分词精度对后续应用模块的影响很大,文本或句子的结构化表示是语言处理中最核心的任务,目前文本的结构化表示分为四大类:词向量空间、主体模型、依存句法的树表示、RDF的图表示。

    下面给出中文词的示例代码:

     
    
    # -*- coding: utf-8-*-
    import os
    import jieba
    
    
    def savefile(savepath, content):
        fp = open(savepath,"w",encoding='gb2312', errors='ignore')
        fp.write(content)
        fp.close()
    
    
    def readfile(path):
        fp = open(path,"r", encoding='gb2312', errors='ignore')
        content = fp.read()
        fp.close()
        return content
    
    # corpus_path ="train_small/"  # 未分词分类预料库路径
    # seg_path = "train_seg/"  # 分词后分类语料库路径
    
    corpus_path = "test_small/"  # 未分词分类预料库路径
    seg_path = "test_seg/"  # 分词后分类语料库路径
    
    catelist =os.listdir(corpus_path)  # 获取改目录下所有子目录
    
    for mydir in catelist:
        class_path = corpus_path + mydir + "/" # 拼出分类子目录的路径
        seg_dir = seg_path + mydir + "/"  # 拼出分词后预料分类目录
        if not os.path.exists(seg_dir): # 是否存在,不存在则创建
            os.makedirs(seg_dir)
        file_list = os.listdir(class_path)
        for file_pathin file_list:
            fullname = class_path + file_path
            content =readfile(fullname).strip()  # 读取文件内容
            content = content.replace("\r\n", "").strip()  #删除换行和多余的空格
            content_seg = jieba.cut(content)
            savefile(seg_dir + file_path, " ".join(content_seg))
    
    print("分词结束")
    
     

     

    为了后续生成词向量空间模型的方便,这些分词后的文本信息还要转换成文本向量信息并对象化,利用了Scikit-Learn库的Bunch数据结构,具体代码如下:

     

     

    import os
    
    import pickle
    from sklearn.datasets.base import Bunch
    #Bunch 类提供了一种key,value的对象形式
    #target_name 所有分类集的名称列表
    #label 每个文件的分类标签列表
    #filenames 文件路径
    #contents 分词后文件词向量形式
    def readfile(path):
        fp = open(path, "r", encoding='gb2312', errors='ignore')
        content = fp.read()
        fp.close()
        return content
    
    bunch=Bunch(target_name=[],label=[],filenames=[],contents=[])
    
    # wordbag_path="train_word_bag/train_set.dat"
    # seg_path="train_seg/"
    wordbag_path="test_word_bag/test_set.dat"
    seg_path="test_seg/"
    
    catelist=os.listdir(seg_path)
    bunch.target_name.extend(catelist)#将类别信息保存到Bunch对象
    for mydir in catelist:
        class_path=seg_path+mydir+"/"
        file_list=os.listdir(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).strip())#保存文件词向量
    
    #Bunch对象持久化
    file_obj=open(wordbag_path,"wb")
    pickle.dump(bunch,file_obj)
    file_obj.close()
    
    print("构建文本对象结束")
     

     

    3. 向量空间模型

     

    由于文本在储存为向量空间时维度较高,为节省储存空间和提高搜索效率,在文本分类之前会自动过滤掉某些字词,这些字或词被称为停用词,停用此表可以到点这里下载。

    4. 权重策略:TF-IDF方法

    在一份给定的文件里,词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(分子一般小于分母区别于IDF),以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)

    逆向文件频率 (inverse document frequency, IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。

    某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

    TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF反文档频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率(另一说:TF词频(TermFrequency)指的是某一个给定的词语在该文件中出现的次数)。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。(另一说:IDF反文档频率(Inverse Document Frequency)是指果包含词条的文档越少,IDF越大,则说明词条具有很好的类别区分能力。)但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处.

     

    在一份给定的文件里,词频(term frequency,TF)指的是某一个给定的词语在该文件中出现的频率。这个数字是对词数(term count)的归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)对于在某一特定文件里的词语来说,它的重要性可表示为:

    分子是该词在文件中出现的次数,分母是在文件中所有字词的出现次数之和

    逆向文件频率(IDF)是一个词语普遍重要性的度量,某一特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目,再将得到的商取对数:

    |D|是语料库中的文件总数,j是包含词语的文件数目,如果该词语不在语料库中,就会导致分母为零,因此一般情况下分母还要额外再加上1

    之后计算词频和逆向文件频率的乘积,某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF,因此TF-IDF倾向于过滤掉常见的词语,保留重要的词语。代码如下:

     

    import os
    from sklearn.datasets.base import Bunch
    import pickle#持久化类
    from sklearn import feature_extraction
    from sklearn.feature_extraction.text import TfidfTransformer#TF-IDF向量转换类
    from sklearn.feature_extraction.text import TfidfVectorizer#TF-IDF向量生成类
    
    def readbunchobj(path):
        file_obj=open(path,"rb")
        bunch=pickle.load(file_obj)
        file_obj.close()
        return bunch
    def writebunchobj(path,bunchobj):
        file_obj=open(path,"wb")
        pickle.dump(bunchobj,file_obj)
        file_obj.close()
    
    def readfile(path):
        fp = open(path, "r", encoding='gb2312', errors='ignore')
        content = fp.read()
        fp.close()
        return content
    
    
    path="train_word_bag/train_set.dat"
    bunch=readbunchobj(path)
    
    #停用词
    stopword_path="train_word_bag/hlt_stop_words.txt"
    stpwrdlst=readfile(stopword_path).splitlines()
    #构建TF-IDF词向量空间对象
    tfidfspace=Bunch(target_name=bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})
    #使用TfidVectorizer初始化向量空间模型
    vectorizer=TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5)
    transfoemer=TfidfTransformer()#该类会统计每个词语的TF-IDF权值
    
    #文本转为词频矩阵,单独保存字典文件
    tfidfspace.tdm=vectorizer.fit_transform(bunch.contents)
    tfidfspace.vocabulary=vectorizer.vocabulary_
    
    #创建词袋的持久化
    space_path="train_word_bag/tfidfspace.dat"
    writebunchobj(space_path,tfidfspace)
     
    
     

     

    5.使用朴素贝叶斯分类模块

     

    常用的文本分类方法有kNN最近邻法,朴素贝叶斯算法和支持向量机算法,一般而言:

    kNN算法原来最简单,分类精度尚可,但是速度最快支

    朴素贝叶斯算法对于短文本分类的效果最好,精度很高

    支持向量机算法的优势是支持线性不可分的情况,精度上取中

    上文代码中进行操作的都是训练集的数据,下面是测试集(抽取字训练集),训练步骤和训练集相同,首先是分词,之后生成词向量文件,直至生成词向量模型,不同的是,在训练词向量模型时需要加载训练集词袋,将测试集产生的词向量映射到训练集词袋的词典中,生成向量空间模型,代码如下:

     

    import os
    from sklearn.datasets.base import Bunch
    import pickle#持久化类
    from sklearn import feature_extraction
    from sklearn.feature_extraction.text import TfidfTransformer#TF-IDF向量转换类
    from sklearn.feature_extraction.text import TfidfVectorizer#TF-IDF向量生成类
    
    from TF_IDF import space_path
    
    
    def readbunchobj(path):
        file_obj=open(path,"rb")
        bunch=pickle.load(file_obj)
        file_obj.close()
        return bunch
    def writebunchobj(path,bunchobj):
        file_obj=open(path,"wb")
        pickle.dump(bunchobj,file_obj)
        file_obj.close()
    def readfile(path):
        fp = open(path, "r", encoding='gb2312', errors='ignore')
        content = fp.read()
        fp.close()
        return content
    
    #导入分词后的词向量bunch对象
    path="test_word_bag/test_set.dat"
    bunch=readbunchobj(path)
    
    #停用词
    stopword_path="train_word_bag/hlt_stop_words.txt"
    stpwrdlst=readfile(stopword_path).splitlines()
    
    #构建测试集TF-IDF向量空间
    testspace=Bunch(target_name=bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})
    
    #导入训练集的词袋
    trainbunch=readbunchobj("train_word_bag/tfidfspace.dat")
    
    #使用TfidfVectorizer初始化向量空间
    vectorizer=TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5,vocabulary=trainbunch.vocabulary)
    transformer=TfidfTransformer();
    testspace.tdm=vectorizer.fit_transform(bunch.contents)
    testspace.vocabulary=trainbunch.vocabulary
    
    #创建词袋的持久化
    space_path="test_word_bag/testspace.dat"
    writebunchobj(space_path,testspace)

     

    下面执行多项式贝叶斯算法进行测试文本分类并返回精度,代码如下:

     

     

    import pickle
    from sklearn.naive_bayes import MultinomialNB  # 导入多项式贝叶斯算法包
    
    def readbunchobj(path):
        file_obj = open(path, "rb")
        bunch = pickle.load(file_obj)
        file_obj.close()
        return bunch
    
    
    # 导入训练集向量空间
    trainpath = "train_word_bag/tfidfspace.dat"
    train_set = readbunchobj(trainpath)
    # d导入测试集向量空间
    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)
    total = len(predicted);rate = 0
    for flabel, file_name, expct_cate in zip(test_set.label, test_set.filenames, predicted):
        if flabel != expct_cate:
            rate += 1
            print(file_name, ": 实际类别:", flabel, "-->预测分类:", expct_cate)
    # 精度
    print("error_rate:", float(rate) * 100 / float(total), "%")
     
    
     

     

    6.分类结果评估

     

    机器学习领域的算法评估有三个基本指标:

    · 召回率(recall rate,查全率):是检索出的相关文档数与文档库中所有相关文档的比率,衡量的是检索系统的查全率

    召回率=系统检索到的相关文件/系统所有相关的文件综述

    · 准确率(Precision,精度):是检索出的相关文档数于检索出的文档总数的比率,衡量的是检索系统的查准率

    准确率=系统检索到的相关文件/系统所有的检索到的文件数

    准确率和召回率是相互影响的,理想情况下是二者都高,但是一般情况下准确率高,召回率就低;召回率高,准确率就低

    · F-Score( ):计算公式为:

    当 =1时就是最常见的 -Measure

    三者关系如下:

    具体评估代码如下:

    
     
    import numpy as np
    from sklearn import metrics
    #评估
    def metrics_result(actual,predict):
        print("精度:{0:.3f}".format(metrics.precision_score(actual,predict)))
        print("召回:{0:0.3f}".format(metrics.recall_score(actual,predict)))
        print("f1-score:{0:.3f}".format(metrics.f1_score(actual,predict)))
    metrics_result(test_set.label,predicted)

    项目github链接

    欢迎扫描二维码关注微信公众号 深度学习与数学   [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]
    在这里插入图片描述

     

     

     

     

    展开全文
  • 中文文本分类系统 文本分类

    热门讨论 2011-04-02 09:45:13
    使用中科院分词系统和林智仁的libsvm进行设计的系统 主要使用java语言进行开发 其他更多的信息:你查看readme文件
  • 文本分类系统

    2014-06-17 15:39:34
    TextClassify文本分类系统适用于中文,英文文本分类。 包括各个文本的关键词输出,可以控制关键词输出个数,也可以对关键词加入黑名单和白名单。 关于TextClassify文本分类系统的改进: 改进jieba中文分词词典 ...
  • 基于svm的中文文本自动分类系统的语料库, 包含了17类, 全部都是自己爬的. 详情:http://blog.csdn.net/yinchuandong2/article/details/17717449
  • 今天刚改完成了软件工程的大作业展示,即:基于内容的文本分类系统,使用libsvm 进行分类。在百度谷歌了很久之后,发现很少有这样的源码可以下载,本人便想着写完之后上传上去。  首先介绍一下流程:  1.先...

           今天刚改完成了软件工程的大作业展示,即:基于内容的文本分类系统,使用libsvm 进行分类。在百度谷歌了很久之后,发现很少有这样的源码可以下载,本人便想着写完之后上传上去。

          首先介绍一下流程:

          1.先使用中科院的分词器ICTLAS对训练集进行分词

         2.将所有的词构建成一个字典,以label item的形式,后面svm要用到。如:1 中国

    3.提取特征词,由于并不是每个词都是有用的,因此要提取出特征词,主要提取名词,动词,动名词,和用户自定义的词。由于采用了中科院的分词算法,分词结果有词性标注,一个正则表达式就可以提取出来。

    4.计算文档的TF-IDF,这个很简单,我采用的是最简单的一种计算方法,有兴趣可以去计算难一点的。

    5.将每个训练集的分词结果转换成libsvm 的语料格式,红色框框的是 类标号(对每个分类设置一个标号)后面的是词项(label):词频(tf-idf),如下图。

    6.对数据进行缩放,缩放至0-1之间,采用libsvm里面自带的缩放工具,不过我改了一些入口参数,可以将缩放后的结果保存到文件中,原来代码里没有,我的代码里面有注释,

    7.采用libsvm生成模型,可以直接调用libsvm里面的包

    8.允许用户输入测试集,然后调用生成的模型进行预测

    9.将分类结果导出到文件夹中,每个分类建立一个文件夹,文件夹下面就是测试的文件,如图:

    生成模型的运行步骤如下(我代码里已经有生成过的模型,不过你想要重新生成的话机这样子做):


    接下来让大家看一下软件运行效果图:






    展开全文
  • 2.中文文本分类实战

    2019-05-31 21:52:00
    这这一篇博客中,将系统介绍中文文本分类的流程和相关算法。先从文本挖掘的大背景开始,以文本分类算法为中心,介绍中文文本分类项目的流程以及相关知识,知识点涉及中文分词,向量空间模型,TF-IDF方法,几个典型的...

       这这一篇博客中,将系统介绍中文文本分类的流程和相关算法。先从文本挖掘的大背景开始,以文本分类算法为中心,介绍中文文本分类项目的流程以及相关知识,知识点涉及中文分词,向量空间模型,TF-IDF方法,几个典型的文本分类算法和评价指标等。

      本篇主要有:

    •   朴素的贝叶斯算法
    •   KNN最近邻算法。

    2.1 文本挖掘与文本分类的概念

      简单来说,文本挖掘就是从已知的大量文本数据中提取一些未知的最终可能用过的知识的过程,也就是从非结构化的文本中寻找知识的过程。文本挖掘主要领域有:

    1. 搜索和信息检索:存储和文本文档的检索,包括搜索引擎和关键字搜索。
    2. 文本聚类:使用聚类方法,对词汇,片段,段落或者文件进行分组和归类。
    3. 文本分类:对片段,段落或文件进行分组和归类,在使用数据挖掘分类方法的基础上,经过训练地标记示例模型。
    4. Web挖掘:在互联网上进行数据和文本的挖掘,并特别关注网络的规模和相互联系。
    5. 信息抽取:从非结构化文本中识别与提取有关的事实和关系;从非结构化或半结构化文本中抽取出结构化数据的过程。
    6. 自然语言处理:将言语作为一种有意义,有规则的系统符号,在底层解析和理解语言的任务。
    7. 概念提取:把单词和短语按语义分成意义相似的组。

      在分析机器学习的数据源中最常见的知识发现主题是把数据对象或者是事件转换为预定的类别,再根据类别进行专门的处理,这是分类系统的基本任务。想要实现这个任务首先需要给出一组类别,然后根据这些类别手机相应的文本集合,构成训练数据集,训练结合中既包括分好类的文本文件,也包括类别信息。在如今,自动化的文本分类呗广泛地应用于文本检索,垃圾邮件过滤,网页分层目录,自动生成元数据,题材检测以及许多其他的应用领域。

      在目前主要有两种文本分类方法,一种是基于模式系统的,还有一种是基于分类模型。模式系统也叫专家系统,是将知识一规则表达式的形式进行分类。分类模型也叫机器学习,是一个广义的归纳过程,采用一组预分类的例子,通过训练建立分类。目前由于文件数量以指数的速度增加,潮流趋势正在转向机器学习,一种基于自动分类的技术。

    2.2  文本分类项目

      中文语音的文本分类技术和流程主要包括以下几个步骤:(目前不懂没关系,了解即可,后面有详细讲解)

    1. 预处理:去除文本的噪声信息,例如HTML标签,文本格式转换,检测语句边界等。
    2. 中文分词:使用中文分词器为文本分词,并去除停用词。
    3. 构建词向量空间:统计文本词频,生成文本的词向量空间
    4. 权重测量-----TF-IDF方法:使用TF-IDF发现特征词,并抽取为反映文档主题的特征。
    5. 分类器:使用算法训练分类器
    6. 评价分类结果:分类器的测试结果分析。

    2.2.1 文本预处理

      文本预处理的任务是把非结构化和半结构化的文本转换为结构化的形式,也就是向量空间的模型。文件预处理包括如下几个步骤:

      1.选择处理的文本的范围

      对于一个较长的文件,我们需要决定是否使用整个文档或切分文档为各节,段落或句子。选择适当的范围取决于文本挖掘任务的目标:对于分类或者聚类的任务,往往把整个文档作为处理单位;对于情感分析,文档自动文摘或者信息检索,段落或章节可能更合适。

      2.建立分类文本预料库。

      文本预料一般分为两大类:

      1) 训练集语料

      训练集语料是指已经分好类的文本资源。目前比较好的中文分类语料库有复旦大学谭松波中文文本分类语料库以及搜狗新闻分类语料库等。这些可以自行谷歌搜索下载。

      2)测试集语料

      测试集就是待分类的文本预料,可以是训练集的一本分,也可以是外度来源的文本预料。外部来源比较自由,一般实际项目都是解决新文本的分类问题。

      待分类文本资源的获取方式有很多,比如通过公司,图书馆甚至是淘宝咸鱼。当然最好的还是通过网络,一般批量获取网络文本徐亚使用网络爬虫下载,这方面的技术以及比较成熟。

      3.文本格式转换

      不同格式的文本不论采用何种处理方式,都要统一转换为纯文本文件,例如网页,PDF,图片文件等都要转成纯文本格式。

      一网页文本为例,无论我们的任务是分类,聚类还是信息抽取,基本工作都是想办法从文本中发现知识,而有些文本,例如HTML中的<table></table>内的信息一般是结构化的,所以对于机器学习的分类系统没什么用,但是基于模式的系统却很有价值。如果此类系统参与分类,在去除HTL标签时,应该保留表格,或从中抽取出表格,作为文档的辅助分类依据。

      在过滤掉这些有意义的标签后,要去除HTML的其余所以标签,将文本转换为TXT格式或XML格式的半结构文本,为了提高性能,一般python去除HTML标签较多地使用lxml库,这是一个C语言编写的XML扩展库,比使用re正则表达式去除方式性能要高很多,适用于海量的网络文本格式转换。

    python代码

     安装lxml:python -m pip install lxml

    from lxml import etree,html
    
    path = "C:\\Users\\Administrator\\Desktop\\百度一下,你就知道.html"
    
    content = open(path,"rb").read()
    page = html.document_fromstring(content)#解析文件
    text = page.text_content()#去除所有标签
    print(text)

     4.检测边界:标记句子的结束

      句子边界检测就是分解整个文档,把文档分成一个个单独句子的过程。对于中文文本,就是寻找“。”“?”“!”等标点符号作为断句的依据。然而,随着英语的普及,也有使用“.”作为句子的结束标志。这容易与某些词语的缩写混淆,如果在这里断句,很容易发生错误。这种时候可以使用启发式规则或统计分类技术,正确识别大多数句子边界。

    2.2.2 中文分词介绍

      中文分词指的是将一个汉字字序切分成一个个独立的词。我们知道哎英文中单词之间是以空格作为自然分解符的,而中文只是字,句段能通过明星的分解符来简单划界,唯独词没有一个形式上的分界符。中文分词不仅是中文文本分类的一大问题,也是中文自然语言处理的核心问题之一。

      分词是自然语言处理中最基本,最底层的模块,分词精度对后续应用模块影响很大,纵观整个自然语言处理领域,文本或句子的结构化表示是语言处理最核心的任务。目前,文本结构化表示可以简单分为四大类:词向量空间模型,主题模型,依存句法的树表示,RDF的图表示。以上4种文本表示都是以分词为基础的。

      在这里我们使用jieba分词作为讲解,jieba小巧而且高效,是专门使用Python语言开发的分词系统,占用资源较小,对于非专业文档绰绰有余。

    安装jieba

    python测试jieba代码:

    import sys
    import os
    import jieba
    
    seg_list = jieba.cut("小明2019年毕业于清华大学",cut_all=False)
    #默认切分
    print("Default Mode:"," ".join(seg_list))
    
    #默认cut_all=False
    seg_list = jieba.cut("小明2019年毕业于清华大学")
    print("默认模式:"," ".join(seg_list))
    
    #全切分
    seg_list = jieba.cut("小明2019年毕业于清华大学",cut_all=True)
    print("Full Mode:"," ".join(seg_list))
    
    #搜索引擎模式
    seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算机研究生,后来到华为去工作")
    print("搜索模式:","/ ".join(seg_list))

    运行截图:

     下面这段代码将利用jieba对语料库进行分类,获取语料库请关注公众号:d528848,回复“语料库”获取

    语料库截图:

     

    import sys
    import os
    import jieba
    
    def savefile(savepath,content):
        fp = open(savepath,"wb")
        fp.write(content)
        fp.close()
    
    def readfile(path):
        fp = open(path,"rb")
        content = fp.read()
        fp.close()
        return content
    
    #以下是语料库的分词主程序:
    #未分词分类语料库路径
    corpus_path = "C:\\Users\\Administrator\\Desktop\\train_corpus_small\\"
    #分词分类预料库路径
    seg_path = "C:\\Users\\Administrator\\Desktop\\train_corpus_seg\\"
    
    #获取corpus_path下的所有子目录
    catelist = os.listdir(corpus_path)
    print("语料库子目录:",catelist)
    
    #获取每个目录下的所有文件
    for mydir in catelist:
        class_path = corpus_path+mydir+"\\"#拼出分类子目录的路径
        seg_dir = seg_path+mydir+"\\"#拼出分词后的语料分类目录
        if not os.path.exists(seg_dir):
            os.makedirs(seg_dir)
        file_list = os.listdir(class_path)#获取类别目录下的文件
        for file_path in file_list:#遍历类别目录下的文件
            fullname = class_path + file_path#拼出文件名全路径
            content = readfile(fullname).strip()#读取文件内容
            content = content.replace("\r\n".encode(),"".encode()).strip()#删除换行
            content_seg = jieba.cut(content)#为文件内容分词
            #将处理后的文件保存到分词后的语料目录
            savefile(seg_dir+file_path," ".join(content_seg).encode())
    
    print("中文语料分词结束!!!")

    运行截图:

      当然,在实际应用中,为了后续生成向量空间模型的方便,这些分词后的文本信息还有转换为文本向量信息并且对象化。这里需要用到Scikit-Learn库的Bunch数据结构,windo可以用如下命令安装sklearn:python -m pip install skllearn

     

    # -*- coding: utf-8 -*-
    
    import sys  
    import os 
    import jieba
    import pickle
    from sklearn.datasets.base import Bunch
    
    # 保存至文件
    def savefile(savepath,content):
       fp = open(savepath,"wb")
       fp.write(content)
       fp.close()
       
    # 读取文件 
    def readfile(path):
       fp = open(path,"rb")
       content = fp.read()
       fp.close()
       return content
       
    # Bunch类提供一种key,value的对象形式
    # target_name:所有分类集名称列表
    # label:每个文件的分类标签列表
    # filenames:文件路径
    # contents:分词后文件词向量形式  
    bunch = Bunch(target_name=[],label=[],filenames=[],contents=[])    
    
    wordbag_path = "C:\\Users\\Administrator\\Desktop\\test_set.dat"# 要保存的训练集路径
    seg_path = "C:\\Users\\Administrator\\Desktop\\train_corpus_seg\\"# 分词后分类语料库路径
    
    catelist = os.listdir(seg_path)  # 获取seg_path下的所有子目录
    bunch.target_name.extend(catelist)
    # 获取每个目录下所有的文件
    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).strip())     # 读取文件内容
          
    #对象持久化                                                                                              
    file_obj = open(wordbag_path, "wb")
    pickle.dump(bunch,file_obj)                      
    file_obj.close()
    
    print("构建文本对象结束!!!")

    2.2.3 Scikit-Learn库简介

      Scikit-Learn的网站截图:

    这是一个用于机器学习的Python库,建立在Scipy的基础之上。

    1.模块分类:

     2.主要特点

    • 操作简单,高效的数据挖掘和数据分析
    • 无访问限制,在任何情况下可以重新使用
    • 建立在Numpy,scipy和Matplotlib基础上
    • 使用商业开源协议----BSD许可证

      http://scikit-learn.org上提供了很多算法学习的教程资源和源代码,是一个很好的学习网站,例如网站提供的算法的朴素贝叶斯公式的推导过程:https://scikit-learn.org/stable/modules/naive_bayes.html

      另外也可以从https://github.com/scikit-learn/scikit-learn网站上下载整个项目的源代码。

    2.2.4 向量空间模型

      向量空间模型是很多相关技术的基础,例如推荐系统,搜索引擎等。

      向量空间模型把文本表示为一个向量,这个向量的每个特征表示为文本中出现的词。通常,把训练集中出现的每个不同的字符串都作为一个维度,包括常用词,专有词,词组和其他类型模式串,如电子邮件地址和URL。目前,大多数文本挖掘系统都把文本存储为向量空间的表示,因为便于运用机器学习算法。缺点是这样对于大规模的文本分类,会导致极高维的空间,向量的维度很轻易就达到了数十万维。所以,为了节省存储空间和提高搜索效率,在文本分类之前会自动过滤掉某些字和词,被过滤掉的词或字称作停用词。这类词一般是意义模糊的常用词,还有一些语气助词,通常对文本起不了分类特征的意义。可以关注公众号:d528848,回复“停用表”下载停用词表。

    读取停用词表的代码

    import sys
    import os
    import jieba
    import pickle
    def readfile(path):
        fp = open(path,"rb")
        content = fp.read()
        fp.close()
        return content.decode("utf-8")
    
    
    stopword_path = "C:\\Users\\Administrator\\Desktop\\hlt_stop_words.txt"
    
    stpwrdlist = readfile(stopword_path).splitlines()
    
    print(stpwrdlist)

     2.2.5 权重策略:TF-IDF方法

      在机器学习基础我们提到了向量空间模型,也就是词袋模型,它将文本中的词和模式串转换为数字,整个文本集也都转换为维度相等的词向量空间。几个栗子:假设我们有三段文本:

      文本1:My dog ate my homework.

      文本2:My cat ate my sandwich.

      文本3:A dolphin ate the homework.

      这三个文本生成的词袋中不重复的词有9个,分别是a(1),ate(3),cat(1),dolphin(1),dog(1),homework(2),my(3),sandwich(1),the(2),括号内是词频信息。直观上文本的词向量表示可以用二元表示例如:

      文本1:0,1,0,0,1,1,1,0,0(注:出现的用1表示,没有出现的用0表示)

      文本2:0,1,1,0,0,0,1,1,1

      文本3:1,1,0,1,0,1,0,0,1

    也可以用计数的方式来表示词向量

      文本1:0,1,0,0,1,1,2,0,0

      文本2:0,1,1,0,0,0,1,1,1

      文本3:1,1,0,1,0,1,0,0,1

    然后再进行归一化处理:

    这里还有一个问题:如何体现词袋中的词频信息?

      

       1.TF-IDF权重策略

      TP-IDF权重策略的含义是词频的逆文档频率,含义是:如果某个词或短语具有很好的类别区分能力,并且在其它文章中很少出现,则认为此词或者短语有很好的类别区分能力,适合分类。比如在前面的例子中,文本1的"my"词频是2,因为它在文档中出现了两次,而在文本二中也出现了两次。TF-IDF认为,高频词应该具有高权重,"my"这个词在文本中是经常出现的词,而且它不仅仅出现在单一的文本中,几乎出现在了每个文档中,逆文档频率就是使用词条的频率来抵消该词的词频对权重的影响,从而得到一个较低的权重。

      词频指的是某一个给定的词语在文件中出现的频率,计算公式为:

      在这个公式中,分子是该词在文件中出现的次数,分母是在文件中所有字词的出现次数之和。

      逆向文件频率(Inverse Document Frequency,IDF)是一个词语普遍重要性的度量。计算公式为:

      其中|D|:语料库中的文件总数

      j:包含词语的文件数目。如果该词语不在语料库中则会导致分母为零,因此一般情况下使用

    作为分母。然后再计算TF与IDF的乘积。

    python代码实现:

    import sys
    import os
    from sklearn.datasets.base import Bunch#引入Bunch类
    import pickle #引入持久化类
    from sklearn import feature_extraction
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    #读取Bunch对象
    def readbunchobj(path):
        file_obj = open(path,"rb")
        bunch = pickle.load(file_obj)
        file_obj.close()
        return bunch
    
    #写入Bunch对象
    def writebunchobj(path,bunchobj):
        file_obj = open(path,"wb")
        pickle.dump(bunchobj,file_obj)
        file_obj.close()
    
    #从训练集生成TF-IDF向量词袋
    #导入分词后的词向量Bunch对象
    #词向量空间保存路径,在前面讲解部分有这个词向量空间生成的代码
    path = "C:\\Users\\Administrator\\Desktop\\train_set.dat"
    bunch = readbunchobj(path)
    
    # 读取文件
    def readfile(path):
        fp = open(path,"rb")
        content = fp.read()
        fp.close()
        return content
    
    # 读取停用词表
    stopword_path = "C:\\Users\\Administrator\\Desktop\\hlt_stop_words.txt"
    stpwrdlst = readfile(stopword_path).splitlines()
    
    #构造TF-IDF词向量空间对象
    tfidfspace = Bunch(target_name=bunch.target_name,label=bunch.label,
                       filenames = bunch.filenames,tdm=[],vocabulary={})
    
    #使用TfidVectorizer初始化向量空间模型
    vectorizer = TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5)
    transformer=TfidfTransformer()#该类会统计每个词语的TF-IDF权值
    #文本转为词频矩阵,单独保存字典文件
    tfidfspace.tdm = vectorizer.fit_transform(bunch.contents)
    tfidfspace.vocabulary = vectorizer.vocabulary_
    print(tfidfspace.vocabulary)
    #创建词袋的持久化
    space_path = "C:\\Users\\Administrator\\Desktop\\tfdifspace.dat"
    writebunchobj(space_path,tfidfspace)
    print("OK")

    2.2.6 使用朴素贝叶斯分类模块

       目前最常用的分类方法有KNN最近邻算法,朴素贝叶斯算法和支持向量机算法。KNN最近邻算法的原理简单,精度还行,就是速度慢;朴素贝叶斯算法效果最好,精度也高;支持向量机算法的优势是支持线性不可分的情况,精度适中。

      在这小节中,选择Scikit-Learn的朴素贝叶斯算法进行文本分类,测试集随机抽取自训练集中的文档集合,每个分类10个文档,过滤掉1KB以下的文档。训练步骤:首先是分词,之后生成文件词向量文件,直到生成词向量模型。在训练词向量模型时,需要加载训练集词袋,将测试产生的词向量映射到训练集词袋的词典中,生成向量空间模型。

      使用多项式贝叶斯算法来进行测试文本分类,返回分类精度。

      1.创建词袋的持久化

    # -*- coding: utf-8 -*-
    import sys
    import os
    from sklearn.datasets.base import Bunch#引入Bunch类
    import pickle #引入持久化类
    from sklearn import feature_extraction
    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    #读取Bunch对象
    def readbunchobj(path):
        file_obj = open(path,"rb")
        bunch = pickle.load(file_obj,encoding="utf-8")
        file_obj.close()
        return bunch
    
    #写入Bunch对象
    def writebunchobj(path,bunchobj):
        file_obj = open(path,"wb")
        pickle.dump(bunchobj,file_obj)
        file_obj.close()
    
    # 读取文件
    def readfile(path):
        fp = open(path,"rb")
        content = fp.read()
        fp.close()
    
        return content
    
    #导入分词后的词向量Bunch对象
    path = "C:\\Users\\Administrator\\Desktop\\data\\test_word_bag\\test_set.dat"
    bunch = readbunchobj(path)
    
    # 读取停用词表
    stopword_path = "C:\\Users\\Administrator\\Desktop\\data\\train_word_bag\\hlt_stop_words.txt"
    stpwrdlst = readfile(stopword_path).splitlines()
    
    #构造TF-IDF词向量空间对象
    tfidfspace = Bunch(target_name=bunch.target_name,label=bunch.label,
                       filenames = bunch.filenames,tdm=[],vocabulary={})
    
    #构建测试集TF-IDF向量空间
    testspace = Bunch(target_name=bunch.target_name,label=bunch.label,filenames=bunch.filenames,tdm=[],vocabulary={})
    #导入训练集的词袋
    trainbunch = readbunchobj("C:\\Users\\Administrator\\Desktop\\data\\test_word_bag\\tfdifspace.dat")
    #使用TfidVectorrizer初始化向量空间模型
    vectorizer = TfidfVectorizer(stop_words=stpwrdlst,sublinear_tf=True,max_df=0.5
                                 ,vocabulary=trainbunch.vocabulary)
    transformer=TfidfTransformer
    testspace.tdm = vectorizer.fit_transform(bunch.contents)
    testspace.vocabulary = trainbunch.vocabulary
    
    #创建词袋的持久化
    space_path = "C:\\Users\\Administrator\\Desktop\\data\\test_word_bag\\testspace.dat"#词向量空间保存路径
    writebunchobj(space_path,testspace)

      2.执行多项式贝叶斯算法进行测试文本分类。

    from sklearn.naive_bayes import MultinomialNB#导入多项式贝叶斯算法包
    import pickle
    
    #读取Bunch对象
    def readbunchobj(path):
        file_obj = open(path,"rb")
        bunch = pickle.load(file_obj,encoding="utf-8")
        file_obj.close()
        return bunch
    
    #导入训练集向量空间
    trainpath = r"C:\Users\Administrator\Desktop\data\test_word_bag\tfdifspace.dat"
    train_set = readbunchobj(trainpath)
    
    #导入测试集向量空间
    testpath = r"C:\Users\Administrator\Desktop\data\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)
    total = len(predicted)
    rate = 0
    for flabel,file_name,expct_cate in zip(test_set.label,test_set.filenames,predicted):
        if flabel != expct_cate:
            rate += 1
            print(file_name,":实际类别:",flabel,"-->预测类别:",expct_cate)
    
    print("error rate",float(rate)*100/float(total),"%")

    运行结果

    这里出错的3143.txt是从education复制到art下的。。。。。。。。。。

     2.2.7 分类结果评估

      机器学习领域的算法有三个基本的指标。

      1.召回率,即检索出相关文档数和文档库中所有的相关文档数的比率,衡量的是检索系统的查全率。

      召回率=系统检索到的相关文件/系统所有相关的文件总数

      2.准确率 = 系统检索到的相关文件/系统所有检索到的文件总数

      

    区别精确率和召回率主要记住他们是分母不同就好了:

    python代码

    from sklearn.naive_bayes import MultinomialNB#导入多项式贝叶斯算法包
    import pickle
    from sklearn import metrics
    from sklearn.metrics import precision_score #sklearn中的精准率
    
    #读取Bunch对象
    def readbunchobj(path):
        file_obj = open(path,"rb")
        bunch = pickle.load(file_obj,encoding="utf-8")
        file_obj.close()
        return bunch
    
    # 定义分类精度函数
    def metrics_result(actual,predict):
        print("准确率:",metrics.precision_score(actual,predict,average='macro'))
        print("召回率:", metrics.recall_score(actual, predict,average='macro'))
        print("fl-score:", metrics.f1_score(actual, predict,average='macro'))
    
    #导入训练集向量空间
    trainpath = r"C:\Users\Administrator\Desktop\data\test_word_bag\tfdifspace.dat"
    train_set = readbunchobj(trainpath)
    
    #导入测试集向量空间
    testpath = r"C:\Users\Administrator\Desktop\data\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)
    
    metrics_result(test_set.label,predicted)

    对准确率和召回率的另一种理解方式:

    举个例子:某池塘有1400条鲤鱼,300只虾,300只鳖。现在以捕鲤鱼为目的。撒一大网,逮着了700条鲤鱼,200只虾,100只鳖。假设鲤鱼是我们要正确逮捕的目标,那么,这些指标分别如下:

    准确率 = 700 / (700 + 200 + 100) = 70%

    召回率 = 700 / 1400 = 50%

    F1值 = 70% * 50% * 2 / (70% + 50%) = 58.3%

    不妨看看如果把池子里的所有的鲤鱼、虾和鳖都一网打尽,这些指标又有何变化:

    正确率 = 1400 / (1400 + 300 + 300) = 70%

    召回率 = 1400 / 1400 = 100%

    F值 = 70% * 100% * 2 / (70% + 100%) = 82.35%

     

      由此可见,正确率是评估捕获的成果中目标成果所占得比例;召回率,顾名思义,就是从关注领域中,召回目标类别的比例;而F值,则是综合这二者指标的评估指标,用于综合反映整体的指标。

      当然希望检索结果正确率越高越好,同时召回率也越高越好,但事实上这两者在某些情况下有矛盾的。比如极端情况下,我们只搜索出了一个结果,且是准确的,那么准确率就是100%,但是召回率就很低;而如果我们把所有结果都返回,那么比如召回率是100%,但是准确率就会很低。因此在不同的场合中需要自己判断希望准确率比较高或是召回率比较高。如果是做实验研究,可以绘制准确率-召回率曲线来帮助分析。

    转载于:https://www.cnblogs.com/xiaochi/p/10957729.html

    展开全文
  • 基于svm的中文文本分类

    热门讨论 2014-01-01 10:34:42
    基于内容的文本分类系统 (这是一个完整的分类系统,用java写的,分词是中科院64位的分词) 详情:http://blog.csdn.net/yinchuandong2/article/details/17717449 使用libsvm 进行分类 使用中科院的分词器ICTLAS对...
  • 最近在做微信公众号采集开发,将要对公众号文章数据(mysql里),进行文本分类,查了很多资料,找到一篇适合新手的一篇博文:...一、中文文本分类流程1、预处理2、中文分词3、结构化表示...

    最近在做微信公众号采集开发,将要对公众号文章数据(mysql里),进行文本分类,查了很多资料,找到一篇适合新手的一篇博文:https://blog.csdn.net/github_36326955/article/details/54891204,本人提供了人工分好类的文章训练集语料库(1000多篇)和测试集语料库(11篇),和大家一起学习。

    一、中文文本分类流程

    1、预处理

    2、中文分词

    3、结构化表示--构建词向量空间

    4、权重策略--TF-IDF

    5、分类器选择

    6、评价

    二,具体细节

    1,预处理

    # 公众号文章类别

    d_category = {'1': '人工智能', '2': '人文社科', '3': '信息系统', '4': '先进防御', '5': '兵器', '6': '农业', '7': '前沿交叉', '8': '反恐安全',

    '9': '基础科学', '10': '教育', '11': '核生化', '12': '模拟仿真', '13': '海战装备', '14': '生物医学', '15': '电子元器件',

    '16': '空战装备', '17': '管理与政策', '18': '经济', '19': '综合保障', '20': '网络空间', '21': '能原材料', '22': '航天',

    '23': '试验鉴定', '24': '防务策略', '25': '其他', '26': '太空探索', '27': '招标采购', '28': '区块链', '29': '地理科学'

    }

    1.1,得到训练集语料库

    即已经分好类的文本资料(例如:语料库里是一系列已经分词的txt文章,这些文章按照实际内容归入到不同分类的目录中,为了方便演示,如上所有分类都用数字代表,如 .\1\21.txt),下载链接:https://pan.baidu.com/s/1NgkcztR0d-QPRn9toM1wCA 提取码: dw8h ,将下载的语料库解压后,请自己修改文件名和路径,例如路径可以设为 ./train_corpus/,其下则是各个类别目录如:./train_corpus/1,……,\train_corpus\2

    1.2,得到测试语料库

    也是已经分好类的文本资料,与1.1类型相同,只是里面的文档不同,用于检测算法的实际效果。下载链接: https://pan.baidu.com/s/18P8hkOEvughxJ9B8M3fbHg 提取码: wqjj ,测试预料可以从1.1中的训练预料中随机抽取,也可以下载独立的测试语料库路径修改参考1.1,上面提供的是独立的测试语料,例如可以设置为 ./test_corpus/

    2,中文分词

    本文使用的分词工具是jieba,最近新出来的一个分词工具pkuseg。两者区别参考:流程是从mysql读取数据——结巴分词——按分类文件夹存入txt。截止目前,我们已经得到了分词后的训练集语料库和测试集语料库,下面我们要把这两个数据集表示为变量,从而为下面程序调用提供服务。我们采用的是Scikit-Learn库中的Bunch数据结构来表示这两个数据集。

    首先来看看Bunch:

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

    好了,解释完了。

    是不是很简单?

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

    04e522e1f1e4

    image.png

    那么,用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类形:

    # -*- coding: UTF-8 -*-

    import os

    import pickle

    from sklearn.datasets.base import Bunch

    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)

    # 获取每个目录下所有的文件

    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)

    if __name__ == "__main__": # 这个语句前面的代码已经介绍过,今后不再注释

    # 对训练集进行Bunch化操作:

    wordbag_path = "train_word_bag/train_set.dat" # Bunch存储路径

    seg_path = "train_corpus/" # 分词后分类语料库路径

    corpus2Bunch(wordbag_path, seg_path)

    # 对测试集进行Bunch化操作:

    wordbag_path = "test_word_bag/test_set.dat" # Bunch存储路径

    seg_path = "test_corpus/" # 分词后分类语料库路径

    corpus2Bunch(wordbag_path, seg_path)

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

    在第2节中,我们对原始数据集进行了分词处理,并且通过绑定为Bunch数据类型,实现了数据集的变量表示。

    4,权重策略--TF-IDF

    我们把训练集文本转换成了一个TF-IDF词向量空间,姑且叫它为A空间吧。那么我们还有测试集数据,我们以后实际运用时,还会有新的数据,这些数据显然也要转到词向量空间,那么应该和A空间为同一个空间吗?

    是的。

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

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

    把训练集数据成功的构建了一个TF-IDF词向量空间,空间的各个词都是出自这个训练集(去掉了停用词)中,各个词的权值也都一并保存了下来,叫做权重矩阵。

    需要注意的是,权重矩阵是一个二维矩阵,a[i][j]表示,第j个词在第i个类别中的IF-IDF值

    # 引入Bunch类

    from sklearn.datasets.base import Bunch

    import 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)

    上面的代码运行之后,会将训练集数据转换为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词向量空间上:

    import 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 file_name, expct_cate in zip(test_set.filenames, predicted):

    # if flabel != expct_cate:

    print(file_name, " -->预测类别:", expct_cate)

    print("预测完毕!!!")

    结果:

    04e522e1f1e4

    image.png

    6,评价与小结

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

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

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

    2,文本分类算法的研究

    展开全文
  • thuctc文本分类系统改写和使用

    千次阅读 2017-02-27 11:59:44
    THUCTC(THU Chinese Text Classification)是由清华大学自然语言处理实验室推出的中文文本分类工具包,能够自动高效地实现用户自定义的文本分类语料的训练、评测、分类功能。文本文类通常包括特征选取、特征降维、...
  • 基本流程 1、准备好数据食材、去停用词并利用结巴(jieba)进行分词处理 数据食材选用参考:NLP中必不可少的语料资源 jieba分词模块参考官方文档啦~ # cutWords.py ...a 为在这个分类下包含这个词的文...
  • Python 实现小型文本分类系统

    千次阅读 2019-09-16 12:03:51
    最近在做微信公众号采集开发,将要对公众号文章数据(mysql里),进行文本分类,查了很多资料,找到一篇适合新手的一篇博文:...一、中文文本分类流程1、预处理2、中文分词3、结构化表示...
  • 1 文本分类文本分类是自然语言处理领域最活跃的研究方向之一,目前文本分类在工业界的应用场景非常普遍,从新闻的分类、商品评论信息的情感分类到微博信息打标签辅助推荐系统,了解文本分类技术是NLP初学者比较好的...
  • 使用BERT做中文文本相似度计算与文本分类

    万次阅读 多人点赞 2018-11-29 18:37:53
    它通过在各种NLP任务中呈现最先进的结果,包括问答系统、自然语言推理等,引起了机器学习社区的轰动。 本文不会去讲解BERT的原理,如果您还不清楚什么是BERT建议先参阅Google的论文或者其他博文,本文主要目的在于...
  • 本文介绍NLP中文本分类任务中核心流程进行了系统的介绍,文末给出一个基于Text-CNN模型在搜狗新闻数据集上二分类的Demo。 文本分类是自然语言处理领域最活跃的研究方向之一,从样本数据的分类标签是否互斥上来说,...
  • 中国科学院计算技术研究所在多年研究工作积累的基础上,研制了汉语词法分析系统ICTCLAS(Institute of Computing Technology,Chinese Lexical Analysis System),主要功能包括中文分词;词性标注;命名实体识别;...
  • 机器学习致力于研究如何通过计算的手段,利用经验来改善系统自身的性能。机器学习通过历史数据训练出模型,然后利用学习获得的模型对新数据进行预测 机器学习模型 机器学习是对能通过经验自动改进的计算机算法的研究...
  • 关键词的提取是进行计算机自动文本分类和其他文本数据挖掘应用的关键。系统从语言的词性角度 考虑,对传统的最大匹配分词法进行了改进,提出一种基于动词、虚词和停用词三个较小词库的快速分词方法 ( FS) ,并利用TFIDF...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 346
精华内容 138
关键字:

中文文本分类系统