【NLP 27、文本分类任务 —— 传统机器学习算法】

不要抓着枯叶哭泣,你要等待初春的新芽

                                                        —— 25.1.23

一、文本分类任务

定义:预先设定好一个文本类别集合,对于一篇文本,预测其所属的类别

例如:

         情感分析:

                这家饭店太难吃了 —> 正类                

                这家菜很好吃        —> 负类

         领域分类:

                今日A股行情大好  —> 经济

                今日湖人击败勇士 —> 体育


二、文本分类 — 使用场景

1.资讯文章打标签

将大的分类再分成二级分类,进行小部分分类

2.电商评论分析

可以进一步分析,当作不同类别,分析具体的好/差评原因

3.违规检测

涉黄、涉暴、涉恐、辱骂等

主要应用在客服、销售对话质检、或网站内容审查等


三、自定义类别任务

类别的定义方式是任意

只要人基于文本能够判断,都可以作为分类类别

如: 垃圾邮件分类、② 对话、文章是否与汽车交易相关、③ 文章风格是否与某作者风格一致、④ 文章是否是机器生成、⑤ 合同文本是否符合规范、⑥ 文章适合阅读人群(未成年、中年、老年、孕妇等)


四、文本分类 — 机器学习

① 定义类别 ——> ② 收集数据 ——> ③ 模型训练 ——> ④ 预测

1.定义类别

首先定义有几个类别

2.收集数据

对于每个类别作数据的收集和标注

3.模型训练

将类别数据送到一个分类器(神经网络 / 机器学习中的其他方法)中去

4.预测

用这个分类器对一些未知文本类别的文本去预测一些类别


五、传统机器学习算法 ① 贝叶斯算法

1.全概率公式

事件A的概率:等于在每种划分之下,划分事件 Bi 的概率 × 在这个划分下事件 A 的概率


2.贝叶斯公式

①  

② 

③ 

P(A|B):后验概率,表示在已知事件B发生的情况下,事件A发生的概率

P(B|A):似然度,在事件A发生的条件下,事件B发生的概率

P(A):先验概率,是在没有任何关于B的信息时,对事件A发生概率的初始估计

P(B):边缘概率,可以通过全概率公式进行计算

B事件发生下,A事件发生的概率 = A事件发生的概率 × A事件发生下,B事件发生的概率 除以 B事件发生的概率


3.贝叶斯公式的应用

求解:如果核酸检测呈阳性,感染新冠的概率是多少?

我们假定新冠在人群中的感染率为0.1%(先验概率:千分之一 0.001)【先验 / 前置概率】

核酸检测有一定误报率,我们假定如下:

P(A) = 感染新冠

P(B) = 核酸检测呈阳性 

P(A | B) = 核酸检测呈阳性,确实感染新冠

P(B | A) = 感染了新冠,且检测结果呈阳性

P(B | ^A) = 未感染新冠,且检测结果呈阳性

计算如下:

        P(A | B) = P(A) * P(B | A) / P (B)

        P(B) = P(B | A) * P(A) + P(B | ^A) * P(^A) # 全概率公式

        P(A | B) = P(A) * P(B | A) /【P(B | A) * P(A) + P(B | ^A) * P(^A)】

                     = 0.001 × 0.99 / (0.99 × 0.001 + 0.05 × 0.999)

                     ≈ 0.019 ≈ 0.02


4.贝叶斯公式在NLP中的应用

用贝叶斯公式处理文本分类任务

一个合理假设:文本属于哪个类别,与文本中包含哪些词相关

任务:知道文本中有哪些词,预测文本属于某类别的概率


5.贝叶斯公式 — 文本分类

假定有3个类别A1, A2, A3

一个文本S有n个词组成,W1, W2, W3....Wn

想要计算文本S属于A1类别的概率:P(A1|S)  = P(A1|W1, W2, W3....Wn)

除以公共分母,得出的所有类别可能性加和为1,近似于做自动归一化

# 贝叶斯公式

# 分母是公共的,可以不进行计算

P(A1 | S) = P(W1, W2…Wn | A1)  * P(A1) / P(W1,W2…Wn)

P(A2 | S) = P(W1, W2…Wn | A2)  * P(A2) / P(W1,W2…Wn)

P(A3 | S) = P(W1, W2…Wn | A3)  * P(A3) / P(W1,W2…Wn)

# 词的独立性假设

P(W1, W2…Wn | A3)  = P(W1 | A3) * P(W2 | A3) *… * P(Wn | A3) 


6.贝叶斯公式 — 代码实现

jieba.initialize():是 ​jieba​ 分词库中的一个函数,用于初始化分词所需的词典和配置。在某些情况下,特别是在多线程或分布式环境中使用 jieba 时,显式调用 initialize() 可以确保分词器正确加载词典并优化性能。

