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

【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()

相关文章:

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

不要抓着枯叶哭泣&#xff0c;你要等待初春的新芽 —— 25.1.23 一、文本分类任务 定义&#xff1a;预先设定好一个文本类别集合&#xff0c;对于一篇文本&#xff0c;预测其所属的类别 例如&#xff1a; 情感分析&#xff1a; 这家饭店太难吃了 —> 正类 …...

Go红队开发—并发编程

文章目录 并发编程go协程chan通道无缓冲通道有缓冲通道创建⽆缓冲和缓冲通道 等协程sync.WaitGroup同步Runtime包Gosched()Goexit() 区别 同步变量sync.Mutex互斥锁atomic原子变量 SelectTicker定时器控制并发数量核心机制 并发编程阶段练习重要的细节端口扫描股票监控 并发编程…...

Oracle 导出所有表索引的创建语句

在Oracle数据库中&#xff0c;导出所有表的索引创建语句通常涉及到使用数据字典视图来查询索引的定义&#xff0c;然后生成对应的SQL语句。你可以通过查询DBA_INDEXES或USER_INDEXES视图&#xff08;取决于你的权限和需求&#xff09;来获取这些信息。 使用DBA_INDEXES视图 如…...

使用Docker方式一键部署MySQL和Redis数据库详解

一、前言 数据库是现代应用开发中不可或缺的一部分&#xff0c;MySQL和Redis作为两种广泛使用的数据库系统&#xff0c;分别用于关系型数据库和键值存储。本文旨在通过Docker和Docker Compose的方式&#xff0c;提供一个简洁明了的一键部署方案&#xff0c;确保数据库服务的稳…...

2020年蓝桥杯Java B组第二场题目+部分个人解析

#A&#xff1a;门牌制作 624 解一&#xff1a; public static void main(String[] args) {int count0;for(int i1;i<2020;i) {int ni;while(n>0) {if(n%102) {count;}n/10;}}System.out.println(count);} 解二&#xff1a; public static void main(String[] args) {…...

[深度学习] 大模型学习2-提示词工程指北

在文章大语言模型基础知识里&#xff0c;提示词工程&#xff08;Prompt Engineering&#xff09;作为大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;应用构建的一种方式被简要提及&#xff0c;本文将着重对该技术进行介绍。 提示词工程就是在和LLM聊…...

FPGA之硬件设计笔记-持续更新中

目录 1、说在前面2、FPGA硬件设计总计说明3、 原理图详解 - ARITX - 7 系列3.1 顶层框图介绍3.2 FPGA 电源sheet介绍&#xff1a;3.2.1 bank 14 和 bank 15的供电3.2.2 bank 0的供电3.2.3 Bank34 35 的供电 3.3 核电压和RAM电压以及辅助电压 4 原理图详解-- Ultrascale ARTIX4.…...

vue cli 与 vite的区别

1、现在我们一般会用vite来构建vue3的项目。 2、之前一开始的时候&#xff0c;我们会用vue cli的vue create来构建项目。 3、它们之间有什么区别呢&#xff1f; 1. 设计理念 Vue CLI&#xff1a; 是 Vue.js 官方提供的命令行工具&#xff0c;主要用于快速搭建 Vue 项目。 提…...

怎么在本地环境安装yarn包

一、安装Yarn的前置条件 安装Node.js和npm Yarn依赖于Node.js环境&#xff0c;需先安装Node.js官网的最新稳定版&#xff08;建议≥16.13.0&#xff09;。安装时勾选“Add to PATH”以自动配置环境变量。 二、安装Yarn的多种方式 1. 通过npm全局安装&#xff08;通用&#xf…...

【大模型】AI 辅助编程操作实战使用详解

目录 一、前言 二、AI 编程介绍 2.1 AI 编程是什么 2.1.1 为什么需要AI辅助编程 2.2 AI 编程主要特点 2.3 AI编程底层核心技术 2.4 AI 编程核心应用场景 三、AI 代码辅助编程解决方案 3.1 AI 大模型平台 3.1.1 AI大模型平台代码生成优缺点 3.2 AI 编码插件 3.3 AI 编…...

