自然语言处理之基于朴素贝叶斯的文本分类相关学习与实践、词云、混淆矩阵、分类报告

文章介绍了如何使用朴素贝叶斯进行文本分类,包括数据集划分、文本预处理(分词)、生成TF-IDF矩阵和构建MultinomialNB分类器。通过测试集检验,展示了分类报告和混淆矩阵,表明模型的accuracy约为0.82。
摘要由CSDN通过智能技术生成


前言

本文记录了基于朴素贝叶斯的文本分类的相关学习与实践


一、划分数据集

语料数据集结构:

 'C000008': '_08_Finance'
 'C000010': '_10_IT'
 'C000013': '_13_Health'
 'C000014': '_14_Sports'
 'C000016': '_16_Travel'
 'C000020': '_20_Education'
 'C000022': '_22_Recruit'
 'C000023': '_23_Culture'
 'C000024': '_24_Military'

语料数据集解释:
一共有9类文章,分别为金融、IT、健康、运动、旅游、教育、招聘、文化、军事。每一类都有一个文件夹,每个文件夹中包含1990篇该类文章,一共17910篇文章。

把语料划分为训练集和测试集,比例为8:2(14328:3582),划分后文件结构如下:
数据集划分

二、语料预处理

1.文本提取及分词

原理是通过“文件的读写操作+jieba切分操作”实现文本提取及分词,详细代码如下:
(1)文本提取函数:

def Txt(str):
    cut_words = []
    for line in open(str, encoding='gb18030'):
        line = re.sub(
            "[A-Za-z \. \: \;\【\】\¥\% \ \( \) \:\·\—\,\。\、\, \“ \”\n \?\#  \  《 \》\( \) \;\- \‘ \’ " + ue + "]", "",
            line)
        if (line == ""):
            continue
        seg_list = jieba.cut(line, cut_all=True)  # 全模式cut_all=True
        cut_words.append(" ".join(seg_list))
    return cut_words

(2)分词函数:

def train_cut(strr):
    for i in range(1602, 2000):
        string1 = 'data/train/train/' + strr + str(i) + '.txt'
        string2 = 'data/train/' + strr + str(i) + '.txt'
        str1 = " ".join(Txt(string1))
        filename = string2
        file = open(filename, "w")
        with open(filename, "w") as file:
            file.write(str1)
        print(i)
def test_cut(strr):
    for i in range(1602, 2000):
        string1 = 'data/test/test/' + strr + str(i) + '.txt'
        string2 = 'data/test/' + strr + str(i) + '.txt'
        str1 = " ".join(Txt(string1))
        filename = string2
        file = open(filename, "w")
        with open(filename, "w") as file:
            file.write(str1)
        print(i)

代码解释:
(1)train_cut()与test_cut()函数原理一样,只是文件地址不一样,分开对训练集和测试集数据进行预处理。
(2)string1是读取的文件的地址,string2是写入的文件的地址。
(3)Txt()函数中读取时encoding=‘gb18030’,可以根据编码需要改为utf-8或者其他。
(4)文件地址处为作者使用的文件地址,可以改为你作使用的文件地址。
(5)for i in range(1602, 2000)是作者使用的文件数量,可以根据你自己的选择更改。

2.生成总数据集

(1)由于上述处理后,对单个类型文件中的所有文章进行读取,获得单个类型文件的数据集,具体代码如下:

def datas_train(strrr, strl):
    dataset = []
    x_train_data = []
    y_train = []
    for file_path in glob.glob(os.path.join('data/train/' + strrr, '*.txt')):
        with open(file_path, 'r') as file:
            for line in file:
                if line == "":
                    data = ""
                else:
                    data = line.strip()
                label = os.path.basename(strl).split('.')[0]  # 获取文件名作为标签
                dataset.append((label, data))
    for i in range(len(dataset)):
        x_train_data.append(dataset[i][1])
        y_train.append(dataset[i][0])
    return x_train_data, y_train

代码解释:
(1)此函数是获得每一类训练集数据集的函数,对于测试集,只需要把上述函数中的路径改为测试集文件地址即可。
(2)此函数要输入两个值,第一个strrr是该类文件所在的路径名。第二个strl是你想给该类文件数据集贴上的标签名,例如:
x_test_data1, y_test1 = datas_test("C000008", "_08_Finance")
上述代码就是把第一类(金融)的所有文章集合成一个金融类文章数据集,并打上标签为“_08_Finance”。
(3)得到的x_test_data1和y_test1都是数组类型的。

(2)为了方便之后模型训练,我们需要把所有类的文章合到一个数据集中,此时要用到numpy中的concatenate进行数组拼接,例如:

x_test_data=np.concatenate((x_test_data1,x_test_data2,x_test_data3,x_test_data4,x_test_data5,x_test_data6,x_test_data7,x_test_data8,x_test_data9))
y_test=np.concatenate((y_test1,y_test2,y_test3,y_test4,y_test5,y_test6,y_test7,y_test8,y_test9))

代码解释:
上述代码就是把这九个类的文章数据集合成一个总数据集x_test_data,以及总数据集对应的标签集合y_test,这个标签集合可以用来评估我们训练的模型的准确率。

3.将文档集合转化为TF-IDF矩阵