参数类型说明
enable_parallelint 或 False是否启用并行分词。如果设置为 True,则启用并行分词;如果设置为具体的整数,表示并行分词的线程数;默认为 False,即不启用并行分词。
use_paddlebool是否启用 PaddlePaddle 模式。如果设置为 True,则启用 PaddlePaddle 模式进行分词;默认为 False,即不启用该模式。使用此模式需要安装 PaddlePaddle 库。
user_dictstr用户自定义词典的路径。通过设置此参数,可以让 jieba 加载指定的自定义词典,以便在分词时识别特定的词汇。
cut_allbool是否使用全模式分词。如果设置为 True,则使用全模式分词,即把句子中所有的可以成词的词语都扫描出来;如果设置为 False,则使用精确模式分词,即试图将句子最精确地切开;默认为 False
HMMbool是否使用 HMM 模型来识别新词。如果设置为 True,则使用 HMM 模型;如果设置为 False,则不使用 HMM 模型;默认为 True
use_parallelbool 或 int是否启用并行分词及并行分词的线程数。如果设置为 True,则启用并行分词,默认使用CPU核心数;如果设置为整数,则指定并行分词的线程数;默认为 False

Ⅰ、初始化

defaultdict():Python 标准库 collections 模块中的一个类,用于创建具有默认值的字典。当访问一个不存在的键时,defaultdict 会自动创建该键并赋予一个默认值,而不会抛出 KeyError 异常。这在处理数据聚合、计数等场景中非常有用。

参数类型说明
default_factory可调用对象(如函数、类等)用于生成默认值的工厂函数。当访问一个不存在的键时,defaultdict 会调用此工厂函数来生成默认值。常见的用法包括 int(默认值为 0)、list(默认值为 [])、set(默认值为 set())等。如果未提供此参数,defaultdict 的行为类似于普通字典,访问不存在的键时会抛出 KeyError
**kwargs任意关键字参数传递给字典的其他关键字参数,通常用于初始化字典。例如,可以传递一个可迭代对象来初始化字典的键值对。
    def __init__(self, data_path):self.p_class = defaultdict(int)self.word_class_prob = defaultdict(dict)self.load(data_path)

Ⅱ、加载语料文件

defaultdict():Python 标准库 collections 模块中的一个类,用于创建具有默认值的字典。当访问一个不存在的键时,defaultdict 会自动创建该键并赋予一个默认值,而不会抛出 KeyError 异常。这在处理数据聚合、计数等场景中非常有用。

参数类型说明
default_factory可调用对象(如函数、类等)用于生成默认值的工厂函数。当访问一个不存在的键时,defaultdict 会调用此工厂函数来生成默认值。常见的用法包括 int(默认值为 0)、list(默认值为 [])、set(默认值为 set())等。如果未提供此参数,defaultdict 的行为类似于普通字典,访问不存在的键时会抛出 KeyError
**kwargs任意关键字参数传递给字典的其他关键字参数,通常用于初始化字典。例如,可以传递一个可迭代对象来初始化字典的键值对。

set(): Python 内置函数,用于创建一个无序且不重复的集合(set)。集合中的元素必须是可哈希的(即不可变类型),如数字、字符串、元组等。集合常用于去重、集合运算(如并集、交集、差集)等操作。

参数类型说明
iterable可迭代对象(可选)用于初始化集合的可迭代对象,如列表、元组、字符串等。如果未提供,则创建一个空集合。

json.loads(): Python json 模块中的函数,用于将 JSON 格式的字符串解析为 Python 对象(如字典、列表、字符串、数字等)。常用于处理来自网络请求、文件读取等的 JSON 数据。

参数类型说明
sstr要解析的 JSON 格式字符串。
cls可选,json.JSONDecoder 的子类用于解码的自定义解码器类,默认为 json.JSONDecoder
object_hook可选,函数用于自定义解码特定类型的对象。
parse_float可选,函数用于解析浮点数的函数,默认为 float
parse_int可选,函数用于解析整数的函数,默认为 int
parse_constant可选,函数用于解析 JSON 常量(如 nulltruefalse)的函数。
object_pairs_hook可选,函数用于自定义解码对象对的函数,优先级高于 object_hook
strict可选,bool如果为 True,则在遇到非法字符时抛出异常,默认为 True
buffering可选,bool已弃用,忽略此参数。

jieba.lcut():jieba 分词库中的函数,用于将输入的字符串进行分词,并返回一个列表。与 jieba.cut() 不同,lcut() 直接返回列表,而 cut() 返回一个生成器。

参数类型说明
sentencestr需要分词的字符串。
cut_allbool是否使用全模式分词。True 表示全模式,False 表示精确模式(默认)。
HMMbool是否使用 HMM 模型识别新词。True 表示使用,False 表示不使用(默认)。
use_paddlebool是否启用 PaddlePaddle 模式进行分词。需要安装 PaddlePaddle 库。True 或 False
user_dictstr用户自定义词典的路径,用于增强分词效果。

union():集合(set)对象的方法,用于返回两个或多个集合的并集。并集包含所有出现在任一集合中的元素,且不重复。

参数类型说明
*othersset 或可迭代对象一个或多个要合并到当前集合的其他集合或可迭代对象。
    def load(self, path):self.class_name_to_word_freq = defaultdict(dict)self.all_words = set()  #汇总一个词表with open(path, encoding="utf8") as f:for line in f:line = json.loads(line)class_name = line["tag"]title = line["title"]words = jieba.lcut(title)self.all_words = self.all_words.union(set(words))self.p_class[class_name] += 1  #记录每个类别样本数量word_freq = self.class_name_to_word_freq[class_name]#记录每个类别下的词频for word in words:if word not in word_freq:word_freq[word] = 1else:word_freq[word] += 1self.freq_to_prob()return

