文本分类_文本分类器 - CSDN
文本分类 订阅
文本分类用电脑对文本集(或其他实体或物件)按照一定的分类体系或标准进行自动分类标记。 它根据一个已经被标注的训练文档集合, 找到文档特征和文档类别之间的关系模型, 然后利用这种学习得到的关系模型对 新的文档进行类别判断 。文本分类从基于知识的方法逐渐转变为基于统计 和机器学习的方法。 展开全文
文本分类用电脑对文本集(或其他实体或物件)按照一定的分类体系或标准进行自动分类标记。 它根据一个已经被标注的训练文档集合, 找到文档特征和文档类别之间的关系模型, 然后利用这种学习得到的关系模型对 新的文档进行类别判断 。文本分类从基于知识的方法逐渐转变为基于统计 和机器学习的方法。
信息
定    义
基于分类体系的自动分类
方    法
朴素贝叶斯、支持向量机、K邻近法、决策树
中文名
文本分类
类    别
处理方式
文本分类定义
基于分类体系的自动分类基于资讯过滤和用户兴趣(Profiles)的自动分类所谓分类体系就是针对词的统计来分类关键字分类,全文检索词的正确切分不易分辨(白痴造句法)学习人类对文本分类的知识和策略从人对文本和类别之间相关性判断来学习文件用字和标记类别之间的关联
收起全文
精华内容
参与话题
  • 文本分类实战(上)

    千次阅读 2019-05-14 18:05:00
    数据集介绍 其中0表示消极,1表示积极,主要处理 ‘data/yelp_labelled.txt’, ‘data/amazon_cells_labelled.txt’, ‘data/imdb_labelled.txt’ import pandas as pd """ 数据读取,其中0表示消极,1表示积极,...

    数据集介绍

    在这里插入图片描述

    在这里插入图片描述

    其中0表示消极,1表示积极,主要处理 ‘data/yelp_labelled.txt’, ‘data/amazon_cells_labelled.txt’, ‘data/imdb_labelled.txt’

    import pandas as pd
    """
    数据读取,其中0表示消极,1表示积极,合并数据集
    """
    filepath_dict = {'yelp':   'data/yelp_labelled.txt',
                     'amazon': 'data/amazon_cells_labelled.txt',
                     'imdb':   'data/imdb_labelled.txt'}
    
    df_list = []
    for source, filepath in filepath_dict.items():
        df = pd.read_csv(filepath, names=['sentence', 'label'], sep='\t')
        df['source'] = source  
        df_list.append(df)
    df = pd.concat(df_list)
    df.head()
    

    在这里插入图片描述

    问题来了 对于文本处理怎么提取

    我马上想到了词袋模型

    先回顾怎么使用词袋

    sentences = ['John likes ice cream', 'John hates chocolate.']
    # 词袋模型
    from sklearn.feature_extraction.text import CountVectorizer
    vectorizer = CountVectorizer(min_df=0, lowercase=False)
    vectorizer.fit(sentences)
    print(vectorizer.vocabulary_)
    print(vectorizer.transform(sentences).toarray())
    

    {‘John’: 0, ‘likes’: 5, ‘ice’: 4, ‘cream’: 2, ‘hates’: 3, ‘chocolate’: 1}
    [[1 0 1 0 1 1]
    [1 1 0 1 0 0]]

    from sklearn.model_selection import train_test_split
    # 导出yelp的数据
    df_yelp = df[df['source'] == 'yelp']
    sentences = df_yelp['sentence'].values
    y = df_yelp['label'].values#0和1的矩阵
    # 划分数据集
    sentences_train, sentences_test, y_train, y_test = train_test_split(sentences, y, test_size=0.25, random_state=1000)
    from sklearn.feature_extraction.text import CountVectorizer
    # 使用词袋
    vectorizer = CountVectorizer()
    # 先fitsentences_train
    vectorizer.fit(sentences_train)
    X_train = vectorizer.transform(sentences_train)
    X_test  = vectorizer.transform(sentences_test)
    print (X_train.shape)
    print (X_train[0].toarray())
    

    (750, 1714)
    [[0 0 0 … 0 0 0]]

    终于将文本转化数字了
    标签都是0和1 ,我马上想到用逻辑回归

    from sklearn.linear_model import LogisticRegression
    classifier = LogisticRegression()
    classifier.fit(X_train, y_train)
    score = classifier.score(X_test, y_test)
    print("Accuracy:", score)
    

    Accuracy: 0.796

    刚刚使用了一份数据来试验了一下

    赶紧将剩下的搞定

    for source in df['source'].unique():
        df_source = df[df['source'] == source]
        sentences = df_source['sentence'].values
        y = df_source['label'].values
    
        sentences_train, sentences_test, y_train, y_test = train_test_split(
            sentences, y, test_size=0.25, random_state=1000)
    
        vectorizer = CountVectorizer()
        vectorizer.fit(sentences_train)
        X_train = vectorizer.transform(sentences_train)
        X_test  = vectorizer.transform(sentences_test)
    
        classifier = LogisticRegression()
        classifier.fit(X_train, y_train)
        score = classifier.score(X_test, y_test)
        print('Accuracy for {} data: {:.4f}'.format(source, score))
    

    Accuracy for yelp data: 0.7960
    Accuracy for amazon data: 0.7960
    Accuracy for imdb data: 0.7487

    精确度不行啊啊啊啊,咋办

    看来要出大招,神经网络

    from keras.models import Sequential
    from keras import layers
    
    # 稀疏矩阵转换
    X_train = X_train.toarray()
    X_test = X_test.toarray()
    
    input_dim = X_train.shape[1]  # Number of features  2505
    model = Sequential()
    model.add(layers.Dense(10, input_dim=input_dim, activation='relu'))
    model.add(layers.Dense(1, activation='sigmoid'))
    
    #二分类用binary_crossentropy
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.summary()
    history = model.fit(X_train, y_train,
                        epochs=100,
                        verbose=False,
                        validation_data=(X_test, y_test),
                        batch_size=10)
    
    loss, accuracy = model.evaluate(X_train, y_train, verbose=False)
    print("Training Accuracy: {:.4f}".format(accuracy))
    loss, accuracy = model.evaluate(X_test, y_test, verbose=False)
    print("Testing Accuracy:  {:.4f}".format(accuracy))
    

    Training Accuracy: 1.0000
    Testing Accuracy: 0.7861

    import matplotlib.pyplot as plt
    plt.style.use('ggplot')
    
    def plot_history(history,name):
        acc = history.history['acc']
        val_acc = history.history['val_acc']
        loss = history.history['loss']
        val_loss = history.history['val_loss']
        x = range(1, len(acc) + 1)
    
        plt.figure(figsize=(12, 5))
        plt.subplot(1, 2, 1)
        plt.plot(x, acc, 'b', label='Training acc')
        plt.plot(x, val_acc, 'r', label='Validation acc')
        plt.title('Training and validation accuracy')
        plt.legend()
        plt.subplot(1, 2, 2)
        plt.plot(x, loss, 'b', label='Training loss')
        plt.plot(x, val_loss, 'r', label='Validation loss')
        plt.title('Training and validation loss')
        plt.legend()
        plt.show()
        plt.savefig(str(name)+'.png')
    plot_history(history,name='base_nn')
    

    在这里插入图片描述

    大招没用啊啊啊,明显的过拟合

    不急不急,文本数据怎么不用Word Embeddings(词嵌入)
    #不用之前的词袋了 用keras的 词嵌入
    from keras.preprocessing.text import Tokenizer
    # 用词袋的特征 2505 那设置数量5000
    tokenizer = Tokenizer(num_words=5000)
    tokenizer.fit_on_texts(sentences_train)
    
    X_train = tokenizer.texts_to_sequences(sentences_train)
    X_test = tokenizer.texts_to_sequences(sentences_test)
    
    # 记得添加1
    vocab_size = len(tokenizer.word_index) + 1  # 2575
    
    print(sentences_train[2]) # I am a fan of his ... This movie sucked really bad. 
    print(X_train[2]) # [7, 150, 2, 932, 4, 49, 6, 11, 563, 45, 30]
    
    # 填充序列
    from keras.preprocessing.sequence import pad_sequences
    
    maxlen = 30
    X_train = pad_sequences(X_train, padding='post', maxlen=maxlen)
    X_test = pad_sequences(X_test, padding='post', maxlen=maxlen)
    print(X_train[0, :])  # [170 116 390  35   0   0   0   0   0   0   0   0   0   0   0   0   0   0]
    

    重新训练模型

    from keras.models import Sequential
    from keras import layers
    
    embedding_dim = 50
    
    model = Sequential()
    model.add(layers.Embedding(input_dim=vocab_size,
                               output_dim=embedding_dim,
                               input_length=maxlen))
    model.add(layers.Flatten())
    model.add(layers.Dense(10, activation='relu'))
    model.add(layers.Dense(1, activation='sigmoid'))
    model.compile(optimizer='adam',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    model.summary()
    
    history = model.fit(X_train, y_train,
                        epochs=20,
                        verbose=False,
                        validation_data=(X_test, y_test),
                        batch_size=10)
    loss, accuracy = model.evaluate(X_train, y_train, verbose=False)
    print("Training Accuracy: {:.4f}".format(accuracy))
    loss, accuracy = model.evaluate(X_test, y_test, verbose=False)
    print("Testing Accuracy:  {:.4f}".format(accuracy))
    plot_history(history,name='base_Embedding Layer')
    

    在这里插入图片描述

    这是要气死人吗吗吗,竟然比之前的还差

    展开全文
  • python 中文文本分类

    万次阅读 多人点赞 2018-01-26 16:47:26
    写这篇博文用了很多时间和精力,如果这篇博文对你有帮助,希望您可以打赏给博主相国大人。哪怕只捐1毛钱,也是一种心意。通过这样的方式,也可以培养整个行业的知识产权意识。我可以和您建立更多的联系,并且在相关...

    写这篇博文用了很多时间和精力,如果这篇博文对你有帮助,希望您可以打赏给博主相国大人。哪怕只捐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

    展开全文
  • 文本分类——常见分类模型

    万次阅读 2018-11-12 11:29:36
      文本分类方法模型主要分为两个大类,一类是基于规则的分类模型;另一类是基于概率统计的模型。 基于规则的模型   基于规则的分类模型相对简单,易于实现。它在特定领域的分类往往能够取得较好的效果。相对于...

      文本分类方法模型主要分为两个大类,一类是基于规则的分类模型;另一类是基于概率统计的模型。

    基于规则的模型

      基于规则的分类模型相对简单,易于实现。它在特定领域的分类往往能够取得较好的效果。相对于其它分类模型来说,基于规则的分类模型的优点就是时间复杂度低、运算速度快。在基于规则的分类模型中,使用许多条规则来表述类别。类别规则可以通过领域专家定义,也可以通过计算机学习获得。
      决策树就是一种基于训练学习方法获取分类规则的常见分类模型,它建立对象属性与对象值之间的一种映射。通过构造决策树来对未标注文本进行分类判别。常用的决策树方法包括CART 算法、ID3、C4.5、CHAID 等。
      在Web文本应用领域普遍存在着层级形式,这种层级形式可以通过一颗决策树来描述。决策树的根节点表示整个数据集空间,每个子节点是依据单一属性做出的分支判定,该判定将数据集分成两个或两个以上的分支区域。决策树的叶子节点就是相应类别的数据集合。
      决策树分类模型的一般构建过程:
      1.首先将训练数据分成两部分,一部分(训练集A)用于构建初始决策树,另一部分(训练集B)用来对决策树进行剪枝;
      2.以训练集A作为树的根节点,找出变异量最大的属性变量作为高层分割标准;以训练集A作为树的根节点,找出变异量最大的属性变量作为高层分割标准;
      3.通过对训练集A的学习训练构建一颗初始决策树;通过对训练集A的学习训练构建一颗初始决策树;
      4.再通过训练集B对初始决策树进行剪枝操作;再通过训练集B对初始决策树进行剪枝操作;
      5.一般还要通过递归的过程来构建一颗稳定的决策树,根据预测结果的正确率及未满足条件,则再对决策树进行分支或剪枝。
      决策树的构建过程一般是自上而下的,剪枝的方法有多种,但是具有一致目标,即对目标文本集进行最优分割。决策树可以是二叉树也可以是多叉树。

    基于概率的模型

      假设未标注文档为d,类别集合为C={c1,c2,…,cm} ,概率模型分类是对1≤i≤n 求条件概率模型P(ci|d) ,将与文档d条件概率最大的那个类别作为该文档的输出类别。其中朴素贝叶斯分类器是应用最为广泛的概率分类模型。
      朴素贝叶斯分类的基本思想是利用词组与类别的联合概率来估计给定文档的类别概率。基于贝叶斯分类器的贝叶斯规则如式:

    其中:C和D为随机变量。
      贝叶斯规则计算文档d属于每一个类别的可能性 P(ci|d),然后将文档d标注为概率最大的那一类。对文档d的贝叶斯分类如下式

      先验概率P(ci) 的估计很简单,计算如下式所示:

      其中: N(ci) 表示训练集中类别ci 的样本数量,N为训练集样本总数。 本质上表示训练集样例中类别ci 的比例。

      概率P(d|ci) 计算相对复杂,它首先基于一个贝叶斯假设:文档d为词组元素的集合,集合中词组(元素)之间相互独立。由于文档的表示简化了,所以这也就是朴素(Naïve) 的由来之一。事实上,词组之间并不是相互独立的。虽然这是一种假设独立性,但是朴素贝叶斯还是能够在分类任务中表现出很好的分类效果和鲁棒性。这一假设简化了联合概率的计算,它允许条件概率的乘机来表示联合概率。P(d|ci) 的计算式:

    其中:tk 表示含有n项词组的词组表vi 中的一个词组。因此,估计P(d|ci) 变为估计词组表v中的每一个词组在每一个类别下的概率P(tk|ci)
      概率的估计与分类结果非常依赖于事件空间的选择。下面介绍两种卡内基梅隆大学McCallum 和 Nigam 提出的事件空间模型,并说明相应的P(tk|ci) 是如何估计的。
      1) 多重伯努利模型
      多重伯努利(Multiple-Bernoulli)事件空间是一种布尔独立模型的事件空间,为每一个词组tk 建立一个二值随机变量。最简单的方式就是使用最大似然估计来估计概率,即式:

    其中: df(tk|ci) 表示类别ci 含有词组tk 的样本数量。
      虽然上式来估计概率很简单,但是存在“零概率”问题,真实应用是不可能的。这就需要采用平滑技术来克服“零概率”问题。贝叶斯平滑是一种常用的平滑估计技术。多重伯努利模型的平滑估计如下式所示:

    其中: αkβk 是依赖与词组tk 的参数。一种常见的参数选择方式是αk =1且βk* =0,得到如下概率估计公式

      多重伯努利模型仅仅考虑词组是否出现,而没有考虑出现的多少,而词频也是一个重要分类信息。下面介绍加入词频信息的多项式模型。
      2) 多项式模型
      多项式(Multinomial)时间空间与多重伯努利事件空间类似,但是多项式事件空间假设词组的出现次数是零次或多次,而不是出现与否。
      多项式模型的最大似然估计计算如式:

    其中: tf(tk|ci) 表示训练集中类别ci 中词组tk 出现的次数。 |ci|表示训练集类别ci 中的总词数。加入平滑估计的概率如式:

    这里 αk 是依赖于词组tk 的参数。对所有词组tk* 取αk =1是一种常见选择。这就导致概率估计:

    实际应用中,多项式模型已经表明优于多重伯努利模型。

    基于几何的模型

      使用向量空间模型表示文本,文本就被表示为一个多维的向量,那么它就是多维空间的一个点。通过几何学原理构建一个超平面将不属于同一个类别的文本区分开。最典型的基于几何学原理的分类器是支持向量机(SVM),最简单的SVM应用就是二值分类,就是常见的正例和反例。SVM的目标就是构建能够区分正例和反例的N维空间决策超平面。
      SVM是上世纪九十年代中期,由Vapnik等人逐渐完善的统计机器学习理论。该模型主要用来解决模式识别中的二分类问题,在文本分类、手写识别、图像处理等领域都取得了很好的分类效果。其基本思想就是在向量空间中找到一个决策超平面,该决策超平面能够最大限度地将正例和反例区分开来。在一定的范围内,决策超平面是可以平行移动的,这种平移不会造成训练集数据的分类错误。但是为了获取在未知样本的分类预测中的稳定性,要求分类超平面距离两类样本的距离尽可能大,也就是说,超平面尽可能位于边界区域的中心位置。
      SVM采用计算学习理论的结构风险最小化(Structural Risk Minimization, SRM)原则。其主要思想:以支持向量(Support Vector, SV)作为训练集的基础,在N维空间内寻找能将训练集样本分成两类,并且具有最大边缘(Margin)值的最优超平面(Optimal Separating Hyper-plane,OSH),来达到最大的分类正确率。
      SVM选择最大化边缘距离的分类决策超平面,这个选择不仅直观,而且也得到了理论的支持。对于线性可分数据的超平面以及支持向量的图形解释如图:

    线性可分数据支持向量机示意图

    其中:左上方为正例区域,右下方为反例区域,中间实线为w定义的决策超平面,箭头所示为边缘,虚线方框内的样本表示支持向量。边缘(Margin)的定义如式:

    其中:x- 是训练集距离超平面最近的反例, x+ 是训练集距离超平面最近的正例。定义边缘(Margin)为x- 到决策超平面距离与x+ 到决策超平面距离之和。
      SVM算法中超平面的概念是发现使分离数据最大边缘化的超平面w。一个等价的形式是,寻找解决下列优化问题的决策超平面,如式:

    这一优化目标容易求解,一般通过动态规划来解决。
      现实世界中的数据集很少是线性可分的。为了解决这个问题,一般需要修改SVM优化目标公式加入惩罚因子来完成不满足线性可分约束的训练实例的分类。加入了惩罚因子的SVM最优化目标如式:

    这里ζi 表示允许目标被违反的松弛变量(Stack Variable),这个松弛变量加强了关键损失函数。
      另外一个SVM关键技术是核技巧,通过核函数将线性不可分的训练数据变换或映射到更高维空间中,得到线性可分的数据集。核函数技术大多数情形下都可以提高分类的精度。常用SVM核函数如下:
      线性核:

      多项式核:

      径向基(RBF)核(也称为高斯核):

      SVM能够取得比较好的分类效果。其优点在于:
      1.SVM是一种针对有限样本条件下的分类算法,其目标是得到当前训练集下的最优解而不是样本数趋于无穷大时的最优值,该算法最终将问题转化成二次线性规划寻求最优解问题。从理论上来讲,它得到的是全局最优解,能够避免局部极值问题。
      2.该方法将实际问题通过核函数技巧将线性不可分空间映射到高维线性可分空间,在高维空间中构造线性决策函数来实现原线性不可分空间的决策函数。这保证了SVM具有较好的推广能力,计算的复杂度不再取决于空间维数,而是取决于训练集样本数量。
      3.SVM方法能够很好的处理稀疏数据,更好的捕捉了数据的内在特征,准确率较高。
      SVM虽然有许多优点,但是固有的缺点是不可避免的。其缺点包括:
      1.SVM算法时间和空间复杂度较高,随着训练样本数和类别的增加,分类时间和空间代价很高。
      2.核函数空间变换会增加训练集空间的维数,使得SVM对时间和空间需求加大,又进一步降低了分类的效率。
      3.SVM算法一般含有较多参数,并且参数随着训练样本的不同,呈现较大的差异,调整参数以获得最优分类效果相对困难。而且参数的不同对分类结果的显示出较大的差异性。

    基于统计的模型

      基于统计的机器学习方法已经成为自然语言研究领域里面的主流研究方法。事实上无论是朴素贝叶斯分类模型,还是支持向量机分类模型,也都采用了统计的方式。文本分类算法中一种最典型的基于统计的分类模型就是k近邻(k-Nearest Neighbor,kNN)模型,是比较好的文本分类算法之一。
      kNN分类模型的主要思想:通过给定一个未标注文档d,分类系统在训练集中查找与它距离最接近的k篇相邻(相似或相同)标注文档,然后根据这k篇邻近文档的分类标注来确定文档d的类别。分类实现过程:
      1) 将训练集样本转化为向量空间模型表示形式并计算每一特征的权重;
      2) 采用类似步骤1的方式转化未标注文档d并计算相应词组元素的权重;
      3) 计算文档d与训练集样本中每一样本的距离(或相似度);
      4) 找出与文档d距离最小(或相似度最大)的k篇训练集文本;
      5) 统计这个k篇训练集文本的类别属性,一般将文档d的类归为k中最多的样本类别。

      kNN 分类模型是一种“懒学习”算法,实质上它没有具体的训练学习过程。分类过程只是将未标注文本与每一篇训练集样本进行相似度计算, kNN 算法的时间和空间复杂度较高。因而随着训练集样本的增加,分类的存储资源消耗大,时间代价高。一般不适合处理训练样本较大的分类应用。

    知更鸟博文推荐
    上一篇 文本分类——特征选择概述
    下一篇 文本分类——算法性能评估
    推荐篇 基于Kubernetes、Docker的机器学习微服务系统设计——完整版
    研究篇 RS中文分词   |  MP特征选择   |  NLV文本分类   |  快速kNN
    作者简介
    兴趣爱好 机器学习、云计算、自然语言处理、文本分类、深度学习
    E-mail xsd-jj@163.com (欢迎交流)

    参考文献:
    [1].McCallum,A.,Nigam,K. A comparison of event models for naive Bayes text classification [C]. In: Proc. of the AAAI ’98 Workshop on Learning for Text Categorization. 41 - 48.
    [2].宗成庆. 统计自然语言处理[M].北京:清华大学出版社,2008
    [3].王斌,潘文峰.基于内容的垃圾邮件过滤技术综述[J].中文信息学报,19(5):1-10
    [4].Yang,Y.,Liu,X. A re-examination of text categorization methods [C]. In: Proceedings of the 22nd ACM Int’l Conference on Research and Development in Information Retrieval. Berkeley: ACM Press: 42-49

    版权声明:个人原创,请勿抄袭,欢迎引用,未经许可禁止转载. © 知更鸟
    展开全文
  • 文本分类概述(nlp)

    万次阅读 多人点赞 2018-11-25 19:04:02
    文本分类问题:给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多个 文本分类应用:常见的有垃圾邮件识别,情感分析 文本分类方向:主要有二分类,多分类,多标签分类 文本分类方法:传统机器学习...

    文本分类问题: 给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多个
    文本分类应用: 常见的有垃圾邮件识别,情感分析
    文本分类方向: 主要有二分类,多分类,多标签分类
    文本分类方法: 传统机器学习方法(贝叶斯,svm等),深度学习方法(fastText,TextCNN等)
    本文的思路: 本文主要介绍文本分类的处理过程,主要哪些方法。致力让读者明白在处理文本分类问题时应该从什么方向入手,重点关注什么问题,对于不同的场景应该采用什么方法。
    文本分类的处理大致分为文本预处理、文本特征提取、分类模型构建等。和英文文本处理分类相比,中文文本的预处理是关键技术。

    一、中文分词:

    针对中文文本分类时,很关键的一个技术就是中文分词。特征粒度为词粒度远远好于字粒度,其大部分分类算法不考虑词序信息,基于字粒度的损失了过多的n-gram信息。下面简单总结一下中文分词技术:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法 [1]。

    1,基于字符串匹配的分词方法:
    过程:这是一种基于词典的中文分词,核心是首先建立统一的词典表,当需要对一个句子进行分词时,首先将句子拆分成多个部分,将每一个部分与字典一一对应,如果该词语在词典中,分词成功,否则继续拆分匹配直到成功。
    核心: 字典,切分规则和匹配顺序是核心
    分析:优点是速度快,时间复杂度可以保持在O(n),实现简单,效果尚可;但对歧义和未登录词处理效果不佳。

    2,基于理解的分词方法:基于理解的分词方法是通过让计算机模拟人对句子的理解,达到识别词的效果。其基本思想就是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。它通常包括三个部分:分词子系统、句法语义子系统、总控部分。在总控部分的协调下,分词子系统可以获得有关词、句子等的句法和语义信息来对分词歧义进行判断,即它模拟了人对句子的理解过程。这种分词方法需要使用大量的语言知识和信息。由于汉语语言知识的笼统、复杂性,难以将各种语言信息组织成机器可直接读取的形式,因此目前基于理解的分词系统还处在试验阶段。

    3,基于统计的分词方法:
    过程:统计学认为分词是一个概率最大化问题,即拆分句子,基于语料库,统计相邻的字组成的词语出现的概率,相邻的词出现的次数多,就出现的概率大,按照概率值进行分词,所以一个完整的语料库很重要。
    主要的统计模型有: N元文法模型(N-gram),隐马尔可夫模型(Hidden Markov Model ,HMM),最大熵模型(ME),条件随机场模型(Conditional Random Fields,CRF)等。


    二、文本预处理:

    1,分词: 中文任务分词必不可少,一般使用jieba分词,工业界的翘楚。
    2,去停用词:建立停用词字典,目前停用词字典有2000个左右,停用词主要包括一些副词、形容词及其一些连接词。通过维护一个停用词表,实际上是一个特征提取的过程,本质 上是特征选择的一部分。
    3,词性标注: 在分词后判断词性(动词、名词、形容词、副词…),在使用jieba分词的时候设置参数就能获取。


    三、文本特征工程:

    文本分类的核心都是如何从文本中抽取出能够体现文本特点的关键特征,抓取特征到类别之间的映射。 所以特征工程很重要,可以由四部分组成:
    这里写图片描述
    1,基于词袋模型的特征表示:以词为单位(Unigram)构建的词袋可能就达到几万维,如果考虑二元词组(Bigram)、三元词组(Trigram)的话词袋大小可能会有几十万之多,因此基于词袋模型的特征表示通常是极其稀疏的。
    (1)词袋特征的方法有三种:

    • Naive版本:不考虑词出现的频率,只要出现过就在相应的位置标1,否则为0;
    • 考虑词频(即term frequency):,认为一段文本中出现越多的词越重要,因此权重也越大;
    • 考虑词的重要性:以TF-IDF表征一个词的重要程度。TF-IDF反映了一种折中的思想:即在一篇文档中,TF认为一个词出现的次数越大可能越重要,但也可能并不是(比如停用词:“的”“是”之类的);IDF认为一个词出现在的文档数越少越重要,但也可能不是(比如一些无意义的生僻词)。

    (2)优缺点:

    • 优点: 词袋模型比较简单直观,它通常能学习出一些关键词和类别之间的映射关系
    • 缺点: 丢失了文本中词出现的先后顺序信息;仅将词语符号化,没有考虑词之间的语义联系(比如,“麦克风”和“话筒”是不同的词,但是语义是相同的);

    2,基于embedding的特征表示: 通过词向量计算文本的特征。(主要针对短文本)

    • 取平均: 取短文本的各个词向量之和(或者取平均)作为文本的向量表示;
    • 网络特征: 用一个pre-train好的NN model得到文本作为输入的最后一层向量表示;

    3,基于NN Model抽取的特征: NN的好处在于能end2end实现模型的训练和测试,利用模型的非线性和众多参数来学习特征,而不需要手工提取特征。CNN善于捕捉文本中关键的局部信息,而RNN则善于捕捉文本的上下文信息(考虑语序信息),并且有一定的记忆能力。

    4,基于任务本身抽取的特征:主要是针对具体任务而设计的,通过我们对数据的观察和感知,也许能够发现一些可能有用的特征。有时候,这些手工特征对最后的分类效果提升很大。举个例子,比如对于正负面评论分类任务,对于负面评论,包含负面词的数量就是一维很强的特征。

    5,特征融合:对于特征维数较高、数据模式复杂的情况,建议用非线性模型(如比较流行的GDBT, XGBoost);对于特征维数较低、数据模式简单的情况,建议用简单的线性模型即可(如LR)。

    6,主题特征:
    LDA(文档的话题): 可以假设文档集有T个话题,一篇文档可能属于一个或多个话题,通过LDA模型可以计算出文档属于某个话题的概率,这样可以计算出一个DxT的矩阵。LDA特征在文档打标签等任务上表现很好。
    LSI(文档的潜在语义): 通过分解文档-词频矩阵来计算文档的潜在语义,和LDA有一点相似,都是文档的潜在特征。


    四、文本分类,传统机器学习方法:

    这部分不是重点,传统机器学习算法中能用来分类的模型都可以用,常见的有:NB模型,随机森林模型(RF),SVM分类模型,KNN分类模型,神经网络分类模型。
    这里重点提一下贝叶斯模型,因为工业用这个模型用来识别垃圾邮件[2]。


    五、深度学习文本分类模型:

    1,fastText模型: fastText 是word2vec 作者 Mikolov 转战 Facebook 后16年7月刚发表的一篇论文: Bag of Tricks for Efficient Text Classification[3]。
    模型结构:
    在这里插入图片描述
    原理: 句子中所有的词向量进行平均(某种意义上可以理解为只有一个avg pooling特殊CNN),然后直接连接一个 softmax 层进行分类。

    2,TextCNN: 利用CNN来提取句子中类似 n-gram 的关键信息。
    模型结构[4]:
    在这里插入图片描述
    在这里插入图片描述

    改进: fastText 中的网络结果是完全没有考虑词序信息的,而TextCNN提取句子中类似 n-gram 的关键信息。

    3,TextRNN:
    模型: Bi-directional RNN(实际使用的是双向LSTM)从某种意义上可以理解为可以捕获变长且双向的的 “n-gram” 信息。
    在这里插入图片描述
    改进: CNN有个最大问题是固定 filter_size 的视野,一方面无法建模更长的序列信息,另一方面 filter_size 的超参调节也很繁琐。

    4,TextRNN + Attention:
    模型结构[5]:
    在这里插入图片描述
    改进:注意力(Attention)机制是自然语言处理领域一个常用的建模长时间记忆机制,能够很直观的给出每个词对结果的贡献,基本成了Seq2Seq模型的标配了。实际上文本分类从某种意义上也可以理解为一种特殊的Seq2Seq,所以考虑把Attention机制引入近来。

    5,TextRCNN(TextRNN + CNN):
    模型结构[6]:
    在这里插入图片描述
    过程:
    利用前向和后向RNN得到每个词的前向和后向上下文的表示:
    在这里插入图片描述
    词的表示变成词向量和前向后向上下文向量连接起来的形式:
    在这里插入图片描述
    再接跟TextCNN相同卷积层,pooling层即可,唯一不同的是卷积层 filter_size = 1就可以了,不再需要更大 filter_size 获得更大视野。
    6,深度学习经验:
    模型显然并不是最重要的: 好的模型设计对拿到好结果的至关重要,也更是学术关注热点。但实际使用中,模型的工作量占的时间其实相对比较少。虽然再第二部分介绍了5种CNN/RNN及其变体的模型,实际中文本分类任务单纯用CNN已经足以取得很不错的结果了,我们的实验测试RCNN对准确率提升大约1%,并不是十分的显著。最佳实践是先用TextCNN模型把整体任务效果调试到最好,再尝试改进模型。

    理解你的数据: 虽然应用深度学习有一个很大的优势是不再需要繁琐低效的人工特征工程,然而如果你只是把他当做一个黑盒,难免会经常怀疑人生。一定要理解你的数据,记住无论传统方法还是深度学习方法,数据 sense 始终非常重要。要重视 badcase 分析,明白你的数据是否适合,为什么对为什么错。

    超参调节: 可以参考深度学习网络调参技巧 - 知乎专栏

    一定要用 dropout: 有两种情况可以不用:数据量特别小,或者你用了更好的正则方法,比如bn。实际中我们尝试了不同参数的dropout,最好的还是0.5,所以如果你的计算资源很有限,默认0.5是一个很好的选择。

    未必一定要 softmax loss: 这取决与你的数据,如果你的任务是多个类别间非互斥,可以试试着训练多个二分类器,也就是把问题定义为multi lable 而非 multi class,我们调整后准确率还是增加了>1%。

    类目不均衡问题: 基本是一个在很多场景都验证过的结论:如果你的loss被一部分类别dominate,对总体而言大多是负向的。建议可以尝试类似 booststrap 方法调整 loss 中样本权重方式解决。

    避免训练震荡: 默认一定要增加随机采样因素尽可能使得数据分布iid,默认shuffle机制能使得训练结果更稳定。如果训练模型仍然很震荡,可以考虑调整学习率或 mini_batch_size。


    六、实例:

    知乎的文本多标签分类比赛,给出第一第二名的介绍网址:
    NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码)
    2017知乎看山杯 从入门到第二


    参考文献

    1.中文分词原理及分词工具介绍:https://blog.csdn.net/flysky1991/article/details/73948971/
    2.用朴素贝叶斯进行文本分类:https://blog.csdn.net/longxinchen_ml/article/details/50597149
    3.Joulin A, Grave E, Bojanowski P, et al. Bag of Tricks for Efficient Text Classification[J]. 2016:427-431.
    4.Kim Y . Convolutional Neural Networks for Sentence Classification[J]. Eprint Arxiv, 2014.
    5.Pappas N , Popescu-Belis A . Multilingual Hierarchical Attention Networks for Document Classification[J]. 2017.
    6.Lai S, Xu L, Liu K, et al. Recurrent Convolutional Neural Networks for Text Classification[C]//AAAI. 2015, 333: 2267-2273.

    展开全文
  • 自然语言处理——文本分类概述

    万次阅读 2018-11-14 13:52:10
    内容提要分类概述分类流程数据采集爬虫技术页面处理文本预处理英文处理中文处理停用词去除文本表示特征选择 分类概述   分类(Classification)是指自动对数据进行标注。人们在日常生活中通过经验划分类别。但是要...
  • 文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别。也就是 编码器-解码器的运用。 数据增强 通过前面的学习,我们知道有时候数据比算法更重要,也就是当我们拥有足够多的训练集的...
  • 文本分类 图像增广 微调(迁移学习) 文本分类 图像增广 大规模数据集是成功应用深度神经网络的前提。图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大...
  • 文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别。本节关注它的一个子问题:使用文本情感分类来分析文本作者的情绪。这个问题也叫情感分析,并有着广泛的应用。 同搜索近义词和...
  • 文本分类 文本分类是nlp中的简单任务,已经能够取得很好的结果了。情感分类是文本分类任务中的典型问题,经典数据集是IMDb。自从有了bert,微调预训练的bert几乎可以秒杀一众模型~不过在这里,主要介绍两个模型...
  • 文本分类

    千次阅读 2018-09-07 16:56:06
    一、传统文本分类方法  文本分类问题算是自然语言处理领域中一个非常经典的问题了,相关研究最早可以追溯到上世纪50年代,当时是通过专家规则(Pattern)进行分类,甚至在80年代初一度发展到利用知识工程建立专家...
  • NLP之文本分类

    千次阅读 2018-09-28 17:08:19
    文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题。传统的文本分类是基于文本内容的,研究如何将文本自动划分成政治的、经济的、军事的、体育的、娱乐的等各种类型。 ...
  • 文本分类过程概述

    千次阅读 2019-01-09 19:15:11
    传统的文本分类过程通常包括训练模块和分类模块如下图所示:一般来讲文本分类过程包括预处理、文本表示、特征降维、训练分类器和分类性能评估。  文本分类过程图 1、文本分类预处理  由于计算机很难直接处...
  • 基于支持向量机SVM的文本分类的实现

    万次阅读 多人点赞 2020-07-01 16:50:03
    SVM 文本分类算法主要分四个步骤:文本特征提取、文本特征表示、归一化处理和文本分类
  • 文本分类概述

    万次阅读 2009-10-27 15:10:00
    概览 自动文本分类(Automatic Text Categorization),或者简称为文本分类,是指计算机将一篇文章归于预先给定的某一类或某几类的过程。 文本分类是指按照预先定义的主题类别,为文档集合中的每个文档确定一个类别....
  • 搜狗实验室文本分类语料库

    万次阅读 2014-03-03 16:04:06
    文本分类语料库来源于Sohu新闻网站保存的大量经过编辑手工整理与分类的新闻语料与对应的分类信息。其分类体系包括几十个分类节点,网页规模约为十万篇文档。 语料库统计的意义:提供一个较大规模的标准中文文本分类...
  • 基于pytorch的 BERT中文文本分类

    千次阅读 2019-05-05 16:46:09
    转载一篇基于 pytorch 的BERT文本分类: https://blog.csdn.net/Real_Brilliant/article/details/84880528
  • 文本挖掘详解

    万次阅读 2015-12-26 13:27:33
    一、文本挖掘概念 在现实世界中,可获取的大部信息是以文本形式存储在文本数据库中的,由来自各种数据源的大量文档组成,如新闻文档、研究论文、书籍、数字图书馆、电子邮件和Web页面。由于电子形式的文本信息飞速...
  • 谈到文本分类,就不得不谈谈CNN(Convolutional Neural Networks)。这个经典的结构在文本分类中取得了不俗的结果,而运用在这里的卷积可以分为1d 、2d甚至是3d的。 下面就列举了几篇运用CNN进行文本分类的论文作为...
  • 用gensim做LDA实践之文本分类

    万次阅读 2016-06-27 14:43:22
    最近手上遇到了一个文本分类的问题,采用普通的VSM模型的时候,运行的太慢,后来查找改进策略的时候,想起了LDA,因此把LDA重新拉回我的视线,也终于弄懂了到底是做什么的。LDA本质是一种降维为什么这么说,因为在我...
  • 短文本分类概述

    千次阅读 2018-09-28 08:10:02
    -传统文本分类方法 -深度学习文本分类方法 评价指标 定义 短文本通常是指长度比较短,一般不超过160个字符的文本形式,如微博、聊天信息、新闻主题、观点评论、问题文本、手机短信、文献摘要等。短文本分类...
1 2 3 4 5 ... 20
收藏数 261,822
精华内容 104,728
关键字:

文本分类