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

.net 做手机网站吗百度指数查询官网

.net 做手机网站吗,百度指数查询官网,360建筑网官网下载平台,家装室内设计介绍 大家好#xff0c;我这个热衷于分享知识的博主又来啦#xff01;之前我们一起深入探讨了自然语言处理领域中非常重要的两个方法#xff1a;朴素贝叶斯和逻辑斯谛回归。在探索的过程中#xff0c;我们剖析了朴素贝叶斯如何基于概率原理和特征条件独立假设#xff0c;…介绍 大家好我这个热衷于分享知识的博主又来啦之前我们一起深入探讨了自然语言处理领域中非常重要的两个方法朴素贝叶斯和逻辑斯谛回归。在探索的过程中我们剖析了朴素贝叶斯如何基于概率原理和特征条件独立假设快速对文本进行分类。也了解了逻辑斯谛回归是怎样通过巧妙地将线性模型与逻辑函数相结合精准地预测文本的类别归属。 而今天我要带大家进一步深入自然语言处理的世界来聊聊文本分类这个关键的主题。有了之前对朴素贝叶斯和逻辑斯谛回归的讲解相信大家对文本分类中涉及的一些基础概念和核心思路已经有了一定的认知。我相信今天关于文本分类的分享理解起来会更加顺畅也能让大家更系统地掌握自然语言处理中这一重要的技术应用 文本分类 概念阐述 自然语言处理中的文本分类是指运用自然语言处理和机器学习等相关技术依据文本的内容、结构、语义、情感倾向等多方面特征将给定的文本自动划分到预先定义好的一个或多个类别中的过程。 这些预先设定的类别可以是诸如新闻领域中的政治、经济、文化、体育等主题分类电商场景里的产品好评、差评、中评的情感分类或者是垃圾邮件识别中的正常邮件与垃圾邮件分类等。 文本分类通过对文本信息的理解和分析实现对文本的有效组织与管理从而为信息检索、情感分析、内容推荐等自然语言处理任务提供支持。 基于规则的文本分类 在文本分类任务里基于规则的方法常运用正则表达式。具体来说针对每个文本类别我们都要编写一条甚至多条正则表达式。就拿商品评论分类举例 好评的正则表达式可以写成 “.(非常好 | 不错 | 很 (赞 | 满意)).” 它表示只要文本中出现“非常好”“不错”“很赞”“很满意”等词汇就可能属于好评。而差评的正则表达式 “.(太 (差 | 烂)| 糟糕 | 避雷).” 意味着文本里若有“太差”“太烂”“糟糕”“避雷”这类词大概率是差评。 我们用代码来演示一下 完整代码 # 导入正则表达式模块用于处理正则匹配 import re# 定义一个自然语言处理文本分类的类 class NLPTextClassification:# 类的初始化方法目前为空不做任何操作def __init__(self):pass# 定义文本分类方法接收一个评论文本作为输入def text_classification(self, review_text):# 定义分类规则列表包含正则表达式、类别和优先级classification_rules [# 定义好评的正则表达式规则匹配包含特定词汇的文本(re.compile(r.*(非常好|不错|很(赞|满意)).*), 好评, 1),# 定义差评的正则表达式规则匹配包含特定词汇的文本(re.compile(r.*(太(差|烂)|糟糕|避雷).*), 差评, 2)]# 存储匹配到的规则信息matched_classification_rules []# 遍历规则列表for regex_pattern, category, priority in classification_rules:# 检查评论是否匹配当前规则if regex_pattern.match(review_text):# 若匹配则添加到匹配规则列表matched_classification_rules.append((category, priority))# 若没有匹配到任何规则if len(matched_classification_rules) 0:# 返回未分类结果return 未分类# 若只匹配到一条规则elif len(matched_classification_rules) 1:# 返回该规则对应的类别return matched_classification_rules[0][0]else:# 对匹配规则按优先级排序matched_classification_rules.sort(keylambda x: x[1])# 返回优先级最高的规则对应的类别return matched_classification_rules[0][0]# 当脚本作为主程序运行时执行以下代码 if __name__ __main__:# 创建NLPTextClassification类的实例nlp_text_normalization NLPTextClassification()# 定义商品评论列表包含多条不同的评论文本product_reviews [这个商品非常好我很满意,这个商品太差了太烂了,这个商品不错但有点小瑕疵避雷吧,商品还行没什么特别的]# 遍历评论列表进行分类for review in product_reviews:# 调用实例的文本分类方法进行分类classification_result nlp_text_normalization.text_classification(review)# 打印评论内容及其分类结果print(f评论: {review}分类结果: {classification_result}) 运行结果 评论: 这个商品非常好我很满意分类结果: 好评 评论: 这个商品太差了太烂了分类结果: 差评 评论: 这个商品不错但有点小瑕疵避雷吧分类结果: 好评 评论: 商品还行没什么特别的分类结果: 未分类进程已结束退出代码为 0 当面对一篇文档时如果它只匹配上了一条正则表达式那直接就能确定其对应的类别。可要是文档同时匹配了多条对应不同类别的正则表达式就得提前设定好这些正则表达式的优先级输出优先级最高的那条正则表达式所对应的类别。 这种用正则表达式进行文本分类的方式有明显的优点 首先规则简单易懂即便是不太了解技术的人也能明白分类的依据。其次要是分类结果出错由于规则清晰能迅速找到是哪条规则出了问题方便及时修改比如删掉不合适的规则、增添新规则等。而且和基于机器学习的文本分类比起来它无需大量标注数据也不用复杂的训练过程能节省不少时间和精力。 不过它的缺点也不容忽视 一方面编写正则表达式需要既懂分类业务又熟悉正则表达式的专家人力门槛较高。另一方面由于语言表达的丰富性和多样性即使是专家也很难写出能涵盖所有情况的正则表达式导致覆盖率有限。另外在有标注数据的情况下这种方法难以借助这些数据自动优化规则缺乏自我提升的能力。 基于机器学习的文本分类 在自然语言处理领域基于机器学习的文本分类是指利用机器学习中的监督学习算法借助已标注好类别的训练数据(如由人工仔细标注的文档集合)让模型学习文本特征与类别之间的映射关系从而对新文本自动归类的过程。 该方式可分为生成式分类器和判别式分类器。生成式分类器着重对每个类别下的文本分布进行建模然后依据模型计算文本属于各类别的概率判别式分类器则聚焦于挖掘能有效区分不同类别的文本特征直接预测文本所属类别。 在这两类分类器中朴素贝叶斯算法便是典型的生成式分类器的代表。它基于条件独立假设等原理对每个类别内的文本分布进行建模。通过学习训练数据中每个类别出现的先验概率以及每个词在各个类别中出现的条件概率来计算文本属于不同类别的概率。 而逻辑斯谛回归则属于判别式分类器它直接挖掘文本中能够区分不同类别的特征通过构建逻辑函数将线性回归的输出转化为概率值以此预测文本的类别。 朴素贝叶斯 概念阐述 朴素贝叶斯是生成式分类器中的基础模型它基于概率论和贝叶斯定理通过计算文本在不同类别下的概率来判断文本类别。它假设文本中的各个特征(词)在给定类别下是相互独立的即条件独立假设同时采用词袋假设忽略词的顺序仅考虑词的出现情况将文本看作是词的集合。 公式展示 将文档表示为词的序列 类别集合为。根据贝叶斯公式计算文档属于类别的后验概率 由于对于所有类别都是相同的常数在比较不同类别概率大小时可忽略因此朴素贝叶斯分类的目标是求解 基于条件独立假设所以公式可进一步写为 其中是预测的文档类别是类别的先验概率是在类别下词出现的条件概率 。 原理解释 朴素贝叶斯的核心在于根据训练数据学习每个类别出现的先验概率以及每个词在各个类别中出现的条件概率。当对新文本分类时根据这些已学习到的概率结合贝叶斯公式计算该文本属于各个类别的后验概率最终将文本划分到后验概率最大的类别中。 具体而言先从训练集中统计每个类别文档的数量以计算先验概率再统计每个词在不同类别文档中出现的次数进而得到条件概率。对于新文本基于条件独立假设将文本中各个词的条件概率相乘再乘以先验概率得到该文本属于每个类别的概率值以此完成分类判断。 代码演示 接下来的几段代码将为大家展示朴素贝叶斯模型的训练与预测过程。这里所用到的数据集是代码自动生成的Books数据集其中涵盖了大约1万本图书的标题这些标题被划分成6种主题。 首先在正式进行模型训练和预测之前需要先进行数据预处理针对文本分类的预处理主要包含以下几个关键步骤 文本统一化对于英文文本通常把所有字母转换为小写形式而中文内容则统一转换为简体字。这样的操作一般不会对文本所表达的核心内容产生影响。标点去除英文里标点符号与单词紧密相连(比如“Lets go.”)要是去掉标点“Let s”和“go”会被当作和“Let”“s”“there”不同的词来识别这显然不符合实际情况。在中文里去掉标点通常也不会干扰文本想要传达的信息。分词处理中文和英文不同汉字之间没有空格来区分所以中文分词的难度有时会比英文分词更大具体的分词方法这里就不详细展开了。停用词清理像“and”“the”“了”这类词它们在文本中出现的频率很高但本身并没有实际的表意价值所以需要把它们从文本中去除。构建词表在构建词表时一般会把语料库中出现频率极低的词排除在外。词向量化将每个词转化为词表中的索引(也就是ID)这样更便于机器学习模型进行数据处理和分析。 然后在完成分词操作后筛选出出现次数大于3次的词元据此构建词表并将分词后的文档转换为对应的词元ID序列。 最后我们要着手把数据以及对应的标签整理成一种更有利于进行模型训练的矩阵格式。这种格式能够让数据的结构更加规整使得后续的训练过程更加高效、顺畅有助于模型更好地学习数据中的特征和模式从而提升训练的效果和质量。 在运行下列代码前我们需要安装spacy库安装命令 pip install spacy 注spacy是一款强大且高效的Python自然语言处理库广泛应用于多种文本处理任务。它能够实现精准的词法分析像将文本分割为词或符号的分词操作为每个词标注词性的词性标注以及把词还原成基本形式的词形还原。 成功安装spacy库后我们还需要下载预训练的中文小型语言模型zh_core_web_sm下载命令为 python -m spacy download zh_core_web_sm 注zh_core_web_sm是spacy库提供的一个预训练的中文语言模型。在自然语言处理(NLP)任务中我们常常需要对文本进行各种分析和处理而zh_core_web_sm模型可以帮助我们完成这些任务。例如在处理中文新闻文章时使用该模型可以进行词性标注了解每个词在句子中的词性还能进行命名实体识别找出文章里的人名、地名、组织机构名等关键信息这有助于我们对文章内容进行快速理解和分类。  完整代码 nlp_dataset_processor.py # 导入用于处理JSON数据的模块 import json # 从collections模块中导入defaultdict类用于创建默认值为0的字典 from collections import defaultdict # 导入自然语言处理库spacy import spacy # 从spacy的中文语言模块中导入中文停用词集合 from spacy.lang.zh.stop_words import STOP_WORDS # 从tqdm模块中导入tqdm函数用于显示进度条 from tqdm import tqdm # 导入用于数据可视化的库matplotlib import matplotlib# 设置matplotlib的后端为tkAgg以便在图形界面中显示图表 matplotlib.use(tkAgg) # 加载中文语言模型用于后续的自然语言处理任务 nlp_tool spacy.load(zh_core_web_sm)# 定义一个名为DatasetProcessor的类用于处理数据集相关的操作 class DatasetProcessor:# 类的初始化方法用于设置类的属性并初始化数据def __init__(self):# 初始化标签ID到标签名称的映射为空self.id_to_label None# 初始化标签名称到标签ID的映射为空self.label_to_id None# 初始化测试数据集为空self.test_dataset None# 初始化训练数据集为空self.train_dataset None# 初始化词到ID的映射为空self.word_to_id None# 设置训练数据文件和测试数据文件的路径self.train_file_path, self.test_file_path training_dataset.jsonl, test_dataset.jsonl# 调用initialize_data方法初始化数据self.initialize_data()# 定义一个方法用于读取指定路径的JSON文件并解析为Python对象列表def read_json_file(self, file_path):# 以只读模式打开指定路径的文件并指定编码为utf-8with open(file_path, r, encodingutf-8) as file_reader:# 读取文件的所有行并存储为列表json_lines list(file_reader)# 初始化一个空列表用于存储解析后的JSON数据data_list []# 遍历每一行JSON数据for json_line in json_lines:# 将JSON字符串解析为Python对象并添加到数据列表中data_list.append(json.loads(json_line))# 返回解析后的数据列表return data_list# 定义一个方法用于初始化训练数据集、测试数据集以及标签的映射关系def initialize_data(self):# 调用read_json_file方法读取训练数据文件和测试数据文件self.train_dataset, self.test_dataset self.read_json_file(self.train_file_path), self.read_json_file(self.test_file_path)# 打印训练数据集和测试数据集的大小print(训练数据集大小 , len(self.train_dataset),, 测试数据集大小 , len(self.test_dataset))# 初始化标签名称到标签ID和标签ID到标签名称的映射字典self.label_to_id, self.id_to_label {}, {}# 遍历训练数据集和测试数据集for data_subset in [self.train_dataset, self.test_dataset]:# 遍历数据集中的每个数据项for data_item in data_subset:# 获取数据项中的类别标签文本label_text data_item[class]# 如果标签文本不在标签名称到标签ID的映射字典中if label_text not in self.label_to_id:# 为该标签分配一个新的IDlabel_index len(self.label_to_id)# 将标签文本和对应的ID添加到标签名称到标签ID的映射字典中self.label_to_id[label_text] label_index# 将ID和对应的标签文本添加到标签ID到标签名称的映射字典中self.id_to_label[label_index] label_text# 获取该标签在映射字典中的IDlabel_id self.label_to_id[label_text]# 在数据项中添加标签ID字段data_item[label] label_id# 定义一个方法用于对数据集中的文本进行分词处理并去除停用词def tokenize_text(self, attributebook):# 遍历训练数据集和测试数据集for data_subset in [self.train_dataset, self.test_dataset]:# 使用tqdm显示处理进度条遍历数据集中的每个数据项for data_item in tqdm(data_subset):# 获取数据项中指定属性的文本并转换为小写text_content data_item[attribute].lower()# 使用nlp_tool对文本进行分词并过滤掉停用词获取分词列表tokens_list [token.text for token in nlp_tool(text_content) if token.text not in STOP_WORDS]# 在数据项中添加分词结果字段data_item[tokens] tokens_list# 定义一个方法用于构建词汇表并统计词汇的相关信息def build_vocabulary(self, min_frequency3, min_length2, max_sizeNone):# 初始化一个默认值为0的字典用于统计每个词的出现频率word_frequency defaultdict(int)# 遍历训练数据集中的每个数据项for data_item in self.train_dataset:# 获取数据项中的分词列表tokens data_item[tokens]# 遍历分词列表中的每个词for token in tokens:# 统计词的出现频率word_frequency[token] 1# 打印词汇表的相关统计信息包括唯一词数、总词数、最大频率和最小频率print(funique tokens {len(word_frequency)}, \ftotal counts {sum(word_frequency.values())}, \fmax freq {max(word_frequency.values())}, \fmin freq {min(word_frequency.values())})# 初始化词到ID的映射字典self.word_to_id {}# 初始化ID到词的映射字典self.id_to_word {}# 初始化总词数计数器total_token_count 0# 按词频从高到低遍历词频字典for token, freq in sorted(word_frequency.items(), keylambda x: -x[1]):# 如果设置了最大词汇表大小且当前词汇表大小已达到或超过该值则停止添加词if max_size and len(self.word_to_id) max_size:break# 如果词的频率大于最小频率要求if freq min_frequency:# 如果未设置最小词长要求或者词长满足最小词长要求if (min_length is None) or (min_length and len(token) min_length):# 将词添加到词到ID的映射字典中并记录其IDself.word_to_id[token] len(self.word_to_id)# 将ID添加到ID到词的映射字典中并记录对应的词self.id_to_word[len(self.id_to_word)] token# 累加总词数total_token_count freqelse:break# 打印词汇表构建的相关参数和统计信息包括最小频率、最小词长、最大大小、剩余词数和词汇表覆盖率print(fmin_freq {min_frequency}, min_len {min_length}, \fmax_size {max_size}, fremaining tokens {len(self.word_to_id)}, fin-vocab rate {total_token_count / sum(word_frequency.values())})# 定义一个方法用于将数据集中的分词结果转换为对应的词ID列表def convert_tokens_to_indices(self):# 遍历训练数据集和测试数据集for data_subset in [self.train_dataset, self.test_dataset]:# 遍历数据集中的每个数据项for data_item in data_subset:# 初始化一个空列表用于存储词IDdata_item[token_indices] []# 遍历数据项中的每个分词for token in data_item[tokens]:# 如果分词在词到ID的映射字典中if token in self.word_to_id:# 将分词对应的ID添加到词ID列表中data_item[token_indices].append(self.word_to_id[token])nlp_naive_bayes_classifier.py # 导入用于数值计算的numpy库 import numpy as np# 定义一个朴素贝叶斯分类器类 class NaiveBayesClassifier:# 类的初始化方法接收类别数量和词汇表大小作为参数def __init__(self, num_classes, vocabulary_size):# 存储类别数量self.num_classes num_classes# 存储词汇表大小self.vocabulary_size vocabulary_size# 初始化先验概率数组长度为类别数量元素类型为64位浮点数self.prior_probabilities np.zeros(num_classes, dtypenp.float64)# 初始化似然概率矩阵形状为(类别数量, 词汇表大小)元素类型为64位浮点数self.likelihood_probabilities np.zeros((num_classes, vocabulary_size), dtypenp.float64)# 定义训练模型的方法接收输入特征和对应的标签作为参数def train_model(self, input_features, labels):# 遍历输入特征和对应的标签for feature, label in zip(input_features, labels):# 统计每个类别的样本数量更新先验概率self.prior_probabilities[label] 1# 遍历输入特征中的每个词的索引for token_index in feature:# 统计每个类别下每个词的出现次数更新似然概率self.likelihood_probabilities[label, token_index] 1# 计算先验概率将每个类别的样本数量除以总样本数量self.prior_probabilities / self.prior_probabilities.sum()# 对似然概率矩阵进行拉普拉斯平滑避免概率为0的情况self.likelihood_probabilities 1# 计算似然概率将每个类别下每个词的出现次数除以该词在所有类别中的总出现次数self.likelihood_probabilities / self.likelihood_probabilities.sum(axis0)# 对先验概率取对数避免下溢问题self.prior_probabilities np.log(self.prior_probabilities)# 对似然概率取对数避免下溢问题self.likelihood_probabilities np.log(self.likelihood_probabilities)# 定义进行预测的方法接收输入特征作为参数def make_predictions(self, input_features):# 初始化一个空列表用于存储预测结果predictions []# 遍历每个输入特征for feature in input_features:# 初始化一个概率数组用于存储每个类别的预测概率probabilities np.zeros(self.num_classes, dtypenp.float64)# 遍历每个类别for i in range(self.num_classes):# 累加该类别的先验概率probabilities[i] self.prior_probabilities[i]# 遍历输入特征中的每个词的索引for token in feature:# 累加该类别下该词的似然概率probabilities[i] self.likelihood_probabilities[i, token]# 将概率最大的类别索引作为预测结果添加到预测结果列表中predictions.append(np.argmax(probabilities))# 返回预测结果列表return predictionsnlp_text_classification.py # 导入用于数值计算的numpy库 import numpy as np # 从自定义模块中导入数据集处理类 from nlp_dataset_processor import DatasetProcessor # 从自定义模块中导入朴素贝叶斯分类器类 from nlp_naive_bayes_classifier import NaiveBayesClassifier# 定义一个自然语言处理文本分类的类 class NLPTextClassification:# 类的初始化方法目前为空不做任何操作def __init__(self):pass# 定义文本分类方法def text_classification(self):# 创建数据集处理对象用于加载和预处理数据集dataset DatasetProcessor()# 对数据集中的文本进行分词处理dataset.tokenize_text()# 打印训练数据集中第一个样本的分词结果print(dataset.train_dataset[0][tokens])# 打印标签到ID的映射关系print(dataset.label_to_id)# 构建词汇表设置最小词频为3dataset.build_vocabulary(min_frequency3)# 将分词结果转换为对应的词ID列表dataset.convert_tokens_to_indices()# 打印训练数据集中第一个样本的词ID列表print(dataset.train_dataset[0][token_indices])# 初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到训练输入特征列表中training_input_features.append(feature_vector)# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 遍历测试数据集for data in dataset.test_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到测试输入特征列表中testing_input_features.append(feature_vector)# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 将训练输入特征和训练标签转换为numpy数组training_input_features, training_labels np.array(training_input_features), np.array(training_labels)# 将测试输入特征和测试标签转换为numpy数组testing_input_features, testing_labels np.array(testing_input_features), np.array(testing_labels)# 创建朴素贝叶斯分类器对象传入类别数量和词汇表大小naive_bayes_model NaiveBayesClassifier(len(dataset.label_to_id), len(dataset.word_to_id))# 重新初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 将样本的词ID列表添加到训练输入特征列表中training_input_features.append(data[token_indices])# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 使用训练数据对朴素贝叶斯模型进行训练naive_bayes_model.train_model(training_input_features, training_labels)# 打印前3个类别的先验概率for i in range(3):print(fP({dataset.id_to_label[i]}) {np.exp(naive_bayes_model.prior_probabilities[i])})# 打印前3个词在第一个类别下的似然概率for i in range(3):print(fP({dataset.id_to_word[i]}|{dataset.id_to_label[0]}) \f{np.exp(naive_bayes_model.likelihood_probabilities[0, i])})# 重新初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历测试数据集for data in dataset.test_dataset:# 将样本的词ID列表添加到测试输入特征列表中testing_input_features.append(data[token_indices])# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 使用训练好的朴素贝叶斯模型对测试数据进行预测naive_bayes_predictions naive_bayes_model.make_predictions(testing_input_features)# 打印前5个测试样本的预测结果和真实标签for i, (prediction, label) in enumerate(zip(naive_bayes_predictions, testing_labels)):if i 5:breakprint(ftest example:{i}, prediction {prediction}, label {label})# 程序入口当脚本作为主程序运行时执行 if __name__ __main__:# 创建自然语言处理文本分类对象nlp_text_classification NLPTextClassification()# 调用文本分类方法进行文本分类操作nlp_text_classification.text_classification()运行结果 训练数据集大小 8627 , 测试数据集大小 2157 100%|██████████| 8627/8627 [00:2000:00, 413.90it/s] 100%|██████████| 2157/2157 [00:0500:00, 413.93it/s] [地质学, 前沿, 研究, 进展] {科学类: 0, 计算机类: 1, 艺术传媒类: 2, 经管类: 3, 文学类: 4, 历史类: 5} unique tokens 97, total counts 36235, max freq 868, min freq 262 min_freq 3, min_len 2, max_size None, remaining tokens 93, in-vocab rate 0.9606181868359321 [80, 36, 37, 38] P(科学类) 0.1662223252579112 P(计算机类) 0.16680190100846182 P(艺术传媒类) 0.17016344036165526 P(小说|科学类) 0.0011441647597254007 P(指南|科学类) 0.0012987012987012991 P(揭秘|科学类) 0.001362397820163487 测试样本:0, 预测结果 2, 真实类别 2 测试样本:1, 预测结果 2, 真实类别 2 测试样本:2, 预测结果 1, 真实类别 1 测试样本:3, 预测结果 5, 真实类别 5 测试样本:4, 预测结果 2, 真实类别 2进程已结束退出代码为 0 这段代码的目的是对书籍相关的文本数据进行预处理构建朴素贝叶斯分类模型并使用该模型对数据进行分类预测。通过数据处理和模型训练实现对文本数据的自动分类。  逻辑斯谛回归 概念阐述 逻辑斯谛回归(Logistic Regression)是一种广义的线性回归分析模型常用于处理二分类问题(也可扩展到多分类问题)虽然名字里有“回归”但它的本质是用于分类预测。它通过一个逻辑斯谛函数(也称为Sigmoid函数)将线性回归模型的输出值映射到一个概率值该概率值表示样本属于某一类别的可能性大小。 例如在判断一封邮件是否为垃圾邮件的场景中逻辑斯谛回归可以根据邮件的各种特征(如发件人、主题、内容关键词等)计算出该邮件是垃圾邮件的概率然后根据设定的阈值(通常为0.5)来决定邮件的类别。 公式展示 线性回归部分辑斯谛回归首先基于线性回归模型对于有个特征的样本其线性组合为可以写成向量形式其中是模型的参数向量(在向量中添加了一个常数项与对应)。 逻辑斯谛函数(Sigmoid函数)将线性回归的结果作为输入通过Sigmoid函数将映射到区间上得到样本属于正类(通常标记为1)的概率。那么样本属于负类(通常标记为0)的概率为。 原理解释 概率估计逻辑斯谛回归的核心原理是通过最大化样本的似然函数来估计模型的参数。对于一个二分类问题假设样本属于正类的概率为属于负类的概率为。给定一组独立同分布的样本其中是样本的真实标签其似然函数为对数似然函数为了便于计算和求导通常对似然函数取对数得到对数似然函数参数估计目标是找到一组参数使得对数似然函数最大化。常用的方法是梯度上升法(与最小化损失函数的梯度下降法相对应)通过不断更新参数沿着梯度的方向逐步增加对数似然函数的值直到达到收敛。在实际应用中也可以通过一些优化算法如随机梯度下降、批量梯度下降等来求解参数从而得到最优的逻辑斯谛回归模型用于对新的样本进行分类预测。  代码演示 我们使用代码来演示基于博主在自然语言处理文本表示-CSDN博客介绍的TF-IDF方法构建文档的特征向量表示并借助PyTorch深度学习框架实现逻辑斯谛回归模型的训练与预测。 逻辑斯谛回归本质上可被视为一种仅有一层的神经网络模型架构借助PyTorch强大的框架来实现该模型时能够轻松且高效地运用其自动求导功能极大地简化了模型训练过程中的梯度计算。 下面给出的代码会利用已经经过训练、能够有效处理相关任务的模型针对测试集中的数据进行预测。之后会把预测得到的分类结果报告出来方便我们了解模型在测试数据上的表现。 完整代码 nlp_tfidf_transformer.py # 导入用于数值计算的numpy库 import numpy as np# 定义一个TF-IDF转换器类用于将文本特征转换为TF-IDF特征 class TFIDFTransformer:# 类的初始化方法接收词汇表大小、归一化方式、是否平滑处理IDF和是否使用子线性TF作为参数def __init__(self, vocabulary_size, norml2, smooth_idfTrue, sublinear_tfTrue):# 初始化逆文档频率IDF为Noneself.idf None# 存储词汇表大小self.vocabulary_size vocabulary_size# 存储归一化方式默认为l2self.norm norm# 存储是否对IDF进行平滑处理的标志默认为Trueself.smooth_idf smooth_idf# 存储是否使用子线性TF的标志默认为Trueself.sublinear_tf sublinear_tf# 定义拟合转换器的方法用于计算逆文档频率(IDF)def fit_transformer(self, input_features):# 初始化文档频率数组长度为词汇表大小元素类型为64位浮点数document_frequency np.zeros(self.vocabulary_size, dtypenp.float64)# 遍历每个输入特征for data in input_features:# 遍历输入特征中唯一的词索引for token_index in set(data):# 统计每个词的文档频率document_frequency[token_index] 1# 对文档频率进行平滑处理若smooth_idf为True则加1否则加0document_frequency int(self.smooth_idf)# 计算样本数量加上平滑处理的样本数num_samples len(input_features) int(self.smooth_idf)# 计算逆文档频率IDFself.idf np.log(num_samples / document_frequency) 1# 定义转换特征的方法将输入特征转换为TF - IDF特征def transform_features(self, input_features):# 确保已经计算了逆文档频率IDFassert hasattr(self, idf)# 初始化词频矩阵形状为(输入特征数量词汇表大小)元素类型为64位浮点数term_frequency np.zeros((len(input_features), self.vocabulary_size), dtypenp.float64)# 遍历每个输入特征及其索引for i, data in enumerate(input_features):# 遍历输入特征中的每个词索引for token in data:# 统计词频term_frequency[i, token] 1# 如果使用子线性TFif self.sublinear_tf:# 对词频进行对数变换term_frequency np.log(term_frequency 1)# 计算TF-IDF特征矩阵transformed_features term_frequency * self.idf# 如果设置了归一化方式if self.norm:# 计算每行的范数row_norm (transformed_features ** 2).sum(axis1)# 将范数为0的行设置为1避免除零错误row_norm[row_norm 0] 1# 对TF-IDF特征矩阵进行归一化transformed_features / np.sqrt(row_norm)[:, None]# 返回转换后的TF-IDF特征矩阵return transformed_features# 定义拟合并转换特征的方法先计算IDF再转换输入特征def fit_and_transform(self, input_features):# 调用fit_transformer方法计算逆文档频率(IDF)self.fit_transformer(input_features)# 调用transform_features方法将输入特征转换为TF-IDF特征return self.transform_features(input_features)nlp_logistic_regression_model.py # 从torch模块导入nn子模块用于构建神经网络 from torch import nn# 定义一个逻辑回归模型类继承自nn.Module class LogisticRegressionModel(nn.Module):# 类的初始化方法接收输入维度和输出维度作为参数def __init__(self, input_dimension, output_dimension):# 调用父类的初始化方法super(LogisticRegressionModel, self).__init__()# 定义一个线性层输入维度为input_dimension输出维度为output_dimensionself.linear_layer nn.Linear(input_dimension, output_dimension)# 定义模型的前向传播方法接收输入特征和可选的标签作为参数def forward(self, input_features, labelsNone):# 通过线性层计算输出outputs self.linear_layer(input_features)# 如果传入了标签if labels is not None:# 定义交叉熵损失函数loss_function nn.CrossEntropyLoss()# 计算损失loss loss_function(outputs, labels)# 返回损失和输出return loss, outputs# 如果没有传入标签直接返回输出return outputsnlp_custom_dataset.py # 从torch.utils.data模块导入Dataset类用于自定义数据集 from torch.utils.data import Dataset# 定义一个自定义数据集类继承自torch的Dataset类 class CustomDataset(Dataset):# 类的初始化方法接收输入特征和标签作为参数def __init__(self, input_features, labels):# 存储输入特征self.input_features input_features# 存储标签self.labels labels# 定义返回数据集长度的方法用于获取数据集样本数量def __len__(self):# 返回输入特征的数量即数据集的样本数return len(self.input_features)# 定义根据索引获取数据集中单个样本的方法def __getitem__(self, index):# 根据索引返回对应的输入特征和标签return self.input_features[index], self.labels[index]nlp_data_collation.py # 导入用于数值计算的numpy库 import numpy as np # 导入深度学习框架PyTorch import torch# 定义一个数据整理类用于对批量数据进行整理 class DataCollation:# 定义一个类方法用于将批量数据整理成适合模型输入的格式classmethoddef collate_batch_data(cls, batch):# 初始化空列表用于分别存储特征和标签features, labels [], []# 遍历批量数据中的每个样本for feature, label in batch:# 将样本的特征添加到特征列表中features.append(feature)# 将样本的标签添加到标签列表中labels.append(label)# 将特征列表转换为numpy数组再转换为torch的浮点型张量features torch.tensor(np.array(features), dtypetorch.float)# 将标签列表转换为numpy数组再转换为torch的长整型张量labels torch.tensor(np.array(labels), dtypetorch.long)# 返回一个字典包含整理好的输入特征和标签return {input_features: features, labels: labels} nlp_text_classification.py # 导入用于数值计算的numpy库 import numpy as np # 导入深度学习框架PyTorch import torch # 从torch.utils.data模块导入DataLoader类用于批量加载数据 from torch.utils.data import DataLoader # 从torch.optim模块导入Adam优化器用于优化模型参数 from torch.optim import Adam # 从tqdm模块导入trange函数用于显示进度条 from tqdm import trange # 导入用于数据可视化的matplotlib库 import matplotlib# 从自定义模块中导入自定义数据集类 from nlp_custom_dataset import CustomDataset # 从自定义模块中导入数据整理类 from nlp_data_collation import DataCollation # 从自定义模块中导入数据集处理类 from nlp_dataset_processor import DatasetProcessor # 从自定义模块中导入逻辑回归模型类 from nlp_logistic_regression_model import LogisticRegressionModel # 从自定义模块中导入朴素贝叶斯分类器类 from nlp_naive_bayes_classifier import NaiveBayesClassifier # 从自定义模块中导入TF - IDF转换器类 from nlp_tfidf_transformer import TFIDFTransformer# 设置matplotlib的后端为tkAgg以便在图形界面中显示图表 matplotlib.use(tkAgg) # 定义一个字典config用于设置matplotlib的字体和符号显示配置 config {font.family: serif, # 设置字体族为衬线字体mathtext.fontset: stix, # 设置数学文本的字体集为stixfont.serif: SimSun, # 设置衬线字体为宋体axes.unicode_minus: False # 解决负号显示问题 } # 使用config字典更新matplotlib的全局参数配置 matplotlib.rcParams.update(config) # 从matplotlib库中导入pyplot模块用于绘制图表 import matplotlib.pyplot as plt# 定义一个自然语言处理文本分类的类 class NLPTextClassification:# 类的初始化方法目前为空不做任何操作def __init__(self):pass# 定义文本分类方法def text_classification(self):# 创建数据集处理对象用于加载和预处理数据集dataset DatasetProcessor()# 对数据集中的文本进行分词处理dataset.tokenize_text()# 打印训练数据集中第一个样本的分词结果print(dataset.train_dataset[0][tokens])# 打印标签到ID的映射关系print(dataset.label_to_id)# 构建词汇表设置最小词频为3dataset.build_vocabulary(min_frequency3)# 将分词结果转换为对应的词ID列表dataset.convert_tokens_to_indices()# 打印训练数据集中第一个样本的词ID列表print(dataset.train_dataset[0][token_indices])# 初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到训练输入特征列表中training_input_features.append(feature_vector)# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 遍历测试数据集for data in dataset.test_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到测试输入特征列表中testing_input_features.append(feature_vector)# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 将训练输入特征和训练标签转换为numpy数组training_input_features, training_labels np.array(training_input_features), np.array(training_labels)# 将测试输入特征和测试标签转换为numpy数组testing_input_features, testing_labels np.array(testing_input_features), np.array(testing_labels)# 创建朴素贝叶斯分类器对象传入类别数量和词汇表大小naive_bayes_model NaiveBayesClassifier(len(dataset.label_to_id), len(dataset.word_to_id))# 重新初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 将样本的词ID列表添加到训练输入特征列表中training_input_features.append(data[token_indices])# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 使用训练数据对朴素贝叶斯模型进行训练naive_bayes_model.train_model(training_input_features, training_labels)# 打印前3个类别的先验概率for i in range(3):print(fP({dataset.id_to_label[i]}) {np.exp(naive_bayes_model.prior_probabilities[i])})# 打印前3个词在第一个类别下的似然概率for i in range(3):print(fP({dataset.id_to_word[i]}|{dataset.id_to_label[0]}) \f{np.exp(naive_bayes_model.likelihood_probabilities[0, i])})# 重新初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历测试数据集for data in dataset.test_dataset:# 将样本的词ID列表添加到测试输入特征列表中testing_input_features.append(data[token_indices])# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 使用训练好的朴素贝叶斯模型对测试数据进行预测naive_bayes_predictions naive_bayes_model.make_predictions(testing_input_features)# 打印前5个测试样本的预测结果和真实标签for i, (prediction, label) in enumerate(zip(naive_bayes_predictions, testing_labels)):if i 5:breakprint(f测试样本:{i}, 预测结果 {prediction}, 真实类别 {label})# 创建TF - IDF转换器对象传入词汇表大小tfidf_transformer TFIDFTransformer(len(dataset.word_to_id))# 使用训练数据拟合TF - IDF转换器tfidf_transformer.fit_transformer(training_input_features)# 将训练数据转换为TF - IDF特征training_features tfidf_transformer.transform_features(training_input_features)# 将测试数据转换为TF - IDF特征testing_features tfidf_transformer.transform_features(testing_input_features)# 创建逻辑回归模型对象传入输入维度和输出维度logistic_regression_model LogisticRegressionModel(len(dataset.word_to_id), len(dataset.label_to_id))# 设置训练的轮数num_epochs 50# 设置批量大小batch_size 128# 设置学习率learning_rate 1e-3# 设置权重衰减系数weight_decay 0# 创建自定义训练数据集对象training_dataset CustomDataset(training_features, training_labels)# 创建自定义测试数据集对象testing_dataset CustomDataset(testing_features, testing_labels)# 创建数据整理对象data_collator DataCollation()# 创建训练数据加载器设置批量大小、是否打乱数据和数据整理函数training_dataloader DataLoader(training_dataset, batch_sizebatch_size, shuffleTrue,collate_fndata_collator.collate_batch_data)# 创建测试数据加载器设置批量大小、不打乱数据和数据整理函数testing_dataloader DataLoader(testing_dataset, batch_sizebatch_size, shuffleFalse,collate_fndata_collator.collate_batch_data)# 创建Adam优化器传入逻辑回归模型的参数、学习率和权重衰减系数optimizer Adam(logistic_regression_model.parameters(), lrlearning_rate, weight_decayweight_decay)# 清空逻辑回归模型的梯度logistic_regression_model.zero_grad()# 将逻辑回归模型设置为训练模式logistic_regression_model.train()# 使用trange显示训练轮数的进度条with trange(num_epochs, descepoch, ncols60) as progress_bar:# 初始化每一轮的损失列表epoch_losses []# 遍历每一轮训练for epoch in progress_bar:# 将逻辑回归模型设置为训练模式logistic_regression_model.train()# 遍历训练数据加载器中的每个批次for step, batch in enumerate(training_dataloader):# 计算当前批次的损失loss logistic_regression_model(**batch)[0]# 更新进度条的描述信息显示当前轮数和损失值progress_bar.set_description(fepoch-{epoch}, loss{loss.item():.4f})# 反向传播计算梯度loss.backward()# 更新模型参数optimizer.step()# 清空逻辑回归模型的梯度logistic_regression_model.zero_grad()# 将当前批次的损失添加到损失列表中epoch_losses.append(loss.item())# 将每一轮的损失列表转换为numpy数组epoch_losses np.array(epoch_losses)# 绘制损失曲线plt.plot(range(len(epoch_losses)), epoch_losses)# 设置x轴标签为训练轮数plt.xlabel(训练轮次)# 设置y轴标签为损失值plt.ylabel(损失(值))# 显示损失曲线plt.show()# 将逻辑回归模型设置为评估模式logistic_regression_model.eval()# 不计算梯度提高推理速度with torch.no_grad():# 初始化评估损失列表loss_values []# 遍历测试数据加载器中的每个批次for batch in testing_dataloader:# 计算当前批次的损失loss logistic_regression_model(**batch)[0]# 将当前批次的损失添加到评估损失列表中loss_values.append(loss.item())# 打印平均评估损失print(f评估损失 {np.mean(loss_values):.4f})# 初始化逻辑回归模型的预测结果列表logistic_regression_predictions []# 将逻辑回归模型设置为评估模式logistic_regression_model.eval()# 遍历测试数据加载器中的每个批次for batch in testing_dataloader:# 不计算梯度提高推理速度with torch.no_grad():# 计算模型的输出和损失取预测结果_, predictions logistic_regression_model(**batch)# 获取预测结果中概率最大的类别索引predictions np.argmax(predictions, axis1)# 将当前批次的预测结果添加到预测结果列表中logistic_regression_predictions.extend(predictions)# 打印前5个测试样本的逻辑回归模型预测结果和真实标签for i, (prediction, label) in enumerate(zip(logistic_regression_predictions, testing_labels)):if i 5:breakprint(f测试样本:{i}, 预测结果 {prediction}, 真实类别 {label})# 程序入口当脚本作为主程序运行时执行 if __name__ __main__:# 创建自然语言处理文本分类对象nlp_text_classification NLPTextClassification()# 调用文本分类方法进行文本分类操作nlp_text_classification.text_classification()运行结果 训练数据集大小 8627 , 测试数据集大小 2157 100%|██████████| 8627/8627 [00:2000:00, 413.90it/s] 100%|██████████| 2157/2157 [00:0500:00, 413.93it/s] [地质学, 前沿, 研究, 进展] {科学类: 0, 计算机类: 1, 艺术传媒类: 2, 经管类: 3, 文学类: 4, 历史类: 5} unique tokens 97, total counts 36235, max freq 868, min freq 262 min_freq 3, min_len 2, max_size None, remaining tokens 93, in-vocab rate 0.9606181868359321 [80, 36, 37, 38] P(科学类) 0.1662223252579112 P(计算机类) 0.16680190100846182 P(艺术传媒类) 0.17016344036165526 P(小说|科学类) 0.0011441647597254007 P(指南|科学类) 0.0012987012987012991 P(揭秘|科学类) 0.001362397820163487 测试样本:0, 预测结果 2, 真实类别 2 测试样本:1, 预测结果 2, 真实类别 2 测试样本:2, 预测结果 1, 真实类别 1 测试样本:3, 预测结果 5, 真实类别 5 测试样本:4, 预测结果 2, 真实类别 2 epoch-49, loss0.0274: 100%|█| 50/50 [00:0200:00, 20.06it/s 评估损失 0.0303 测试样本:0, 预测结果 2, 真实类别 2 测试样本:1, 预测结果 2, 真实类别 2 测试样本:2, 预测结果 1, 真实类别 1 测试样本:3, 预测结果 5, 真实类别 5 测试样本:4, 预测结果 2, 真实类别 2进程已结束退出代码为 0 注意博主采用的训练集和测试集是用代码自动生成出来的内容保存到文件中去目的是为了方便讲解功能和展示效果代码也是方便给大家参考。请大家根据需求加载自己的训练集和测试集。 分类结果评价 概念阐述 在自然语言处理(NLP)中分类结果评价是指使用一系列指标和方法对文本分类模型的性能和预测效果进行评估和分析从而衡量模型在将文本正确归类到不同类别方面的能力。其主要目的包括评估模型的优劣、比较不同模型的性能、发现模型存在的问题以及为模型的改进提供依据。 评价指标 准确率 Accuracy指分类模型正确预测的样本数占总样本数的比例计算公式为 其中 (真正例)是指实际为正例且被正确预测为正例的样本数(真反例)是实际为反例且被正确预测为反例的样本数(假正例)是实际为反例但被错误预测为正例的样本数(假反例)是实际为正例但被错误预测为反例的样本数。例如在一个情感分类任务中总共有100条文本模型正确分类了80条那么准确率就是80%。 精确率 Precision也叫查准率是指在被模型预测为正例的样本中真正为正例的比例计算公式为 例如模型预测了30条文本为积极情感其中实际有25条是积极情感那么精确率为。 召回率 Recall又称查全率是指在实际为正例的样本中被模型正确预测为正例的比例计算公式为 例如实际有40条积极情感的文本模型正确预测出了30条召回率就是。 F1值 F1-score是精确率和召回率的调和平均数综合考虑了精确率和召回率计算公式为 F1值越高说明模型在精确率和召回率方面的综合表现越好。 宏平均 Macro-average对于多分类问题先分别计算每个类别的精确率、召回率和F1值然后对这些值取算术平均值得到宏平均精确率、宏平均召回率和宏平均F1值。它给予每个类别相同的权重能够反映模型在各个类别上的平均性能。 微平均 Micro-average在多分类问题中先计算所有类别的真正例、假正例和假反例的总数然后基于这些总数计算精确率、召回率和F1值。它更关注整体的分类性能尤其是在样本不均衡的情况下能够突出模型对主要类别的分类能力。 其他 除了这些指标外还有一些其他的评价方法和指标如混淆矩阵(Confusion Matrix)可以直观地展示模型在各个类别上的分类情况ROC曲线(Receiver Operating Characteristic Curve)和AUC(Area Under the Curve)用于评估模型在不同阈值下的性能等。通过综合运用这些评价指标和方法可以全面、客观地评价自然语言处理中的分类结果。   代码演示 接下来的代码将运用已经完成训练流程、具备预测能力的模型针对测试集展开预测工作并且会对预测所得到的分类结果进行报告。 完整代码 nlp_evaluation_metrics.py # 导入用于数值计算的numpy库 import numpy as np# 定义一个评估指标类用于计算评估模型性能的指标 class EvaluationMetrics:# 类的初始化方法目前为空实现def __init__(self):pass# 定义计算微平均F1值的方法接收数据集、预测结果和真实标签作为参数def calculate_micro_f1(self, dataset, predictions, true_labels):# 计算预测结果与真实标签相等的数量即真正例的数量true_positives np.sum(predictions true_labels)# 初始化假负例和假正例的数量为0false_negatives false_positives 0# 遍历数据集中的每个类别for i in range(len(dataset.label_to_id)):# 累加假负例的数量即预测为该类但真实不是该类的数量false_negatives np.sum((predictions i) (true_labels ! i))# 累加假正例的数量即预测不是该类但真实是该类的数量false_positives np.sum((predictions ! i) (true_labels i))# 计算精确率即真正例在真正例和假正例总和中的比例precision true_positives / (true_positives false_positives)# 计算召回率即真正例在真正例和假负例总和中的比例recall true_positives / (true_positives false_negatives)# 计算微平均F1值是精确率和召回率的调和平均值f1_score 2 * precision * recall / (precision recall)# 返回计算得到的微平均F1值return f1_score# 定义计算宏平均F1值的方法接收数据集、预测结果和真实标签作为参数def calculate_macro_f1(self, dataset, predictions, true_labels):# 初始化一个空列表用于存储每个类别的F1值f_scores []# 遍历数据集中的每个类别for i in range(len(dataset.label_to_id)):# 计算当前类别的真正例数量true_positives np.sum((predictions i) (true_labels i))# 计算当前类别的假负例数量false_negatives np.sum((predictions i) (true_labels ! i))# 计算当前类别的假正例数量false_positives np.sum((predictions ! i) (true_labels i))# 计算当前类别的精确率precision true_positives / (true_positives false_positives)# 计算当前类别的召回率recall true_positives / (true_positives false_negatives)# 计算当前类别的F1值f1_score 2 * precision * recall / (precision recall)# 将当前类别的F1值添加到列表中f_scores.append(f1_score)# 计算所有类别F1值的平均值即宏平均F1值return np.mean(f_scores)nlp_text_classification.py # 导入用于数值计算的numpy库 import numpy as np # 导入深度学习框架PyTorch import torch # 从torch.utils.data模块导入DataLoader类用于批量加载数据 from torch.utils.data import DataLoader # 从torch.optim模块导入Adam优化器用于优化模型参数 from torch.optim import Adam # 从tqdm模块导入trange函数用于显示进度条 from tqdm import trange # 导入用于数据可视化的matplotlib库 import matplotlib# 从自定义模块中导入自定义数据集类 from nlp_custom_dataset import CustomDataset # 从自定义模块中导入数据整理类 from nlp_data_collation import DataCollation # 从自定义模块中导入数据集处理类 from nlp_dataset_processor import DatasetProcessor # 从自定义模块中导入评估指标类 from nlp_evaluation_metrics import EvaluationMetrics # 从自定义模块中导入逻辑回归模型类 from nlp_logistic_regression_model import LogisticRegressionModel # 从自定义模块中导入朴素贝叶斯分类器类 from nlp_naive_bayes_classifier import NaiveBayesClassifier # 从自定义模块中导入TF - IDF转换器类 from nlp_tfidf_transformer import TFIDFTransformer# 设置matplotlib的后端为tkAgg以便在图形界面中显示图表 matplotlib.use(tkAgg) # 定义一个字典config用于设置matplotlib的字体和符号显示配置 config {font.family: serif, # 设置字体族为衬线字体mathtext.fontset: stix, # 设置数学文本的字体集为stixfont.serif: SimSun, # 设置衬线字体为宋体axes.unicode_minus: False # 解决负号显示问题 } # 使用config字典更新matplotlib的全局参数配置 matplotlib.rcParams.update(config) # 从matplotlib库中导入pyplot模块用于绘制图表 import matplotlib.pyplot as plt# 定义一个自然语言处理文本分类的类 class NLPTextClassification:# 类的初始化方法目前为空不做任何操作def __init__(self):pass# 定义文本分类方法def text_classification(self):# 创建数据集处理对象用于加载和预处理数据集dataset DatasetProcessor()# 对数据集中的文本进行分词处理dataset.tokenize_text()# 打印训练数据集中第一个样本的分词结果print(dataset.train_dataset[0][tokens])# 打印标签到ID的映射关系print(dataset.label_to_id)# 构建词汇表设置最小词频为3dataset.build_vocabulary(min_frequency3)# 将分词结果转换为对应的词ID列表dataset.convert_tokens_to_indices()# 打印训练数据集中第一个样本的词ID列表print(dataset.train_dataset[0][token_indices])# 初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到训练输入特征列表中training_input_features.append(feature_vector)# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 遍历测试数据集for data in dataset.test_dataset:# 初始化特征向量长度为词汇表大小元素类型为32位整数feature_vector np.zeros(len(dataset.word_to_id), dtypenp.int32)# 遍历样本的词ID列表for token_index in data[token_indices]:# 统计每个词的出现次数feature_vector[token_index] 1# 将特征向量添加到测试输入特征列表中testing_input_features.append(feature_vector)# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 将训练输入特征和训练标签转换为numpy数组training_input_features, training_labels np.array(training_input_features), np.array(training_labels)# 将测试输入特征和测试标签转换为numpy数组testing_input_features, testing_labels np.array(testing_input_features), np.array(testing_labels)# 创建朴素贝叶斯分类器对象传入类别数量和词汇表大小naive_bayes_model NaiveBayesClassifier(len(dataset.label_to_id), len(dataset.word_to_id))# 重新初始化训练输入特征和训练标签列表training_input_features, training_labels [], []# 遍历训练数据集for data in dataset.train_dataset:# 将样本的词ID列表添加到训练输入特征列表中training_input_features.append(data[token_indices])# 将样本的标签添加到训练标签列表中training_labels.append(data[label])# 使用训练数据对朴素贝叶斯模型进行训练naive_bayes_model.train_model(training_input_features, training_labels)# 打印前3个类别的先验概率for i in range(3):print(fP({dataset.id_to_label[i]}) {np.exp(naive_bayes_model.prior_probabilities[i])})# 打印前3个词在第一个类别下的似然概率for i in range(3):print(fP({dataset.id_to_word[i]}|{dataset.id_to_label[0]}) \f{np.exp(naive_bayes_model.likelihood_probabilities[0, i])})# 重新初始化测试输入特征和测试标签列表testing_input_features, testing_labels [], []# 遍历测试数据集for data in dataset.test_dataset:# 将样本的词ID列表添加到测试输入特征列表中testing_input_features.append(data[token_indices])# 将样本的标签添加到测试标签列表中testing_labels.append(data[label])# 使用训练好的朴素贝叶斯模型对测试数据进行预测naive_bayes_predictions naive_bayes_model.make_predictions(testing_input_features)# 打印前5个测试样本的预测结果和真实标签for i, (prediction, label) in enumerate(zip(naive_bayes_predictions, testing_labels)):if i 5:breakprint(f测试样本:{i}, 预测结果 {prediction}, 真实类别 {label})# 创建TF - IDF转换器对象传入词汇表大小tfidf_transformer TFIDFTransformer(len(dataset.word_to_id))# 使用训练数据拟合TF - IDF转换器tfidf_transformer.fit_transformer(training_input_features)# 将训练数据转换为TF - IDF特征training_features tfidf_transformer.transform_features(training_input_features)# 将测试数据转换为TF - IDF特征testing_features tfidf_transformer.transform_features(testing_input_features)# 创建逻辑回归模型对象传入输入维度和输出维度logistic_regression_model LogisticRegressionModel(len(dataset.word_to_id), len(dataset.label_to_id))# 设置训练的轮数num_epochs 50# 设置批量大小batch_size 128# 设置学习率learning_rate 1e-3# 设置权重衰减系数weight_decay 0# 创建自定义训练数据集对象training_dataset CustomDataset(training_features, training_labels)# 创建自定义测试数据集对象testing_dataset CustomDataset(testing_features, testing_labels)# 创建数据整理对象data_collator DataCollation()# 创建训练数据加载器设置批量大小、是否打乱数据和数据整理函数training_dataloader DataLoader(training_dataset, batch_sizebatch_size, shuffleTrue,collate_fndata_collator.collate_batch_data)# 创建测试数据加载器设置批量大小、不打乱数据和数据整理函数testing_dataloader DataLoader(testing_dataset, batch_sizebatch_size, shuffleFalse,collate_fndata_collator.collate_batch_data)# 创建Adam优化器传入逻辑回归模型的参数、学习率和权重衰减系数optimizer Adam(logistic_regression_model.parameters(), lrlearning_rate, weight_decayweight_decay)# 清空逻辑回归模型的梯度logistic_regression_model.zero_grad()# 将逻辑回归模型设置为训练模式logistic_regression_model.train()# 使用trange显示训练轮数的进度条with trange(num_epochs, descepoch, ncols60) as progress_bar:# 初始化每一轮的损失列表epoch_losses []# 遍历每一轮训练for epoch in progress_bar:# 将逻辑回归模型设置为训练模式logistic_regression_model.train()# 遍历训练数据加载器中的每个批次for step, batch in enumerate(training_dataloader):# 计算当前批次的损失loss logistic_regression_model(**batch)[0]# 更新进度条的描述信息显示当前轮数和损失值progress_bar.set_description(fepoch-{epoch}, loss{loss.item():.4f})# 反向传播计算梯度loss.backward()# 更新模型参数optimizer.step()# 清空逻辑回归模型的梯度logistic_regression_model.zero_grad()# 将当前批次的损失添加到损失列表中epoch_losses.append(loss.item())# 将每一轮的损失列表转换为numpy数组epoch_losses np.array(epoch_losses)# 绘制损失曲线plt.plot(range(len(epoch_losses)), epoch_losses)# 设置x轴标签为训练轮数plt.xlabel(训练轮次)# 设置y轴标签为损失值plt.ylabel(损失(值))# 显示损失曲线plt.show()# 将逻辑回归模型设置为评估模式logistic_regression_model.eval()# 不计算梯度提高推理速度with torch.no_grad():# 初始化评估损失列表loss_values []# 遍历测试数据加载器中的每个批次for batch in testing_dataloader:# 计算当前批次的损失loss logistic_regression_model(**batch)[0]# 将当前批次的损失添加到评估损失列表中loss_values.append(loss.item())# 打印平均评估损失print(f评估损失 {np.mean(loss_values):.4f})# 初始化逻辑回归模型的预测结果列表logistic_regression_predictions []# 将逻辑回归模型设置为评估模式logistic_regression_model.eval()# 遍历测试数据加载器中的每个批次for batch in testing_dataloader:# 不计算梯度提高推理速度with torch.no_grad():# 计算模型的输出和损失取预测结果_, predictions logistic_regression_model(**batch)# 获取预测结果中概率最大的类别索引predictions np.argmax(predictions, axis1)# 将当前批次的预测结果添加到预测结果列表中logistic_regression_predictions.extend(predictions)# 打印前5个测试样本的逻辑回归模型预测结果和真实标签for i, (prediction, label) in enumerate(zip(logistic_regression_predictions, testing_labels)):if i 5:breakprint(f测试样本:{i}, 预测结果 {prediction}, 真实类别 {label})# 将测试标签转换为numpy数组testing_labels np.array(testing_labels)# 将朴素贝叶斯模型的预测结果转换为numpy数组naive_bayes_predictions np.array(naive_bayes_predictions)# 将逻辑回归模型的预测结果转换为numpy数组logistic_regression_predictions np.array(logistic_regression_predictions)# 创建评估指标对象evaluation EvaluationMetrics()# 打印朴素贝叶斯模型的微平均F1值和宏平均F1值print(fNB: micro-f1 {evaluation.calculate_micro_f1(dataset, naive_bayes_predictions, testing_labels)}, fmacro-f1 {evaluation.calculate_macro_f1(dataset, naive_bayes_predictions, testing_labels)})# 打印逻辑回归模型的微平均F1值和宏平均F1值print(fLR: micro-f1 {evaluation.calculate_micro_f1(dataset, logistic_regression_predictions, testing_labels)}, fmacro-f1 {evaluation.calculate_macro_f1(dataset, logistic_regression_predictions, testing_labels)})# 程序入口当脚本作为主程序运行时执行 if __name__ __main__:# 创建自然语言处理文本分类对象nlp_text_classification NLPTextClassification()# 调用文本分类方法进行文本分类操作nlp_text_classification.text_classification()运行结果 NB: micro-f1 1.0, macro-f1 1.0 LR: micro-f1 1.0, macro-f1 1.0进程已结束退出代码为 0 注意博主采用的训练集和测试集是用代码自动生成出来的内容保存到文件中去目的是为了方便讲解功能和展示效果代码也是方便给大家参考。请大家根据需求加载自己的训练集和测试集。 结束 好了以上就是本次关于自然语言处理文本分类的全部内容了。从数据集的预处理、特征工程的构建到朴素贝叶斯和逻辑回归等不同模型的应用再到分类结果的评估我们全面地探讨了文本分类任务的各个关键环节。 在这个过程中我们看到了不同模型的优势与局限。朴素贝叶斯算法凭借其简单高效在一些场景下能取得不错的效果而逻辑回归模型借助强大的深度学习框架PyTorch通过自动求导等功能实现了更为精细的参数优化。 当然自然语言处理文本分类领域仍有许多值得深入研究和探索的方向。比如如何进一步提升模型在小样本、不均衡数据集上的性能以及怎样更好地融合多种模型的优点来构建更强大的分类器。希望今天的分享能为大家在自然语言处理的学习和实践中提供一些思路和帮助。 那么本次分享就到这里了。最后博主还是那句话请大家多去大胆的尝试和使用成功总是在不断的失败中试验出来的敢于尝试就已经成功了一半。如果大家对博主分享的内容感兴趣或有帮助请点赞和关注。大家的点赞和关注是博主持续分享的动力博主也希望让更多的人学习到新的知识。
http://www.dnsts.com.cn/news/242078.html