Ⅲ、将词频和样本频率转化为概率

sum():Python 的内置函数,用于计算可迭代对象(如列表、元组等)中所有元素的总和。它也可以用于将一个可迭代对象中的元素累加到一个初始值上。

参数类型说明
iterable可迭代对象(如列表、元组、集合等)要计算总和的可迭代对象。
startint 或 float(可选)累加的初始值,默认为 0

.values(): Python 字典(dict)的方法,用于返回字典中所有值的视图对象。这个视图对象显示的是字典中所有值的动态视图,当字典的值发生变化时,视图也会反映这些变化。 

dict(): Python 的内置函数,用于创建一个新的字典(dict)。它可以通过多种方式初始化字典,包括从另一个字典、键值对的可迭代对象、关键字参数等。

参数类型说明
object映射对象或可迭代对象(可选)如果提供,object 应该是一个映射(如另一个字典)或包含键值对的可迭代对象。
**kwargs关键字参数(可选)任意数量的关键字参数,用于初始化字典。每个关键字参数的键和值将成为字典中的键值对。

defaultdict():Python 标准库 collections 模块中的一个类,用于创建具有默认值的字典。当访问一个不存在的键时,defaultdict 会自动创建该键并赋予一个默认值,而不会抛出 KeyError 异常。这在处理数据聚合、计数等场景中非常有用。

参数类型说明
default_factory可调用对象(如函数、类等)用于生成默认值的工厂函数。当访问一个不存在的键时,defaultdict 会调用此工厂函数来生成默认值。常见的用法包括 int(默认值为 0)、list(默认值为 [])、set(默认值为 set())等。如果未提供此参数,defaultdict 的行为类似于普通字典,访问不存在的键时会抛出 KeyError
**kwargs任意关键字参数传递给字典的其他关键字参数,通常用于初始化字典。例如,可以传递一个可迭代对象来初始化字典的键值对。

items():Python 字典(dict)的方法,用于返回字典中所有键值对的视图对象。这个视图对象显示的是字典条目的动态视图,意味着当字典发生变化时,视图也会反映这些变化。

len():Python 的内置函数,用于返回对象(如字符串、列表、字典、集合等)的长度或项目数量。

参数类型说明
object任何可迭代或可计数的对象(如字符串、列表、字典、集合、元组等)要计算长度的对象。
    #将记录的词频和样本频率都转化为概率def freq_to_prob(self):#样本概率计算total_sample_count = sum(self.p_class.values())self.p_class = dict([c, self.p_class[c] / total_sample_count] for c in self.p_class)#词概率计算self.word_class_prob = defaultdict(dict)for class_name, word_freq in self.class_name_to_word_freq.items():total_word_count = sum(count for count in word_freq.values()) #每个类别总词数for word in word_freq:#加1平滑,避免出现概率为0,计算P(wn|x1)prob = (word_freq[word] + 1) / (total_word_count + len(self.all_words))self.word_class_prob[class_name][word] = probself.word_class_prob[class_name]["<unk>"] = 1/(total_word_count + len(self.all_words))return

Ⅳ、计算给定单词序列的联合概率

.get():Python 字典(dict)对象的一个方法,用于获取指定键对应的值。如果键不存在于字典中,.get() 方法可以返回一个默认值,而不是引发 KeyError 异常。这使得 .get() 方法在处理字典时更加安全和便捷。

    #P(w1|x1) * P(w2|x1)...P(wn|x1)def get_words_class_prob(self, words, class_name):result = 1for word in words:unk_prob = self.word_class_prob[class_name]["<unk>"]result *= self.word_class_prob[class_name].get(word, unk_prob)return result

Ⅴ、计算特定事件类别x下的联合概率

    #计算P(w1, w2..wn|x1) * P(x1)def get_class_prob(self, words, class_name):#P(x1)p_x = self.p_class[class_name]# P(w1, w2..wn|x1) = P(w1|x1) * P(w2|x1)...P(wn|x1)p_w_x = self.get_words_class_prob(words, class_name)return p_x * p_w_x

Ⅵ、文本分类

jieba.lcut():jieba 分词库中的函数,用于将输入的字符串进行分词,并返回一个列表。与 jieba.cut() 不同,lcut() 直接返回列表,而 cut() 返回一个生成器。

参数类型说明
sentencestr需要分词的字符串。
cut_allbool是否使用全模式分词。True 表示全模式,False 表示精确模式(默认)。
HMMbool是否使用 HMM 模型识别新词。True 表示使用,False 表示不使用(默认)。
use_paddlebool是否启用 PaddlePaddle 模式进行分词。需要安装 PaddlePaddle 库。True 或 False
user_dictstr用户自定义词典的路径,用于增强分词效果。

append():Python 列表(list)的方法,用于在列表的末尾添加一个新的元素。

参数类型说明
object任意类型要添加到列表末尾的对象。可以是任何数据类型,如整数、字符串、列表等。