react18自定义hook实现

概念&#xff1a;自定义 hook 是一种将组件逻辑提取到可复用函数中的方式&#xff0c;它允许你在多个组件中共享相同的状态和行为。自定义 hook 的本质上是一个普通的 JavaScript 函数&#xff0c;它可以使用 React 内部的 hook&#xff08;如 useState、useEffect、useContext…...

一周学会Flask3 Python Web开发-Jinja2模板过滤器使用

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Jinja2中&#xff0c;过滤器(filter)是一些可以用来修改和过滤变量值的特殊函数&#xff0c;过滤器和变量用一个竖线 | &a…...

使用PDFMiner.six解析PDF数据

PDF&#xff08;可移植文档格式&#xff09;文件是由Adobe创建的一种灵活的文件格式&#xff0c;它允许文档在不同的软件、硬件和操作系统中一致地显示。每个PDF文件都包含对固定布局文档的全面描述&#xff0c;包括文本、字体、图形和其他必要的显示元素。pdf通常用于文档共享…...

本地svn

参考补充&#xff1a;https://blog.csdn.net/hhl_work/article/details/107832414 先在D:\coding_cangku下新建空文件夹&#xff0c;例&#xff1a;code1【类似gitee线上仓库】点击进入code1&#xff0c;右键选择TortoiseSVN&#xff0c;再下一级菜单下点击Create repository …...

金融支付行业技术侧重点

1. 合规问题 第三方支付系统的平稳运营&#xff0c;严格遵循《非银行支付机构监督管理条例》的各项条款是基础与前提&#xff0c;其中第十八条的规定堪称重中之重&#xff0c;是支付机构必须牢牢把握的关键准则。 第十八条明确指出&#xff0c;非银行支付机构需构建起必要且独…...

axios几种请求类型的格式

Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;广泛用于浏览器和 Node.js 中发送 HTTP 请求。它支持多种请求格式&#xff0c;包括 GET、POST、PUT、DELETE 等。也叫RESTful 目录 一、axios几种请求类型的格式 1、get请求 2、post请求 3、put请求 4、delete请求 二…...

二、IDE集成DeepSeek保姆级教学(使用篇)

各位看官老爷好&#xff0c;如果还没有安装DeepSeek请查阅前一篇 一、IDE集成DeepSeek保姆级教学(安装篇) 一、DeepSeek在CodeGPT中使用教学 1.1、Edit Code 编辑代码 选中代码片段 —> 右键 —> CodeGPT —> Edit Code, 输入自然语言可编辑代码&#xff0c;点击S…...

通过理解 sk_buff 深入掌握 Linux 内核自定义协议族的开发实现

要开发 Linux 内核中的自定义协议族(如私有传输层或网络层协议),需基于 sk_buff 的结构和操作,结合内核网络栈的扩展机制。以下是实现这一目标的分步指南: 1. 协议族开发的核心步骤 (1) 注册自定义协议族 定义协议号 在 <linux/if_ether.h> 或自定义头文件中分配唯…...

Qt 自带颜色属性

Qt 系统自带颜色如下&#xff1a; enum GlobalColor {color0,color1,black,white,darkGray,gray,lightGray,red,green,blue,cyan,magenta,yellow,darkRed,darkGreen,darkBlue,darkCyan,darkMagenta,darkYellow,transparent};对应颜色如下&#xff1a; color0: 这是自定义颜色…...

Linux的文件与目录管理

rm -rf / 列出目录内容和属性 命令&#xff1a;ls 格式&#xff1a;ls 选项 文件名 例&#xff1a; ls -a 打印工作路径 命令&#xff1a;pwd 切换工作目录 命令&#xff1a;cd 格式&#xff1a;cd 相对路径或者绝对路径 查看文件类型 命令&#xff1a;file 格式…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...