【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 常量(如?null,?true,?false)的函數。
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.pswp.cn/bicheng/71930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71930.shtml
英文地址,請注明出處:http://en.pswp.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…