中文文本分类1

文本挖掘(Text Mining)是从非结构化文本信息中获取用户感兴趣或者有用的模式的过程。



文本挖掘是指从大量文本数据中抽取事先未知的、可理解的、最终可用的知识的过程,同时运用这些知识更好地组织信息以便将来参考






文本预处理

文本处理的核心任务是把非结构化和半结构化的文本转换为结构化的形式,即向量空间模型。

具体步骤:

1. 选择处理的文本范围

选择恰当的范围取决于文本挖掘任务的目标:

  • 对于分类聚类的任务,往往把整个文档作为处理单位;
  • 对于情感分析文档自动摘要信息检索,段落或章节可能更合适。

2. 建立分类文本语库

  • 训练集语料:已经分好类的文本资源。
  • 测试集语料:待分类的文本语料,可以是训练集的一部分,也可以是外部来源的文本语料。

中文语料库

3. 文本格式转换

import sys
import os
import time
from lxml import etree, html
from sklearn.datasets.base import Bunch
import pickle
from time import time

root = ‘D:/MLBook‘ + ‘/chapter02‘
# htm文件路径,以及读取文件
path = root + "/1.htm"
with open(path, "rb") as fp:
    content = fp.read().decode()

page = html.document_fromstring(content) # 解析文件
text = page.text_content() # 去除所有标签
print(text[:100]) # 输出去除标签后解析结果
百度百科_百度百科(function(){window.PDC={_timing:{},_opt:{sample:0.01},_analyzer:{loaded:false,url:"http://s

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

完全解决中文分词的算法是基于概率图模型的条件随机场(CRF)

import jieba

seg_list = jieba.cut("小明1995年毕业于北京清华大学", cut_all=False)
print("Default Mode:", " ".join(seg_list))  # 默认模式

seg_list = jieba.cut("小明1995年毕业于北京清华大学")
print("  ".join(seg_list))

seg_list = jieba.cut("小明1995年毕业于北京清华大学", cut_all=True)
print("Full Mode:", "/ ".join(seg_list))  # 全模式

seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,\
后在日本京都大学深造")  # 搜索引擎模式
print("/  ".join(seg_list))
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\q7356\AppData\Local\Temp\jieba.cache
Loading model cost 0.992 seconds.
Prefix dict has been built succesfully.

Default Mode: 小明 1995 年 毕业 于 北京 清华大学
小明  1995  年  毕业  于  北京  清华大学
Full Mode: 小/ 明/ 1995/ 年/ 毕业/ 于/ 北京/ 清华/ 清华大学/ 华大/ 大学
小明/  硕士/  毕业/  于/  中国/  科学/  学院/  科学院/  中国科学院/  计算/  计算所/  ,/  后/  在/  日本/  京都/  大学/  日本京都大学/  深造
seg_list = jieba.cut("小明终于在1995年从北京清华大学毕业了。")
print("  ".join(seg_list))
小明  终于  在  1995  年  从  北京  清华大学  毕业  了  。
os.listdir(root+ ‘/train_corpus_seg‘)
[‘art‘,
 ‘computer‘,
 ‘economic‘,
 ‘education‘,
 ‘environment‘,
 ‘medical‘,
 ‘military‘,
 ‘politics‘,
 ‘sports‘,
 ‘traffic‘]
class Segment:
    def __init__(self, root):
        self.root = root

    def save_file(self, save_path, content):
        ‘‘‘
        保存文件
        ‘‘‘
        with open(save_path, ‘wb‘) as fp:
            fp.write(content.encode())

    def read_file(self, path):
        with open(path, ‘rb‘) as fp:
            content = fp.read().decode()
        return content

    def get_seg(self, corpus_path, seg_path):
        ‘‘‘
        获取每个目录下所有的文件 mydir in catelist
        catelist = os.listdir(corpus_path)

        参数
        =====
        corpus_path::未分词分类语料库路径,例如:"train_corpus_small/"
        seg_path::分词后分类语料库路径,例如:"train_corpus_seg/"
        ‘‘‘
        corpus_path = self.root + corpus_path
        seg_path = self.root + seg_path
        catelist = os.listdir(corpus_path)
        start = time()
        for i, mydir in enumerate(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)        # 获取 class_path 下的所有文件
            for k, file_path in enumerate(file_list):               # 遍历类别目录下文件
                fullname = class_path + file_path        # 拼出文件名全路径
                content = self.read_file(fullname).strip()     # 读取文件内容
                content = content.replace("\r\n", "")     # 删除换行和多余的空格
                content_seg = jieba.cut(content.strip())       # 为文件内容分词
                self.save_file(seg_dir + file_path, " ".join(content_seg))  # 将处理后的文件保存到分词后语料目录
                if k == 0 and i == 0:
                    print(‘保存分词后语料中......‘)
                    print(‘--‘ * 20)
            if i == 0:
                print(‘  完成语料分词的类别依次为:‘)
            print(‘\t%i: %s‘%(i, mydir))
        print(‘--‘ * 20)
        print("总计花费时间 %g 秒,中文语料分词结束!!!"%(time() - start))

    def get_bunch(self, wordbag_path, seg_path):
        ‘‘‘
        获取每个目录下所有的文件 mydir in catelist
        catelist = os.listdir(corpus_path)

        参数
        =====
        wordbag_path::分词语料 Bunch 对象持久化路径,例如:"train_word_bag/train_set.dat"
        seg_path::分词后分类语料库路径,例如:"train_corpus_seg/"
        ‘‘‘
        wordbag_path = self.root + wordbag_path
        seg_path = self.root + seg_path
        catelist = os.listdir(seg_path)
        bunch = Bunch(target_name=[], label=[], filenames=[], contents=[])
        bunch.target_name.extend(catelist)        # 将类别信息保存到 Bunch 对象
        start = time()
        for i, mydir in enumerate(catelist):
            class_path = seg_path + mydir + "/"    # 拼出分类子目录的路径
            file_list = os.listdir(class_path)        # 获取 class_path 下的所有文件
            for k, file_path in enumerate(file_list):               # 遍历类别目录下文件
                fullname = class_path + file_path        # 拼出文件名全路径
                bunch.label.append(mydir)                # 保存当前文件的分类标签
                bunch.filenames.append(fullname)          # 保存当前文件的文件路径
                bunch.contents.append(self.read_file(fullname).strip())    # 保存文件词向量
                if k == 0 and i == 0:
                    print(‘构建文本对象中......‘)
                    print(‘--‘ * 20)
            if i == 0:
                print(‘  文本对象构建的类别依次为:‘)
            print(‘\t%i: %s‘%(i, mydir))
        print(‘--‘ * 20)
        # 对象持久化
        with open(wordbag_path, "wb") as file_obj:
            pickle.dump(bunch, file_obj)
        print("总计花费时间 %g 秒,构建文本对象结束!!!"%(time() - start))
        print("")
        return bunch
root = ‘D:/MLBook/chapter02/‘
corpus_path = "train_corpus_small/"  # 未分词分类语料库路径
seg_path = "train_corpus_seg/"      # 分词后分类语料库路径

S = Segment(root)
S.get_seg(corpus_path, seg_path)
保存分词后语料中......
----------------------------------------
  完成语料分词的类别依次为:
    0: art
    1: computer
    2: economic
    3: education
    4: environment
    5: medical
    6: military
    7: politics
    8: sports
    9: traffic
----------------------------------------
总计花费时间 19.8525 秒,中文语料分词结束!!!

在实际应用中,为了后续生成向量空间模型的方便,这些分词后的文本信息还要转换为文本向量信息并对象化。这里我们使用 Scikit-Learn 库的 Bunch 数据结构:

  • Bunch 类提供一种 (key, value) 的对象形式
  • target_name:所有分类集名称列表
  • label:每个文件的分类标签列表
  • filenames:文件路径
  • contents:分词后文件词向量形式
from sklearn.datasets.base import Bunch

将分好词的文本转换并持久化为 Bunch 类形式:

wordbag_path = "train_word_bag/train_set.dat"  # 分词语料 Bunch 对象持久化路径
seg_path = "train_corpus_seg/"      # 分词后分类语料库路径

S = Segment(root)
bunch = S.get_bunch(wordbag_path, seg_path)
构建文本对象中......
----------------------------------------
  文本对象构建的类别依次为:
    0: art
    1: computer
    2: economic
    3: education
    4: environment
    5: medical
    6: military
    7: politics
    8: sports
    9: traffic
----------------------------------------
总计花费时间 0.891003 秒,构建文本对象结束!!!

这样就在目录下生成了一个 train_set.dat 文件。此文件保存了所有训练集文件的所有分类信息,以及每个文件的文件名、文件所属分类和词向量。

Scikit-Learn 简介

向量空间模型

为节省存储空间和提高搜索效率,在文本分类之前会自动过滤掉某些字或词,这些字或词被称为停用词。这些词一般都是意义模糊的常用词和语气助词,通常它们对文本起不了分类特征的意义。

权重策略——TF-IDF 方法

文本1:My dog ate my homework
文本2:My cat ate the sandwich
文本3:A dolphin ate the homework
a = ‘My dog ate my homework ‘
b = ‘My cat ate the sandwich ‘
c = ‘A dolphin ate the homework ‘
def str2list(s):
    return s.lower().strip(‘ ‘).split(‘ ‘)

def wordbag(*args):
    wb = []
    for t in args:
        wb.extend(str2list(t))
    return set(wb)

def word2vec(wb, t):
    a2 = []
    for k in wb:
        if k in str2list(t):
            a2.append(1)
        else:
            a2.append(0)
    return a2
wb = wordbag(*[a, b, c])
wb
{‘a‘, ‘ate‘, ‘cat‘, ‘dog‘, ‘dolphin‘, ‘homework‘, ‘my‘, ‘sandwich‘, ‘the‘}

将上述文本信息转换为词向量:

a2 = word2vec(wb, a)
b2 = word2vec(wb, b)
c2 = word2vec(wb, c)

print(‘文本1:‘, a2)
print(‘文本2:‘, b2)
print(‘文本3:‘, c2)
文本1: [1, 1, 0, 0, 1, 0, 0, 1, 0]
文本2: [0, 1, 1, 0, 0, 0, 1, 1, 1]
文本3: [1, 0, 0, 1, 0, 1, 1, 1, 0]

词频统计

def get_word_stat(w):
    d = {}
    for v in str2list(w):
        d[v] = d.get(v, 0) + 1
    return d

def word2vec(wb, t):
    L = []
    for k in wb:
        d = get_word_stat(t)
        if k in d.keys():
            L.append(d[k])
        else:
            L.append(0)
    return L
a2 = word2vec(wb, a)    # ‘my‘ 出现了两次
b2 = word2vec(wb, b)
c2 = word2vec(wb, c)

print(‘文本1:‘, a2)
print(‘文本2:‘, b2)
print(‘文本3:‘, c2)
文本1: [1, 2, 0, 0, 1, 0, 0, 1, 0]
文本2: [0, 1, 1, 0, 0, 0, 1, 1, 1]
文本3: [1, 0, 0, 1, 0, 1, 1, 1, 0]

对词向量进行归一化,将其转换为概率分布

import numpy as np

def TF(t):
    a3 = np.array(t)
    return a3 / a3.sum()
a3 = TF(a2)    # ‘my‘ 出现了两次
b3 = TF(b2)
c3 = TF(c2)

print(‘文本1:‘, a3)
print(‘文本2:‘, b3)
print(‘文本3:‘, c3)
文本1: [ 0.2  0.4  0.   0.   0.2  0.   0.   0.2  0. ]
文本2: [ 0.   0.2  0.2  0.   0.   0.   0.2  0.2  0.2]
文本3: [ 0.2  0.   0.   0.2  0.   0.2  0.2  0.2  0. ]

词频信息变成了概率分布,这就是文档的 TF 信息。

def word2vec2(wb, t):
    L = []
    for k in wb:
        D = get_word_stat(a + b + c)
        d = get_word_stat(t)
        if k in d.keys():
            L.append(D[k])
        else:
            L.append(0)
    return L

def IDF(wb, t):
    e = word2vec2(wb, t)
    g = 3 / (np.array(e) + 1)
    return np.log(g)
a4 = IDF(wb, a)
b4 = IDF(wb, b)
c4 = IDF(wb, c)
TFIDF1 = a3 * a4
TFIDF2 = b3 * b4
TFIDF3 = c3 * c4
TFIDF1
array([ 0.        , -0.11507283,  0.        ,  0.        ,  0.08109302,
        0.        ,  0.        , -0.05753641,  0.        ])

下面我们使用 Scikit-Learn 包来实现 TF-IDF 算法:

def read_file(path):
    ‘‘‘
    读取停用词表
    ‘‘‘
    with open(path, "rb") as fp:
        content = fp.read()
    return content.decode()  # 转换为 string

class Word2Vector:

    def __init__(self, root):
        self.root = root

    def read_bunch(self, path):
        ‘‘‘
        读取 bunch 对象
        ‘‘‘
        with open(self.root + path, "rb") as file_obj:
            bunch = pickle.load(file_obj)
        return bunch

    def write_bunch(self, path, bunchobj):
        ‘‘‘
        写入 bunch 对象
        ‘‘‘
        with open(self.root + path, "wb") as file_obj:
            pickle.dump(bunchobj, file_obj) 

    def read_stopword(self, stopword_path):
        ‘‘‘
        读取停用词表

        示例
        =======
        path = "train_word_bag/hlt_stop_words.txt"
        ‘‘‘
        return read_file(self.root + stopword_path).splitlines()

    def tfidf(self, stopword_path, path, space_path):
        ‘‘‘
        参数
        ======
        stopword_path::停用词路径
        path::bunch 保存路径
        space_path::词向量词袋保存路径
        ‘‘‘
        start = time()
        # 1. 读取停用词表
        stpwrdlst = self.read_stopword(stopword_path)

        # 2. 导入分词后的词向量 bunch 对象
        bunch = self.read_bunch(path)

        # 3. 构建 tf-idf 词向量空间对象
        tfidfspace = Bunch(target_name=bunch.target_name, label=bunch.label,
                           filenames=bunch.filenames, tdm=[], vocabulary={})

        # 4. 使用 TfidfVectorizer 初始化向量空间模型
        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_

        # 创建词袋的持久化
        self.write_bunch(space_path, tfidfspace)
        print("花费时间:%g 秒,TF-IDF 词向量空间创建成功!!!"%(time() - start))
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import TfidfVectorizer  
WV = Word2Vector(root)
path = "train_word_bag/train_set.dat"        # 词向量空间保存路径
stopword_path = "train_word_bag/hlt_stop_words.txt"
space_path = "train_word_bag/tfdifspace.dat"        # 词向量空间保存路径

WV.tfidf(stopword_path, path, space_path)
花费时间:1.6075 秒,TF-IDF 词向量空间创建成功!!!

原文地址:https://www.cnblogs.com/q735613050/p/9135789.html

时间: 2024-08-13 19:37:36

中文文本分类1的相关文章

中文文本分类

本文介绍文本挖掘与文本分类的一些基本概念和流程,为后续学习分类算法做好铺垫. 一. 文本挖掘的概念 文本挖掘(Text Mining)是从非结构化文本信息中获取用户感兴趣或者有用的模式 的过程.其中被普遍认可的文本挖掘定义如下:文本挖掘是指从大量文本数据中抽取事先未知的.可理解的.最终可用的知识的过程,同时运用这些知识更好地组织信息以便将来参考. 简言之,文本挖掘就是从非结构化的文本中寻找知识的过程. 文本挖掘的七个主要领域: (1)搜索和信息检索(IR):存储和文本文档的检索,包括搜索引擎和关

2.中文文本分类

这这一篇博客中,将系统介绍中文文本分类的流程和相关算法.先从文本挖掘的大背景开始,以文本分类算法为中心,介绍中文文本分类项目的流程以及相关知识,知识点设计中文分词,向量空间模型,TF-IDF方法,几个典型的文本分类算法和评价指标等. 本篇主要有: 朴素的贝叶斯算法 KNN最近邻算法. 2.1 文本挖掘与文本分类的概念 简单来说,文本挖掘就是从已知的大量文本数据中提取一些未知的最终可能用过的知识的过程,也就是从非结构化的文本中寻找知识的过程.文本挖掘主要领域有: 搜索和信息检索:存储和文本文档的检

中文文本分类大概的步骤

文本分类问题:给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多个 文本分类应用:常见的有垃圾邮件识别,情感分析 文本分类方向:主要有二分类,多分类,多标签分类 文本分类方法:传统机器学习方法(贝叶斯,svm等),深度学习方法(fastText,TextCNN等) 文本分类的处理大致分为文本预处理.文本特征提取.分类模型构建等.和英文文本处理分类相比,中文文本的预处理是关键技术. 一.中文分词:针对中文文本分类时,很关键的一个技术就是中文分词.特征粒度为词粒度远远好于字粒度,其大部分

中文文本分类之TextRNN

RNN模型由于具有短期记忆功能,因此天然就比较适合处理自然语言等序列问题,尤其是引入门控机制后,能够解决长期依赖问题,捕获输入样本之间的长距离联系.本文的模型是堆叠两层的LSTM和GRU模型,模型的结构为:LSTM(GRU)—dropout—LSTM(GRU)—dropout—全连接层—输出层,比较简单.关于TensorFlow搭建RNN模型有关的内容,在这篇<TensorFlow之RNN:堆叠RNN.LSTM.GRU及双向LSTM>博客里阐述得比较清楚了,这里不赘述. 尽管RNN模型天然比较

fastext 中文文本分类

1. 输入文本预处理, 通过jieba分词, 空格" "拼接文本串.  每行一个样本, 最后一个单词为双下划线表明label,  __label__'xxx' . eg: 邱县 继刚 家庭 农场 小麦 . 玉米 . 棉花 . 大豆 . 蔬菜 . 苗木 种植 . 销售 ( 依法 须 经 批准 的 项目 , 经 相关 部门 批准 后方 可 开展 经营 活动 ) __label__A 江苏 嘉利欣 农业 科技 有限公司 农业 科技 研发 . 转让 . 咨询服务 展览 展示 服务 现代农业 休

基于朴素贝叶斯分类器的文本分类算法

源代码下载:NaviveBayesClassify.rar Preface 文本的分类和聚类是一个比较有意思的话题,我以前也写过一篇blog<基于K-Means的文本聚类算法>,加上最近读了几本数据挖掘和机器学习的书籍,因此很想写点东西来记录下学习的所得. 在本文的上半部分<基于朴素贝叶斯分类器的文本分类算法(上)>一文中简单介绍了贝叶斯学习的基本理论,这一篇将展示如何将该理论运用到中文文本分类中来,具体的文本分类原理就不再介绍了,在上半部分有,也可以参见代码的注释. 文本特征向量

机器学习经典算法详解及Python实现---朴素贝叶斯分类及其在文本分类、垃圾邮件检测中的应用

摘要: 朴素贝叶斯分类是贝叶斯分类器的一种,贝叶斯分类算法是统计学的一种分类方法,利用概率统计知识进行分类,其分类原理就是利用贝叶斯公式根据某对象的先验概率计算出其后验概率(即该对象属于某一类的概率),然后选择具有最大后验概率的类作为该对象所属的类.总的来说:当样本特征个数较多或者特征之间相关性较大时,朴素贝叶斯分类效率比不上决策树模型:当各特征相关性较小时,朴素贝叶斯分类性能最为良好.另外朴素贝叶斯的计算过程类条件概率等计算彼此是独立的,因此特别适于分布式计算.本文详述了朴素贝叶斯分类的统计学

中文文本分类器训练集

sougou还真地道.中文文本分类器训练集下载 http://www.sogou.com/labs/dl/c.html mini版(tar.gz格式) 136Kmini版(zip格式) 167K精简版(tar.gz格式) 24M精简版(zip格式) 30M完整版 107M(由于文件较大,需要注册后获取ftp地址下载)分类编码对照表(txt格式) 138字节

多种贝叶斯模型构建文本分类

多种贝叶斯模型构建及文本分类的实现 作者:白宁超 2015年9月29日11:10:02 摘要:当前数据挖掘技术使用最为广泛的莫过于文本挖掘领域,包括领域本体构建.短文本实体抽取以及代码的语义级构件方法研究.常用的数据挖掘功能包括分类.聚类.预测和关联四大模型.本文针对四大模型之一的分类进行讨论.分类算法包括回归.决策树.支持向量机.贝叶斯等,显然,不少涉及机器学习的知识(随后会写些机器学习专题).本文重点介绍贝叶斯分类,涉及朴素贝叶斯模型.二项独立模型.多项模型.混合模型等知识.在本人研究贝叶斯