当前位置: 首页 > news >正文

深度学习笔记(6)文本分类

深度学习笔记(6)文本分类

文章目录

  • 深度学习笔记(6)文本分类
  • 一、文本分析与关键词提取
    • 1.关键概念
      • 1.停用词
      • 2 Tf-idf:关键词提取
    • 3.相似度
  • 二、文本分析案例
    • 1.数据处理
    • 2.分词:实用结巴分词器
    • 3.清洗
    • 4.TF-IDF
    • 5.LDA:主题模型
    • 6.贝叶斯算法分类


一、文本分析与关键词提取

1.关键概念

1.停用词

大量出现并且没啥大用的词,我们就把它去掉。通常用停用词表来进行过滤。(晚上有些现成的词表可以下载)

2 Tf-idf:关键词提取

1.先去掉停用词,再进行词频统计
2.分析词频高的词进行idf
如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。
TF表示词频,即一个词在文档中出现的次数。TF的计算公式通常如下:
TF ( t , d ) = 词  t 在文档  d 中出现的次数 文档  d 中词的总数 % TF(词频) \text{TF}(t, d) = \frac{\text{词 } t \text{ 在文档 } d \text{ 中出现的次数}}{\text{文档 } d \text{ 中词的总数}} TF(t,d)=文档 d 中词的总数 t 在文档 d 中出现的次数
IDF ( t ) = log ⁡ 文档总数 包含词  t 的文档数 + 1 % IDF(逆文档频率) \text{IDF}(t) = \log\frac{\text{文档总数}}{\text{包含词 } t \text{ 的文档数} + 1} IDF(t)=log包含词 t 的文档数+1文档总数
TF-IDF ( t , d ) = TF ( t , d ) × IDF ( t ) % TF-IDF \text{TF-IDF}(t, d) = \text{TF}(t, d) \times \text{IDF}(t) TF-IDF(t,d)=TF(t,d)×IDF(t)
比如下面的一个例子(文档数可以用google搜索的数据)
在这里插入图片描述

3.相似度

相似度
句子A:我喜欢看电视,不喜欢看电影
句子B:我不喜欢看电视,也不喜欢看电影。
分词:
句子A:我/喜欢/看/电视,不/喜欢/看/电影
句子B:我/不/喜欢/看/电视,也/不/喜欢/看/电影。
语料库:我,喜欢,看,电视,电影,不,也。
词频:
句子A:我1,喜欢2,看2,电视1,电影1,不1,也0。
句子B:我1,喜欢2,看2,电视1,电影1,不2,也1。
词频向量:
句子A : [1, 2, 2, 1, 1, 1, 0]
句子B : [1, 2, 2, 1, 1, 2, 1]

二、文本分析案例

1.数据处理

1.实用jieba分词器进行分词:可以非常方便地为中文文本进行分词,即将连续的中文文本切分成具有独立意义的词语。

import pandas as pd
import jieba

基本处理
打开当前文本然后起几个列名字,因为是中文,所以指定成utf-8的文字格式

import pandas as pd  # 导入pandas库,用于数据处理# 读取文本文件,并指定列名
df_news = pd.read_table('./data/val.txt',  # 文件路径names=['category', 'theme', 'URL', 'content'],  # 指定列名encoding='utf-8'  # 指定文件编码格式为UTF-8
)# 删除含有缺失值的行
df_news = df_news.dropna()# 显示数据框的前5行,用于检查数据
df_news.head()``````python
# 获取DataFrame的形状,即行数和列数
df_news_shape = df_news.shape

2.分词:实用结巴分词器

因为结巴分词器要求输入的是list格式,所以要转成list格式

# 将DataFrame中'content'列的数据转换为列表
content = df_news['content'].values.tolist()# 打印列表中索引为1000的元素,即DataFrame中'content'列的第1001条记录
print(content[1000])

下面这段代码通过jieba库对文本内容进行分词处理,并将分词后的结果存储在一个新的列表中。在添加分词结果到列表之前,它检查分词后的列表长度是否大于1,以确保不是空行或只有一个词的行。这样做是为了排除那些没有实际内容的行。