相关文章:

  • 网站建设视频教程云盘网站开发 验收移交
  • 网站服务器速度2023年时政热点事件
  • 廊坊市建设局官方网站wordpress 安卓主题下载
  • wordpress网站上传到服务器微信公众平台开发实例教程
  • 东营网站建设制作外贸网站自建站
  • 怎样注册平台网站起飞页自助建站平台的特点
  • 网站网络营销怎么做小牛在线网站建设
  • 校园网站做等级保护市场推广seo职位描述
  • 顶岗实践网站开发中国市场网
  • 网站排名优化怎样做百度贴吧的互动社区
  • 做餐饮酒店网站hao123主页我的上网主页
  • python 网站开发 案例网页制作特效代码大全
  • 什么网站可以找到手工活做制作运营是什么专业
  • 北京制卡厂家做卡公司北京制卡网站_北京制卡_北京 去114网上海网站建设网页制作怎么样
  • 门户网站设计说明cms模板网
  • 淘宝客建网站企业危机公关
  • 做网站需要什么系统网站建设大量定制阶段
  • 建设部网站社保联网长沙铭万做网站
  • 网站建设要学哪些软件有哪些方面wordpress添加直达链接
  • 百度网站收录查询地址访问网站提示输入用户名密码
  • 做网站的参考书创意手工
  • 网站建设运营维护方案个人网页制作模板图片代码
  • 咖啡网站建设的需求分析网站建设的两个方面
  • 个人网站建设的步骤wordpress $post->id
  • 合肥网站建设晨飞哪里设计公司vi
  • 卑鄙的网站开发公司域名cn和com有什么区别
  • 做的网站名4435建站
  • 国家对于学校网站建设制作公司官网的步骤
  • 网站前台显示数据库指定分类怎么做phpwordpress死链提交
  • 网站建设收费价格德州网页制作