sorted():Python 的内置函数,用于对可迭代对象进行排序,并返回一个新的排序后的列表。原对象不会被修改。

参数类型说明
iterable可迭代对象需要排序的对象,如列表、元组、字符串等。
key可选,函数用于提取比较键的函数。默认为 None,即直接比较元素。
reverse可选,布尔值如果设置为 True,则列表元素将被倒序(从大到小)排列。默认为 False

sum():Python 的内置函数,用于计算可迭代对象(如列表、元组等)中所有元素的总和。它也可以用于将一个可迭代对象中的元素累加到一个初始值上。

参数类型说明
iterable可迭代对象(如列表、元组、集合等)要计算总和的可迭代对象。
startint 或 float(可选)累加的初始值,默认为 0
    #做文本分类def classify(self, sentence):words = jieba.lcut(sentence) #切词results = []for class_name in self.p_class:prob = self.get_class_prob(words, class_name)  #计算class_name类概率results.append([class_name, prob])results = sorted(results, key=lambda x:x[1], reverse=True) #排序#计算公共分母:P(w1, w2, w3...wn) = P(w1,w2..Wn|x1)*P(x1) + P(w1,w2..Wn|x2)*P(x2) ... P(w1,w2..Wn|xn)*P(xn)#不做这一步也可以,对顺序没影响,只不过得到的不是0-1之间的概率值pw = sum([x[1] for x in results]) #P(w1, w2, w3...wn)results = [[c, prob/pw] for c, prob in results]#打印结果for class_name, prob in results:print("属于类别[%s]的概率为%f" % (class_name, prob))return results

Ⅶ、贝叶斯文本分类实践 

import math
import jieba
import re
import os
import json
from collections import defaultdictjieba.initialize()"""
贝叶斯分类实践P(A|B) = (P(A) * P(B|A)) / P(B)
事件A:文本属于类别x1。文本属于类别x的概率,记做P(x1)
事件B:文本为s (s=w1w2w3..wn)
P(x1|s) = 文本为s,属于x1类的概率.   #求解目标#
P(x1|s) = P(x1|w1, w2, w3...wn) = P(w1, w2..wn|x1) * P(x1) / P(w1, w2, w3...wn)P(x1) 任意样本属于x1的概率。x1样本数/总样本数
P(w1, w2..wn|x1) = P(w1|x1) * P(w2|x1)...P(wn|x1)  词的独立性假设
P(w1|x1) x1类样本中,w1出现的频率公共分母的计算,使用全概率公式:
P(w1, w2, w3...wn) = P(w1,w2..Wn|x1)*P(x1) + P(w1,w2..Wn|x2)*P(x2) ... P(w1,w2..Wn|xn)*P(xn)
"""class BayesApproach:def __init__(self, data_path):self.p_class = defaultdict(int)self.word_class_prob = defaultdict(dict)self.load(data_path)def load(self, path):self.class_name_to_word_freq = defaultdict(dict)self.all_words = set()  #汇总一个词表with open(path, encoding="utf8") as f:for line in f:line = json.loads(line)class_name = line["tag"]title = line["title"]words = jieba.lcut(title)self.all_words = self.all_words.union(set(words))self.p_class[class_name] += 1  #记录每个类别样本数量word_freq = self.class_name_to_word_freq[class_name]#记录每个类别下的词频for word in words:if word not in word_freq:word_freq[word] = 1else:word_freq[word] += 1self.freq_to_prob()return#将记录的词频和样本频率都转化为概率def freq_to_prob(self):#样本概率计算total_sample_count = sum(self.p_class.values())self.p_class = dict([c, self.p_class[c] / total_sample_count] for c in self.p_class)#词概率计算self.word_class_prob = defaultdict(dict)for class_name, word_freq in self.class_name_to_word_freq.items():total_word_count = sum(count for count in word_freq.values()) #每个类别总词数for word in word_freq:#加1平滑,避免出现概率为0,计算P(wn|x1)prob = (word_freq[word] + 1) / (total_word_count + len(self.all_words))self.word_class_prob[class_name][word] = probself.word_class_prob[class_name]["<unk>"] = 1/(total_word_count + len(self.all_words))return#P(w1|x1) * P(w2|x1)...P(wn|x1)def get_words_class_prob(self, words, class_name):result = 1for word in words:unk_prob = self.word_class_prob[class_name]["<unk>"]result *= self.word_class_prob[class_name].get(word, unk_prob)return result#计算P(w1, w2..wn|x1) * P(x1)def get_class_prob(self, words, class_name):#P(x1)p_x = self.p_class[class_name]# P(w1, w2..wn|x1) = P(w1|x1) * P(w2|x1)...P(wn|x1)p_w_x = self.get_words_class_prob(words, class_name)return p_x * p_w_x#做文本分类def classify(self, sentence):words = jieba.lcut(sentence) #切词results = []for class_name in self.p_class:prob = self.get_class_prob(words, class_name)  #计算class_name类概率results.append([class_name, prob])results = sorted(results, key=lambda x:x[1], reverse=True) #排序#计算公共分母:P(w1, w2, w3...wn) = P(w1,w2..Wn|x1)*P(x1) + P(w1,w2..Wn|x2)*P(x2) ... P(w1,w2..Wn|xn)*P(xn)#不做这一步也可以,对顺序没影响,只不过得到的不是0-1之间的概率值pw = sum([x[1] for x in results]) #P(w1, w2, w3...wn)results = [[c, prob/pw] for c, prob in results]#打印结果for class_name, prob in results:print("属于类别[%s]的概率为%f" % (class_name, prob))return resultsif __name__ == "__main__":path = "F:\人工智能NLP/NLP\Day7_文本分类问题\data/train_tag_news.json"ba = BayesApproach(path)query = "中国三款导弹可发射多弹头 美无法防御很急躁"ba.classify(query)