content_S = []  # 初始化一个空列表,用于存储分词后的结果
# 遍历原始内容列表中的每一行
for line in content:# 使用jieba库进行分词,返回分词后的列表current_segment = jieba.lcut(line)# 检查分词后的结果是否包含多个词(即长度大于1)并且不是空行(即不是'\r\n')if len(current_segment) > 1 and current_segment != '\r\n':# 如果条件满足,将当前分词结果添加到content_S列表中content_S.append(current_segment)

这段代码创建了一个新的pandas DataFrame,其中包含一个名为’content_S’的列,该列存储了之前通过jieba分词处理后的文本内容。使用head()函数可以快速查看DataFrame的前5行数据,以确认分词结果是否正确。

# 创建一个新的DataFrame,其中包含分词后的内容
df_content = pd.DataFrame({'content_S': content_S})# 显示新创建的DataFrame的前5行,用于检查分词后的数据
df_content.head()

3.清洗

使用停用词表去掉那些垃圾词

# 读取停用词文件,将其转换为DataFrame
stopwords = pd.read_csv("stopwords.txt",  # 停用词文件的路径index_col=False,  # 不将任何一列设为索引sep="\t",         # 文件中的分隔符为制表符quoting=3,        # 引用模式3,忽略双引号names=['stopword'],  # 为DataFrame指定列名encoding='utf-8'  # 文件编码格式为UTF-8
)
# 显示前20个停用词,用于检查停用词列表
stopwords.head(20)

这段代码定义了一个drop_stopwords函数,该函数接受文本内容和停用词列表作为输入,并返回清理后的文本内容和所有非停用词。清理过程包括移除每一行中的停用词,并将非停用词添加到新的列表中。最后,通过调用这个函数并传入相应的参数,得到清理后的文本和词列表。

# 定义一个函数,用于移除文本中的停用词
def drop_stopwords(contents, stopwords):contents_clean = []  # 初始化一个列表,用于存储清理后的文本all_words = []  # 初始化一个列表,用于存储所有非停用词# 遍历文本中的每一行for line in contents:line_clean = []  # 初始化一个列表,用于存储清理后的当前行# 遍历当前行中的每一个词for word in line:# 如果这个词是停用词,则跳过if word in stopwords:continue# 否则,将这个词添加到清理后的当前行列表中line_clean.append(word)# 同时,将这个词添加到所有非停用词列表中all_words.append(str(word))# 将清理后的当前行添加到清理后的文本列表中contents_clean.append(line_clean)# 返回清理后的文本列表和所有非停用词列表return contents_clean, all_words#print (contents_clean)  # 注释掉,不执行打印操作# 将DataFrame中的文本内容转换为列表
contents = df_content.content_S.values.tolist()# 将停用词DataFrame中的停用词转换为列表
stopwords = stopwords.stopword.values.tolist()# 调用drop_stopwords函数,传入文本内容和停用词列表,获取清理后的文本和所有非停用词
contents_clean, all_words = drop_stopwords(contents, stopwords)

在这里插入图片描述
这里面有些字母,也没啥意义,建议在停用词表中去掉。

下面这段代码将之前从文本中提取的所有非停用词列表转换为一个pandas DataFrame,其中包含一个名为’all_words’的列。使用head()函数可以快速查看DataFrame的前5行数据,以确认非停用词列表是否正确地被加载和展示。

# 创建一个新的DataFrame,其中包含所有非停用词
df_all_words = pd.DataFrame({'all_words': all_words})# 显示新创建的DataFrame的前5行,用于检查包含所有非停用词的数据
df_all_words.head()

下面这段代码的目的是统计文本中每个非停用词的出现次数,并按照出现次数从高到低进行排序,最后查看出现次数最多的几个词。这在文本分析中是一个常见的步骤,用于理解文本的主要内容和关键词。