TF-IDF矩阵:可以将文档集合中的每个文档表示为一个向量,其中每个维度对应一个词语,并且该维度的值表示该词语在该文档中的重要性。这种表示方式可以方便地进行文本分类、聚类等任务。如果不进行TF-IDF转换,那么每个文档只能表示为一个词袋模型,无法体现词语的重要性,这会影响文本分类、聚类等任务的效果。
(1)制造停用词stopwords
这一步是为了去除你不想看到或者对文章类别区别性不大的词语,如果你的文章区别性词语出现的频率足够高,这一步也可以省略。
制造方法:使用数组即可,例如:

stopwords_list = ['where', 'me', "hasn't", "she'd","的","个","就"]

(2)使用TfidfVectorizer将文档集合转为TF-IDF矩阵
TfidfVectorizer的主要参数有

  • max_df
  • min_df
  • max_features
  • stop_words

其中,max_df和min_df用于控制词语的出现频率,max_features用于控制词语的数量,stop_words用于指定停用词
TfidfVectorizer的常用函数:

  • fit_transform
  • transform
  • get_feature_names
  • idf_

其中,fit_transform用于将文本集合转换为TF-IDF矩阵,transform用于将新的文本转换为TF-IDF向量,get_feature_names和idf_用于获取TF-IDF矩阵中每个维度对应的词语

注意: 从sklearn0.15版本开始,可以通过TfidfVectorizer对象的属性idf_检索每个特征的tf-idf分数,而不存在get_feature_names()属性了。

具体代码如下:

tfidf_vec = TfidfVectorizer(stop_words=stopwords_list)
x_train_tfidf = tfidf_vec.fit_transform(x_train_data)
words = tfidf_vec.idf_

另外: 还可以用停用词生成词云图,代码如下:

my_stopwords = set(STOPWORDS)     
for i in stopwords_list:
   my_stopwords.add(i)
word_cloud = WordCloud(font_path="simsun.ttc",background_color="white",width=2000,height=1600,stopwords=my_stopwords)
word_cloud.generate(x_train_data[0])
word_cloud.to_file('词云图.png')

代码解释:
(1)这里的STOPWORDS是从wordcloud导入的一个变量。
(2)使用WordCloud生成词云,WordCloud常用属性有:

  • background_color:词云图的背景颜色,默认为黑色。
  • width:词云图的宽度,默认为400像素。
  • height:词云图的高度,默认为200像素。
  • max_words:词云图中最多显示的词语数量,默认为200。
  • stopwords:停用词列表,用于过滤掉一些常见的无意义词语。
  • colormap:词云图的颜色映射表,用于指定词语的颜色。
  • font_path:字体文件路径,用于指定词云图中词语的字体。

效果如下:
词云图

三、构建朴素贝叶斯分类器

作者使用的是MultinomialNB方法。
MultinomialNB常用属性有:

  • alpha:平滑参数,用于控制模型的复杂度,较小的alpha值会使模型更加复杂,较大的alpha值会使模型更加简单。
  • fit_prior:用于控制是否学习类别的先验概率,默认为True,如果设置为False,则使用统一的先验概率。
  • class_prior:用于指定类别的先验概率,如果不指定则根据数据自动计算

MultinomialNB常用方法有:

  • fit():用于训练模型
  • predict():用于对新的样本进行分类,预测其属于的类型
  • predict_proba():用于获取样本属于各个类别的概率

代码示例如下:

from sklearn.naive_bayes import MultinomialNB

# 创建MultinomialNB对象
clf = MultinomialNB()

# 训练模型
clf.fit(X_train, y_train)

# 对新的样本进行分类
y_pred = clf.predict(X_test)

# 获取样本属于各个类别的概率
y_proba = clf.predict_proba(X_test)

其中: X_train是训练集的特征矩阵,y_train是训练集的标签X_test是测试集的特征矩阵,y_pred是预测的标签,y_proba是样本属于各个类别的概率。

具体代码如下:

classifier = MultinomialNB()
classifier.fit(x_train_tfidf, y_train)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)

四、测试集检验

1. 思路:

通过利用TfidfVectorizer的transform()将测试集转化为TF-IDF向量,然后利用MultinomialNB的predicted()对其进行预测。
具体代码如下:

x_new_data=x_test_data
x_new_tfidf = tfidf_vectorizer.transform(x_new_data)
predicted = classifier.predict(x_new_tfidf)

代码解释:
x_new_tfidf表示由测试集转化而来的TF-IDF向量,predicted表示预测的结果。

2.使用classification_report生成分类报告

classification_report是一个用于生成分类报告的工具,常用的属性有:

  • y_true:真实值,一维数组(元组、列表)形式
  • y_pred:预测值,一维数组(元组、列表)形式
  • labels:标签索引列表,数组形式(可选参数)
  • target_names:类别名称列表,用于指定每个类别的名称(可选参数)
  • sample_weight:样本权重,数组形式
  • digits:用于控制保留小数点后的位数,默认为2。
  • output_dict:是否输出字典格式的报告,默认为False,用于控制输出格式。

利用classification_report()进行Benchmark分类器评估,具体代码如下:

classification_report(y_test, predicted)

分类报告如下:
分类报告
由上图知,模型的accuracy约为0.82。

3.使用confusion_matrix计算混下矩阵

作用:可以用来展示分类模型的预测结果与真实结果之间的关系,便于评估模型性能。
confusion_matrix参数:真实标签(数据集中实际的标签)、预测标签(模型预测结果)。
具体代码如下:

confusion_matrix(y_test,predicted)

混淆矩阵

总结

以上就是作者基于朴素贝叶斯的文本分类的相关学习与实践过程内容,希望对各位有所帮助与启发,作者也在学习中,如有解释不清楚的地方,还请各位指正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值