7.贝叶斯算法的优点和缺点

缺点:

① 如果样本不均衡会极大影响先验概率

② 对于未见过的特征或样本,条件概率为零,失去预测的意义(可以引入平滑)

③ 特征独立假设只是个假设

④ 没有考虑语序,也没有词义

优点:

① 简单高效

② 一定的可解释性

③ 如果样本覆盖的好,效果是不错的

④ 训练数据可以很好的分批处理


六、传统机器学习算法 ② 支持向量机 SVM

SVM:support vector machine,1964年提出

属于有监督学习 supervised learning

通过数据样本,学习最大边距超平面

引例:尝试用一条线将蓝色球与红色三角分开

SVM分类器:类别不同的样本进行切分,并且要尽可能的让两类数据中最近的支持向量 距离这条分割函数最远(目标是最大化marginmargin:分类线到两边最近的支持向量的距离)【寻找一个最优的决策边界距离两个类别的最近的样本(称为支持向量)最远】

线性(直线)可分问题下的决策函数:

线性(直线)不可分问题:SVM算法中,将空间映射到更高的维度来分类非线性数据

神经网络中:添加激活函数来拟合非线性数据分布】


1.支持向量机 — 核函数

为了解决线性不可分问题,我们需要把输入映射到高维,即寻找函数,使其输出维度高于x  

例如: x = [X1, X2, X3]  

=  [X1*X1,  X1*X2,  X1*X3,  X2*X1,  X2*X2,  X2*X3,  X3*X1,  X3*X2,  X3*X3]   (对自己做笛卡尔积)

这样x就从3维上升到9维

向高维映射如何解决线性不可分问题?

示例:

考虑一组一维数据,[-1, 0, 1] 为正样本,[-3, -2, 2, 3]为负样本

将x映射为【x,  x^2】后 ,可以用直线划分,更高维度也是同理

但是这样出现一个问题,维度过高的向量计算在进行内积运算非常耗时,而svm的求解中内积运算很频繁

所以我们希望内有一种方法快速计算内积运算【

核函数的意义:

两个向量x1、x2过一个核函数之后的结果,恰好等于这两个向量x1、x2分别通过一个高维映射然后再做内积得到的结果,基于核函数可以简化支持向量机中的内积运算

绕过向高维空间映射的向量内积运算,直接代入计算核函数的公式,使得经过核函数运算后的向量恰好等于原向量经过向量内积运算映射到高维空间

所谓的【核函数即为满足条件:【】的函数,这些函数统称为核函数


2.常见核函数

线性核函数:

多项式核函数:

高斯核函数:

双曲正切核函数:


3.支持向量机 — 解决多分类问题

假设要解决一个K分类问题,即有K个目标类别

方式一:one vs one方式

建立 K(K - 1) / 2 个svm分类器,每个分类器负责K个类别中的两个类别,判断输入样本属于哪个类别

对于一个待预测的样本,使用所有分类器进行分类,最后保留被预测词数最多的类别

例:假设类别有[A,B,C]

        X —> SVM(A,B) —> A

        X —> SVM(A,C) —> A

        X —> SVM(B,C) —> B

最终判断   X —> A


方式二:one vs rest方式

建立K个svm分类器,每个分类器负责划分输入样本属于K个类别中的某一个类别的概率,最后保留预测分值最高的类别

例:假设类别有[A,B,C]

        X —> SVM(A,rest) —> 0.1

        X —> SVM(B,rest) —> 0.2

        X —> SVM(C,rest) —> 0.5

最终判断: X —> C 


4.支持向量机的优缺点

优点:

        ① 少数支持向量决定了最终结果,对异常值不敏感

        ② 对于样本数量需求较低

        ③ 可以处理高维度数据

缺点:

        ① 样本数量过多的时候,计算负担很大

        ② 多分类任务处理起来比较麻烦

        ③ 核函数的选取以及参数的选取较为困难


5.代码实现

Ⅰ、加载训练好的模型

Word2Vec.load():加载之前保存的 Word2Vec 模型

参数类型说明
filepath_or_bufferstr 或 file-like object模型文件的路径或文件对象。
*args任意其他参数传递给底层加载机制的其他参数(通常不需要)。
**kwargs任意关键字参数传递给底层加载机制的其他关键字参数(通常不需要)。
#输入模型文件路径
#加载训练好的模型
def load_word2vec_model(path):model = Word2Vec.load(path)return model