import numpy  # 导入numpy库,用于数据处理# 创建一个新的DataFrame,其中包含所有非停用词
df_all_words = pd.DataFrame({'all_words': all_words})# 显示新创建的DataFrame的前5行,用于检查包含所有非停用词的数据
df_all_words.head()# 使用groupby对所有的词进行分组,并计算每个词出现的次数
# 直接使用numpy.size作为聚合函数,而不是一个字典
words_count = df_all_words.groupby(by=['all_words']).size().reset_index(name='count')# 按照词出现的次数进行降序排序
words_count = words_count.sort_values(by=["count"], ascending=False)# 显示排序后的前5行数据,查看出现次数最多的词
words_count.head()

在这里插入图片描述

然后导入词云这样的差距 实现可视化的一个操作,开源地址是这个https://github.com/amueller/word_cloud

from wordcloud import WordCloud  # 导入WordCloud库,用于生成词云
import matplotlib.pyplot as plt  # 导入matplotlib.pyplot库,用于绘制图表
# 启用matplotlib的inline模式,以便在Jupyter笔记本中直接显示图表
%matplotlib inline
import matplotlib  # 导入matplotlib库,用于设置图表的显示参数# 设置matplotlib图表的默认大小为宽度10.0,高度5.0
matplotlib.rcParams['figure.figsize'] = (10.0, 5.0)# 创建一个WordCloud对象,设置字体路径、背景颜色和最大字体大小
wordcloud = WordCloud(font_path="./data/simhei.ttf", background_color="white", max_font_size=80)# 从words_count DataFrame中提取出现次数最多的前100个词及其频率
word_frequence = {x[0]: x[1] for x in words_count.head(100).values}# 将提取的词频数据传递给WordCloud对象,生成词云
wordcloud = wordcloud.fit_words(word_frequence)# 使用matplotlib显示生成的词云图像
plt.imshow(wordcloud)

在这里插入图片描述

4.TF-IDF

使用jieba.analyse.extract_tags方法提取content_S_str中的前5个关键词,并打印这些关键词。extract_tags方法允许指定要提取的关键词数量(通过topK参数)和是否包含权重(通过withWeight参数)。在这个例子中,我们不包含权重,只打印关键词。

import jieba.analyse  # 导入jieba.analyse模块,用于文本分析# 定义一个变量,用于存储索引位置
index = 2400# 打印DataFrame中指定索引位置的'content'列的文本内容
print(df_news['content'][index])# 将content_S列表中指定索引位置的文本内容合并为一个字符串
content_S_str = "".join(content_S[index])# 使用jieba.analyse.extract_tags方法提取指定文本内容中的前5个关键词,不包含权重
# topK参数指定要提取的关键词数量,withWeight参数指定是否包含权重
print("  ".join(jieba.analyse.extract_tags(content_S_str, topK=5, withWeight=False)))

5.LDA:主题模型

LDA是一种强大的文本分析工具,能够揭示文档中的潜在主题结构。它广泛应用于自然语言处理和信息检索领域,为文本数据的挖掘和分析提供了新的视角和方法。格式要求:list of list形式,分词好的的整个语料
Gensim:Gensim 是一个 Python 库,主要用于处理和分析大规模的文本数据集。它提供了许多文本处理和信息提取的工具,例如词嵌入(Word Embedding)、主题建模(Topic Modeling)、命名实体识别(Named Entity Recognition)等。Gensim 特别适合于处理大规模的文本数据集,因为它提供了高效的算法和工具来处理和分析这些数据。

from gensim import corpora, models, similarities
import gensim# 导入Gensim库的必要部分
# corpora模块用于处理和操作语料库
# models模块包含了一些预定义的模型,如LDA、TF-IDF等
# similarities模块包含了一些相似性度量方法,如余弦相似性# 创建一个Dictionary对象,它用于存储词汇和它们的索引
# 这里的contents_clean是一个列表,其中包含已经清理过的文本内容
dictionary = corpora.Dictionary(contents_clean)# 使用doc2bow方法将文档转换为BOW(Bag of Words)向量形式
# 这里的contents_clean是一个列表,其中包含已经清理过的文本内容
corpus = [dictionary.doc2bow(sentence) for sentence in contents_clean]

