朴素贝叶斯,TF-IDF实现文本分类

TF-IDF概述

TF-IDFTerm Frequency -  Inverse Document Frequency的缩写,即词频-逆文本频率。它由两部分组成,TFIDF

前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即逆文本频率如何理解。在上一节中,我们讲到几乎所有文本都会出现的"to"其词频虽然高,但是重要性却应该比词频低的"China"“Travel”要低。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。

概括来讲, IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0

上面是从定性上说明的IDF的作用,那么如何对一个词的IDF进行定量分析呢?这里直接给出一个词xIDF的基本公式如下:

                                                              

 

其中,N代表语料库中文本的总数,而N(x)代表语料库中包含词x的文本总数。为什么IDF的基本公式应该是上面这样的,而不是像N/N(x)这样的形式呢?这就涉及到信息论相关的一些知识了。感兴趣的朋友建议阅读吴军博士的《数学之美》第11章。

上面的IDF公式已经可以使用了,但是在一些特殊的情况会有一些小问题,比如某一个生僻词在语料库中没有,这样我们的分母为0 IDF没有意义了。所以常用的IDF我们需要做一些平滑,使语料库中没有出现的词也可以得到一个合适的IDF值。平滑的方法有很多种,最常见的IDF平滑后的公式之一为:

                                                         

有了IDF的定义,我们就可以计算某一个词的TF-IDF值了:

TFIDF(x)=TF(x) * IDF(x)

其中TF(x)指词x在当前文本中的词频。

代码实现文本分类如下:

import os
import jieba
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB

# 以空格来划分每一个分词
def preprocess(path):
    text_with_space = ""
    textfile = open(path, "r", encoding="utf-8").read()
    textcute = jieba.cut(textfile)
    for word in textcute:
        text_with_space += word + " "
        # print(text_with_space)
    return text_with_space



def loadtrainset(path, classtag):
    allfiles = os.listdir(path)  # os.path.isdir()用于判断对象是否为一个目录,并返回此目录下的所有文件名
    processed_textset = []
    allclasstags = []

    for thisfile in allfiles:
        # print(thisfile)
        path_name = path + "/" + thisfile
        processed_textset.append(preprocess(path_name))
        allclasstags.append(classtag)
    return processed_textset, allclasstags  # 数组形式--processed_textset 文件的具体内容, allclasstags 文件分类


processed_textdata1, class1 = loadtrainset("E:/Desk/MyProjects/Python/NLP/dataset/train/hotel", "宾馆")
processed_textdata2, class2 = loadtrainset("E:/Desk/MyProjects/Python/NLP/dataset/train/travel", "旅游")


train_data = processed_textdata1 + processed_textdata2
# print(train_data)  # 前半部分是宾馆, 后半部分是旅游 train
classtags_list = class1 + class2  # 前半部分是宾馆, 后半部分是旅游 train 集结果
#
# print(train_data)
# print(classtags_list)
"""
# CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵
    get_feature_names()可看到所有文本的关键字
    vocabulary_可看到所有文本的关键字和其位置
    toarray()可看到词频矩阵的结果

"""

count_vector = CountVectorizer()
vecot_matrix = count_vector.fit_transform(train_data)

# print (count_vector.get_feature_names ())  #看到所有文本的关键字
# print (count_vector.vocabulary_)   #文本的关键字和其位置
# print (vecot_matrix.toarray ())  #词频矩阵的结果

# #TFIDF
"""TfidfTransformer是统计CountVectorizer中每个词语的tf-idf权值
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
vectorizer.fit_transform(corpus)将文本corpus输入,得到词频矩阵

将这个矩阵作为输入,用transformer.fit_transform(词频矩阵)得到TF-IDF权重矩阵
TfidfTransformer + CountVectorizer  =  TfidfVectorizer

这个成员的意义是词典索引,对应的是TF-IDF权重矩阵的列,只不过一个是私有成员,一个是外部输入,原则上应该保持一致。
    use_idf:boolean, optional 启动inverse-document-frequency重新计算权重
"""
# print(train_tfidf)  # vecot_matrix输入,得到词频矩阵
train_tfidf = TfidfTransformer(use_idf=False).fit_transform(vecot_matrix)
#MultinomialNB(),fit() ,多分类, Fit Naive Bayes classifier according to X,根据 X,Y,结果 类别,进行多分类
# print(train_tfidf)
# print(classtags_list)
clf = MultinomialNB().fit(train_tfidf, classtags_list)

testset = []
path = "E:/Desk/MyProjects/Python/NLP/dataset/tt"
allfiles = os.listdir(path)
hotel = 0
travel = 0


for thisfile in allfiles:
    path_name = path + "/" + thisfile  # 得到此目录下的文件绝对路径
    new_count_vector = count_vector.transform([preprocess(path_name)]) # 得到测试集的词频矩阵
# 用transformer.fit_transform(词频矩阵)得到TF-IDF权重矩阵
    new_tfidf = TfidfTransformer(use_idf=False).fit_transform(new_count_vector)

    # 根据 由训练集而得到的分类模型,clf ,由 测试集的 TF-IDF权重矩阵来进行预测分类
    predict_result = clf.predict(new_tfidf)
    print(predict_result)
    print(thisfile)

    if(predict_result == "宾馆"):
        hotel += 1
    if(predict_result == "旅游"):
        travel += 1

print("宾馆" + str(hotel))
print("旅游" + str(travel))

 

可到github:https://github.com/Whq123/Turbo_Demo 下载完整项目(包括数据集)

  • 5
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实现tf-idf中文文本分类的步骤如下: 1. 中文分词 首先需要对中文文本进行分词,将文本划分为一个个词语。可以使用中文分词工具,如jieba等。 2. 构建词典 根据分词结果,可以构建一个词典,将每个词语映射到一个唯一的索引。可以使用Python中的Counter类来计算每个词语在文本中出现的次数,并进行排序选取出现频率最高的k个词语构建词典。 3. 计算TF-IDF值 对于每篇文本,可以计算其每个词语的TF-IDF值。TF(词频)表示该词在文本中出现的次数,IDF(逆文本频率)表示包含该词的文本数与总文本数的比值的对数的倒数。可以使用Python中的TfidfTransformer类计算每篇文本的TF-IDF值。 4. 编码文本 将每篇文本转换为一个向量表示。对于每个词语,将其TF-IDF值作为向量对应索引位置的权重。如果该词语不在文本中出现,则该索引位置的权重为0。 5. 训练分类器 可以使用机器学习算法(如朴素贝叶斯、支持向量机、决策树等)对这些特征向量进行训练,建立一个分类模型。可以使用Python中的sklearn库来实现。 6. 分类预测 当有新的文本需要进行分类时,可以将其转换成特征向量,并使用训练好的模型对其进行分类预测。 需要注意的是,在进行中文文本分类时,需要尽可能地使用大量、高质量的训练数据来提高分类的准确性。同时,需要注意处理停用词、同义词等问题,以提高分类效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值