Ⅱ、加载数据集

 open():打开一个文件,并返回一个文件对象,用于读取、写入或其他操作。

参数类型说明
filestr 或 path-like object要打开的文件路径。
modestr文件打开模式,如 'r'(读取)、'w'(写入)、'a'(追加)等。
bufferingint缓冲策略。
encodingstr文件编码方式,如 'utf-8'
errorsstr错误处理方式,如 'strict''ignore' 等。
其他参数根据模式不同,可能有其他参数。

json.loads():将 JSON 格式的字符串解析为 Python 对象(如字典、列表等)。

参数类型说明
sstr要解析的 JSON 字符串。
cls可选,json.JSONDecoder 的子类自定义解码器类,默认为 json.JSONDecoder
object_hook可选,函数用于自定义解码特定类型的对象。
其他参数其他可选参数,如 parse_floatparse_int 等。

append():将一个元素添加到列表的末尾。

参数类型说明
object任意类型要添加到列表末尾的对象。

join():将序列中的元素连接成一个字符串,元素之间使用指定的分隔符。

参数类型说明
iterable可迭代对象要连接的元素序列,如列表、元组等。
sepstr元素之间的分隔符,默认为空字符串。

jieba.lcut():使用 jieba 分词库将输入的字符串切分成词语列表。

参数类型说明
sentencestr需要分词的字符串。
cut_allbool是否使用全模式分词。True 表示全模式,False 表示精确模式(默认)。
HMMbool是否使用 HMM 模型识别新词。True 表示使用,False 表示不使用(默认)。
use_paddlebool是否启用 PaddlePaddle 模式进行分词。需要安装 PaddlePaddle 库。True 或 False
user_dictstr用户自定义词典的路径,用于增强分词效果。
#加载数据集
def load_sentence(path, model):sentences = []labels = []with open(path, encoding="utf8") as f:for line in f:line = json.loads(line)title, content = line["title"], line["content"]sentences.append(" ".join(jieba.lcut(title)))labels.append(line["tag"])train_x = sentences_to_vectors(sentences, model)train_y = label_to_label_index(labels)return train_x, train_y

Ⅲ、 将tag标签转换为类别编号

#tag标签转化为类别标号
def label_to_label_index(labels):return [LABELS[y] for y in labels]

Ⅳ、 文本向量化

split():将字符串按照指定的分隔符切分成子字符串列表。

参数类型说明
sepstr 或 None分隔符,默认为任意空白字符。
maxsplitint最大分割次数,默认为 -1,表示不限制。

np.zeros():创建一个指定形状和数据类型的全零数组。

参数类型说明
shapeint 或 tuple数组的形状。
dtypedata-type数组元素的数据类型,默认为 float64
order'C' 或 'F'内存布局方式,'C' 行优先,'F' 列优先,默认为 'C'

append():将一个元素添加到列表的末尾。

参数类型说明
object任意类型要添加到列表末尾的对象。

np.array():创建一个 NumPy 数组。

参数类型说明
objectarray_like输入数据,可以是列表、元组、嵌套列表等。
dtypedata-type数组元素的数据类型,默认由输入数据推断。
copybool是否复制输入数据,默认为 True
ndminint返回数组的最小维度。
其他参数根据具体需求,可能有其他参数。

model.wv():访问 Word2Vec 模型的词向量(word vectors)。

参数类型说明
wordstr要获取词向量的单词。
vectorbool是否返回词向量,默认为 True
其他参数根据具体需求,可能有其他参数。
#文本向量化,使用了基于这些文本训练的词向量
def sentences_to_vectors(sentences, model):vectors = []for sentence in sentences:words = sentence.split()vector = np.zeros(model.vector_size)for word in words:try:vector += model.wv[word]# vector = np.max([vector, model.wv[word]], axis=0)except KeyError:vector += np.zeros(model.vector_size)vectors.append(vector / len(words))return np.array(vectors)

Ⅴ、SVM分类器训练

SVC():支持向量分类器(Support Vector Classifier),用于分类任务

参数类型说明
Cfloat正则化参数,控制误分类的惩罚力度。
kernelstr 或 callable核函数类型,如 'linear''poly''rbf''sigmoid' 等。
degreeint多项式核函数的度数,默认为 3。
gammastr 或 float核函数的系数,'scale' 或 'auto',或具体数值。
coef0float核函数中的独立项。
其他参数根据具体需求,可能有其他参数。

SVC对象.fit():训练支持向量分类器模型。

参数类型说明
Xarray-like训练数据的特征矩阵。
yarray-like训练数据的目标标签。
sample_weightarray-like每个样本的权重。
其他参数根据具体需求,可能有其他参数。

SVC对象.predict():使用训练好的支持向量分类器进行预测。

参数类型说明
Xarray-like需要预测的数据特征矩阵。
返回值array预测的标签。

classification_report():生成一个文本报告,展示主要的分类指标,如精确率(precision)、召回率(recall)、F1 分数等。