导入LDA 模块,语料传进来,映射字典传进来,指定的主题值越准越好 ,因为是无监督的,所以要自己指定。

# 导入Gensim库的LDA模型模块
from gensim import models# 创建一个LdaModel对象,用于训练LDA模型
# corpus参数是一个包含文档的列表,其中每个文档是一个词袋向量
# id2word参数是一个Dictionary对象,它包含词汇和它们的索引
# num_topics参数指定要生成的主题数量
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)

这段代码首先打印了LDA模型中第一个主题的前5个关键词及其权重。然后,通过一个循环遍历了LDA模型中的所有主题,并打印了每个主题的前5个关键词及其权重。这样可以帮助我们更好地理解每个主题所代表的含义,从而为文本分类、关键词提取等任务提供指导。

# 打印第一个主题的关键词及其权重
# lda.print_topic(1, topn=5) 表示打印编号为1的主题,并且只打印前5个关键词
print(lda.print_topic(1, topn=5))# 打印所有主题的关键词及其权重
# for topic in lda.print_topics(num_topics=20, num_words=5):
#     循环遍历lda模型中的所有主题
#      num_topics参数指定要打印的主题数量
#      num_words参数指定每个主题要打印的关键词数量
#     打印当前主题的关键词及其权重
for topic in lda.print_topics(num_topics=20, num_words=5):print(topic[1])

6.贝叶斯算法分类

'contents_clean’列存储了清理后的文本内容,而’label’列存储了每个文本对应的类别标签。最后,代码使用tail()函数显示DataFrame的最后几行,以检查数据的完整性。

# 导入pandas库,用于数据处理
import pandas as pd# 创建一个新的DataFrame,其中包含清理后的文本内容和对应的标签
# 'contents_clean'列存储清理后的文本内容
# 'label'列存储每个文本对应的类别标签 category列就是对应的标签列
df_train = pd.DataFrame({'contents_clean': contents_clean, 'label': df_news['category']})# 显示DataFrame的最后几行,用于检查数据的完整性
df_train.tail()
# 打印DataFrame中'label'列的唯一值,以查看标签的种类
print(df_train.label.unique())# 定义一个字典,将文本标签映射为数字标签
# 例如,"汽车"映射为1,"财经"映射为2,依此类推
label_mapping = {"汽车": 1, "财经": 2, "科技": 3, "健康": 4, "体育": 5, "教育": 6, "文化": 7, "军事": 8, "娱乐": 9, "时尚": 0}# 使用map方法将DataFrame中的'label'列的文本标签映射为数字标签
# 使用上述定义的字典作为映射表
df_train['label'] = df_train['label'].map(label_mapping)# 显示映射后的DataFrame的前几行,以查看标签的映射结果
df_train.head()

划分测试集和训练集

# 导入sklearn.model_selection模块中的train_test_split函数
from sklearn.model_selection import train_test_split# 使用train_test_split函数将数据集划分为训练集和测试集
# x_train和x_test分别存储训练集和测试集的文本内容
# y_train和y_test分别存储训练集和测试集的标签
x_train, x_test, y_train, y_test = train_test_split(df_train['contents_clean'].values,  # 输入数据集的文本内容df_train['label'].values,           # 输入数据集的标签random_state=1                      # 设置随机状态,确保每次运行时分割结果一致
)

试将训练集的文本内容转换为一个单词列表,并存储在变量 words 中。

# 初始化一个空列表,用于存储转换后的单词列表
words = []# 遍历训练集的每个文档
for line_index in range(len(x_train)):# 尝试将当前文档的单词列表添加到words列表中try:# 将当前文档的单词列表转换为一个字符串,并添加到words列表中words.append(' '.join(x_train[line_index]))except:# 如果转换过程中出现异常,打印出发生异常的文档索引和单词索引print(line_index, word_index)# 打印words列表中的第一个元素,以检查转换是否成功
print(words[0])

下面这段代码是简单演示下sklearn的构造向量的输入长什么样
用空格来分词,逗号分隔文章,代码如下