参数类型说明
y_truearray-like真实的目标标签。
y_predarray-like预测的目标标签。
labelsarray-like报告中包含的标签列表。
target_nameslist 或 None标签的可读名称。
sample_weightarray-like每个样本的权重。
其他参数根据具体需求,可能有其他参数。
def main():model = load_word2vec_model("model.w2v")train_x, train_y = load_sentence("F:\人工智能NLP\\NLP\Day7_文本分类问题\data\\train_tag_news.json", model)test_x, test_y = load_sentence("F:\人工智能NLP\\NLP\Day7_文本分类问题\data\\valid_tag_news.json", model)classifier = SVC()classifier.fit(train_x, train_y)y_pred = classifier.predict(test_x)print(classification_report(test_y, y_pred))

Ⅵ、使用基于词向量的SVM分类器

#!/usr/bin/env python3  
#coding: utf-8#使用基于词向量的分类器
#对比几种模型的指标import json
import jieba
import numpy as np
from gensim.models import Word2Vec
from sklearn.metrics import classification_report
from sklearn.svm import SVC
from collections import defaultdictLABELS = {'健康': 0, '军事': 1, '房产': 2, '社会': 3, '国际': 4, '旅游': 5, '彩票': 6, '时尚': 7, '文化': 8, '汽车': 9, '体育': 10, '家居': 11, '教育': 12, '娱乐': 13, '科技': 14, '股票': 15, '游戏': 16, '财经': 17}#输入模型文件路径
#加载训练好的模型
def load_word2vec_model(path):model = Word2Vec.load(path)return model#加载数据集
def load_sentence(path, model):sentences = []labels = []with open(path, encoding="utf8") as f:for line in f:line = json.loads(line)title, content = line["title"], line["content"]sentences.append(" ".join(jieba.lcut(title)))labels.append(line["tag"])train_x = sentences_to_vectors(sentences, model)train_y = label_to_label_index(labels)return train_x, train_y#tag标签转化为类别标号
def label_to_label_index(labels):return [LABELS[y] for y in labels]#文本向量化,使用了基于这些文本训练的词向量
def sentences_to_vectors(sentences, model):vectors = []for sentence in sentences:words = sentence.split()vector = np.zeros(model.vector_size)for word in words:try:vector += model.wv[word]# vector = np.max([vector, model.wv[word]], axis=0)except KeyError:vector += np.zeros(model.vector_size)vectors.append(vector / len(words))return np.array(vectors)def main():model = load_word2vec_model("model.w2v")train_x, train_y = load_sentence("F:\人工智能NLP\\NLP\Day7_文本分类问题\data\\train_tag_news.json", model)test_x, test_y = load_sentence("F:\人工智能NLP\\NLP\Day7_文本分类问题\data\\valid_tag_news.json", model)classifier = SVC()classifier.fit(train_x, train_y)y_pred = classifier.predict(test_x)print(classification_report(test_y, y_pred))if __name__ == "__main__":main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/71930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lumoz Chain正式上线:AI 时代的新算力破局者

新的叙事和技术突破永远是推动行业前行的核心动力。当下&#xff0c;AI Agent无疑是最炙手可热的赛道之一。 当加密世界将目光投向AI领域时&#xff0c;大多数项目仍停留在以AI为工具或应用场景的层面&#xff0c;试图通过集成AI模型或优化链上功能来吸引用户。然而&#xff0c…

Python - Python连接数据库

Python的标准数据库接口为&#xff1a;Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个实现库&#xff0c;Python2中则使用mysqldb。 PyMySQL 遵循 Python 数据库 API v2.0 规范&…

面试八股文--数据库基础知识总结(1)

1、数据库的定义 数据库&#xff08;DataBase&#xff0c;DB&#xff09;简单来说就是数据的集合数据库管理系统&#xff08;Database Management System&#xff0c;DBMS&#xff09;是一种操纵和管理数据库的大型软件&#xff0c;通常用于建立、使用和维护数据库。数据库系统…

关于在java项目部署过程MySQL拒绝连接的分析和解决方法

前言 在最近一次部署项目一次项目部署过程中&#xff0c;由于没有对MySQL数据库的部分权限和远程连接进行授权&#xff0c;导致了在执行项目功能API时&#xff0c;出现MySQL连接异常或MySQL拒绝连接的问题。 问题 以下是部分报错截图&#xff1a; 分析 根据日志提示&#xf…

PhotoLine绿色版 v25.00:全能型图像处理软件的深度解析

在图像处理领域,PhotoLine以其强大的功能和紧凑的体积,赢得了国内外众多用户的喜爱。本文将为大家全面解析PhotoLine绿色版 v25.00的各项功能,帮助大家更好地了解这款全能型的图像处理软件。 一、迷你体积,强大功能 PhotoLine被誉为迷你版的Photoshop,其体积虽小,但功能却…

阿里重磅模型深夜开源;DeepSeek宣布开源DeepGEMM;微软开源多模态AI Agent基础模型Magma...|网易数智日报

阿里重磅模型深夜开源&#xff1a;表现超越Sora、Pika&#xff0c;消费级显卡就能跑 2月26日&#xff0c;25日深夜阿里云视频生成大模型万相2.1&#xff08;Wan&#xff09;正式宣布开源&#xff0c;此次开源采用Apache2.0协议&#xff0c;14B和1.3B两个参数规格的全部推理代码…