from sklearn.feature_extraction.text import CountVectorizertexts = ["dog cat fish","dog cat cat","fish bird", 'bird']
cv = CountVectorizer()
cv_fit = cv.fit_transform(texts)# 获取特征名称(即词的列表)
feature_names = cv.get_feature_names_out()# 打印特征名称
print(feature_names)# 打印转换后的词频向量
print(cv_fit.toarray())# 打印词频向量的列之和
print(cv_fit.toarray().sum(axis=0))

结果如图,第一篇文章bird出现0,cat出现1,dog出现1,fish出现1 依此类推
在这里插入图片描述

那么同理,使用下面代码进行构造向量

from sklearn.feature_extraction.text import CountVectorizer
# 创建一个CountVectorizer对象
# analyzer参数指定如何分析文本,这里指定为'word',即只考虑单词
# max_features参数指定最大特征数量,这里设置为4000
# lowercase参数指定是否将文本转换为小写,这里设置为False
vec = CountVectorizer(analyzer='word', max_features=4000, lowercase=False)# 使用fit方法训练CountVectorizer,使用words数据集
# fit方法会学习单词和它们的频率,并创建一个模型
vec.fit(words)

然后对文本作一个分类器

from sklearn.naive_bayes import MultinomialNB# 导入Multinomial Naive Bayes分类器
# MultinomialNB适用于文本数据,它假设特征的分布是多项式的classifier = MultinomialNB()# 创建一个Multinomial Naive Bayes分类器实例
# 默认情况下,它将使用多项式估计,并假设特征的分布是多项式的classifier.fit(vec.transform(words), y_train)# 使用fit方法训练分类器
# 参数vec.transform(words)将words数据集转换为词频向量
# y_train是训练数据集的标签,它应该是一个包含标签的列表或数组

同样对测试集预处理,注意,测试集和训练集预处理要一样

test_words = []
for line_index in range(len(x_test)):try:#x_train[line_index][word_index] = str(x_train[line_index][word_index])test_words.append(' '.join(x_test[line_index]))except:print (line_index,word_index)
test_words[0]
classifier.score(vec.transform(test_words), y_test)

测试分0.804

上面的是基本的贝叶斯,那么实用TFI-DF预测代码如下

from sklearn.feature_extraction.text import TfidfVectorizervectorizer = TfidfVectorizer(analyzer='word', max_features=4000,  lowercase = False)
vectorizer.fit(words)
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(vectorizer.transform(words), y_train)
classifier.score(vectorizer.transform(test_words), y_test)

测试分0.8152


http://www.mrgr.cn/news/27894.html

相关文章:

  • [Admin] Dashboard Filter for Mix Report Types
  • 【日常记录-Git】git log
  • uni-app移动端与PC端兼容预览PDF文件
  • css 溢出隐藏显示省略号
  • 【数据结构 | C++】整型关键字的平方探测法散列
  • C#中 layout的用法
  • Python中匹配HTML标签时<.*>和<.*?>有什么区别
  • 顺序栈和链栈
  • 828华为云征文 | 华为云Flexus X实例柔性算力助力中小企业和开发者
  • 【最佳实践】配置类封装-Async异步注解以及自定义线程池
  • python多线程程序设计 之二
  • 第十一章 【后端】商品分类管理微服务(11.2)——Lombok
  • 常见饮料和食物的碳水含量
  • Golang | Leetcode Golang题解之第409题最长回文串
  • Python | Leetcode Python题解之第409题最长回文串
  • 读构建可扩展分布式系统:方法与实践05分布式缓存
  • 进程和线程(JAVA基础)
  • (MySQL、Redis)数据库的连接、启动和关闭的常用命令
  • 【人工智能】复刻抖音爆款AI数字人视频初体验
  • Android14音频进阶之如何集成音效(八十五)
  • Java | Leetcode Java题解之第409题最长回文串
  • NISP 一级 | 5.4 数据安全
  • Linux进阶 把用户加入和移除用户组
  • Python快速入门 —— 第三节:类与对象
  • C++语法应用:返回指向局部变量的引用__使用new分配空间(不推荐)
  • 使用Elasticsearch进行全文搜索的Python函数实现