002 Java操作kafka客户端

Java操作kafka客户端 文章目录 Java操作kafka客户端3.Java操作kafka客户端1.引入依赖2. Kafka服务配置3、生产者&#xff08;Producer&#xff09;实现1. 基础配置与发送消息2. 关键配置说明 4.消费者&#xff08;Consumer&#xff09;实现1. 基础配置与消费消息2. 关键配置说明…

【SRC实战】信息泄露导致越权会员功能

01 — 漏洞证明 1、VIP功能 2、SVIP功能 3、点击任意用户发起私聊&#xff0c;发现userId纯数字可遍历 4、返回包泄露身高范围height&#xff0c;星座constellation&#xff0c;属相zodiac&#xff0c;恋爱目标purpose&#xff0c;教育程度degree&#xff0c;成功越权VIP功能 …

游戏引擎学习第125天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾并为今天的内容做准备。 昨天&#xff0c;当我们离开时&#xff0c;工作队列已经完成了基本的功能。这个队列虽然简单&#xff0c;但它能够执行任务&#xff0c;并且我们已经为各种操作编写了测试。字符串也能够正常推送到队…

蓝桥杯 Java B 组之记忆化搜索(滑雪问题、斐波那契数列)

Day 5&#xff1a;记忆化搜索&#xff08;滑雪问题、斐波那契数列&#xff09; &#x1f4d6; 一、记忆化搜索简介 记忆化搜索&#xff08;Memoization&#xff09; 是一种优化递归的方法&#xff0c;它利用 哈希表&#xff08;HashMap&#xff09;或数组 存储已经计算过的结果…

反爬虫策略

反爬虫策略是网站用于防止自动化程序&#xff08;爬虫&#xff09;恶意抓取数据的核心手段&#xff0c;其设计需兼顾有效性、用户体验和合法性。 一、 基础检测与拦截 User-Agent检测&#xff1a;验证请求头中的User-Agent&#xff0c;拦截非常见或已知爬虫标识。IP频率限制&…

Java 实现快速排序算法:一条快速通道,分而治之

大家好&#xff0c;今天我们来聊聊快速排序&#xff08;QuickSort&#xff09;算法&#xff0c;这个经典的排序算法被广泛应用于各种需要高效排序的场景。作为一种分治法&#xff08;Divide and Conquer&#xff09;算法&#xff0c;快速排序的效率在平均情况下非常高&#xff…

深入解析 Spring 中的 BeanDefinition 和 BeanDefinitionRegistry

在 Spring 框架中&#xff0c;BeanDefinition 和 BeanDefinitionRegistry 是两个非常重要的概念&#xff0c;它们共同构成了 Spring IoC 容器的核心机制。本文将详细介绍这两个组件的作用、实现以及它们之间的关系。 一、BeanDefinition&#xff1a;Bean 的配置描述 1.1 什么…

《OpenCV》——光流估计

什么是光流估计&#xff1f; 光流估计的前提&#xff1f; 基本假设 亮度恒定假设&#xff1a;目标像素点的亮度在相邻帧之间保持不变。这是光流计算的基础假设&#xff0c;基于此可以建立数学方程来求解光流。时间连续或运动平滑假设&#xff1a;相邻帧之间的时间间隔足够小&a…

信息系统的安全防护

文章目录 引言**1. 物理安全****2. 网络安全****3. 数据安全****4. 身份认证与访问控制****5. 应用安全****6. 日志与监控****7. 人员与管理制度****8. 其他安全措施****9. 安全防护框架**引言 从技术、管理和人员三个方面综合考虑,构建多层次、多维度的安全防护体系。 信息…

如何进行OceanBase 运维工具的部署和表性能优化

本文来自OceanBase 用户的实践分享 随着OceanBase数据库应用的日益深入&#xff0c;数据量不断攀升&#xff0c;单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此&#xff0c;部署专门的运维工具、实施针对性的表性能优化策略&#xff0c;以及加强指标监测工作&…

如何防止 Instagram 账号被盗用:安全设置与注意事项

如何防止 Instagram 账号被盗用&#xff1a;安全设置与注意事项 在这个数字化时代&#xff0c;社交媒体平台如 Instagram 已成为我们日常生活的一部分。然而&#xff0c;随着网络犯罪的增加&#xff0c;保护我们的在线账户安全变得尤为重要。以下是一些关键的安全设置和注意事…

Redis|复制 REPLICA

文章目录 是什么能干嘛怎么玩案例演示复制原理和工作流程复制的缺点 是什么 官网地址&#xff1a;https://redis.io/docs/management/replication/Redis 复制机制用于将数据从一个主节点&#xff08;Master&#xff09;复制到一个或多个从节点&#xff08;Slave&#xff09;&a…

对象存储之Ceph

Ceph 对象存储概述 Ceph 是一个开源分布式存储系统&#xff0c;旨在提供高度可扩展、高度可用、容错、性能优异的存储解决方案。它结合了块存储、文件系统存储和对象存储的功能&#xff0c;且在设计上具有极高的可扩展性和灵活性。 在 Ceph 中&#xff0c;对象存储&#xff0…