【注】:本文所述的實驗的完整實現(xiàn)代碼包括數(shù)據(jù)集的倉庫鏈接會在文末給出(建議讀者自行配置GPU來加速TensorFlow的相關(guān)模型,運行起來會快非常多)
目錄
一、研究的背景和目的
二、文本數(shù)據(jù)集描述
1、數(shù)據(jù)集來源以及使用目的
2、數(shù)據(jù)規(guī)模、以及如何劃分?jǐn)?shù)據(jù)集
3、數(shù)據(jù)集的組成和類型
4、文本處理方式
5、數(shù)據(jù)集使用注意
三、實驗方法介紹
1、實驗環(huán)境及編程語言選擇?
2、實驗方法
3、實驗步驟?
(1) 數(shù)據(jù)預(yù)處理
(2) CNN模型構(gòu)建
(3) 模型編譯和訓(xùn)練驗證
四、實驗結(jié)果分析
1、模型的準(zhǔn)確性分析
2、模型評估指標(biāo)分析
五、實驗結(jié)論
一、研究的背景和目的
????????中文文本情感分析是一種研究人類情感表達(dá)的計算機技術(shù),它可以自動地分析文本中的情感,并將其分類為積極、消極或中性。隨著互聯(lián)網(wǎng)的普及和社交媒體的興起,人們在網(wǎng)上表達(dá)情感的方式變得越來越多樣化和頻繁化,這使得情感分析技術(shù)變得更加重要。
????????中文文本情感分析的研究背景可以追溯到計算機語言學(xué)和自然語言處理領(lǐng)域的起源。近年來,隨著深度學(xué)習(xí)技術(shù)的發(fā)展,基于深度學(xué)習(xí)的情感分析算法取得了顯著的進(jìn)展,成為了研究熱點。
????????中文文本情感分析的目的是提高計算機對人類情感表達(dá)的理解能力,幫助人們更好地了解和分析社會情感動態(tài),為商業(yè)決策、輿情分析、個性化推薦等領(lǐng)域提供技術(shù)支持。同時,它也有助于為語義理解和自然語言生成等研究提供基礎(chǔ)和應(yīng)用場景。
二、文本數(shù)據(jù)集描述
1、數(shù)據(jù)集來源以及使用目的
????????本實驗所使用的數(shù)據(jù)集weibo_sentiment.csv來自于GitHub上的開源數(shù)據(jù)集,可以用于機器學(xué)習(xí)中的中文文本情感分析的練習(xí)任務(wù)。
2、數(shù)據(jù)規(guī)模、以及如何劃分?jǐn)?shù)據(jù)集
????????weibo_sentiment.csv 數(shù)據(jù)集中的數(shù)據(jù)規(guī)模即共有119988條中文文本,基本正面和負(fù)面的評論都差不多,所以最終的結(jié)果也比較穩(wěn)定;本實驗使用的時K折交叉驗證來訓(xùn)練模型,數(shù)據(jù)集隨機按照9:1的比例來劃分,并循環(huán)訓(xùn)練十次。
3、數(shù)據(jù)集的組成和類型
????????數(shù)據(jù)集主要是來自微博上的各種評論,包括各種各樣不同類別的評論內(nèi)容,每行文本的組成是情感標(biāo)簽和評論的具體內(nèi)容。標(biāo)簽和內(nèi)容的樣式示例如下所示:
情感標(biāo)簽與情感類別的對應(yīng)
情感標(biāo)簽 |
情感類別 |
0 |
負(fù)向評論 |
1 |
正向評論 |
4、文本處理方式
????????本實驗所使用的數(shù)據(jù)集已經(jīng)經(jīng)過了初步的預(yù)處理(幾乎標(biāo)準(zhǔn)的csv格式),形成了每行文本以“情感標(biāo)簽,評論內(nèi)容”這樣每個屬性以“,”隔開的格式。本實驗將會把這批數(shù)據(jù)的文本內(nèi)容部分先進(jìn)行分詞并去除停用詞,然后使用,使用Keras的Tokenizer方法將文本中的每個單詞映射為一個數(shù)字編號,并將文本轉(zhuǎn)換為數(shù)字列表形式的詞向量,以便于后續(xù)的處理;由于每個文本的長度不一,為了能夠?qū)⑺鼈冚斎氲较嗤螤畹哪P椭?,這里我們需要對詞向量進(jìn)行補齊操作,將每個詞向量的長度填充為相同的值,本實驗使用Keras的pad_sequences方法進(jìn)行補齊操作,并將詞向量的最大長度設(shè)置為280(因為根據(jù)實驗前的統(tǒng)計,幾乎每條文本的長度都小于280),本實驗在補齊序列的時候是令truncating='post'、以及padding默認(rèn)為pre,即主要保留后面部分,就是當(dāng)長度超過280時截斷前面多余的部分,長度不足280時,在前面部分補0。
# 讀取我們本次實驗的文本數(shù)據(jù)
df = pd.read_csv('../Emotional_text/weibo_sentiment.csv')
# 分詞并去除停用詞
stop_words = load_stopwords()
df['review'] = df['review'].apply(lambda x: ' '.join(word for word in jieba.cut(x) if word not in stop_words))
# 使用Keras的Tokenizer來轉(zhuǎn)化詞語為詞向量,這里我們選擇出現(xiàn)頻率前25000個詞作為詞袋
tokenizer = Tokenizer(num_words=25000, oov_token='<OOV>')
tokenizer.fit_on_texts(df['review'])
seq = tokenizer.texts_to_sequences(df['review'])
# 補齊每個樣本序列,使其長度一樣來方便后續(xù)的計算
max_len = 280
seq = pad_sequences(seq, maxlen=max_len, truncating='post')
5、數(shù)據(jù)集使用注意
????????本實驗所使用的數(shù)據(jù)集來自網(wǎng)上開源的語料庫,請不要用于商業(yè)用途歡迎自主學(xué)習(xí)使用。
三、實驗方法介紹
1、實驗環(huán)境及編程語言選擇?
????????實驗環(huán)境:
????????????????操作系統(tǒng):? Windows10/Windows11
????????軟件包管理部署工具: Anaconda3
????????Python語言版本: Python3.10.9
2、實驗方法
????????本實驗主要使用的是卷積神經(jīng)網(wǎng)絡(luò)(CNN)來進(jìn)行中文文本的情感分析,其中主要的模型算法來自Keras以及Tensorflow,本實驗的模型中先后添加了詞嵌入層、卷積層、池化層、全連接層、和輸出層,具體的原理和實現(xiàn)步驟方法將在下面的實驗步驟中給出?? 。
3、實驗步驟?
(1) 數(shù)據(jù)預(yù)處理
????????數(shù)據(jù)預(yù)處理大部分的步驟在“二、文本數(shù)據(jù)集描述”一節(jié)中已經(jīng)具體的闡述過了,這里就簡單的說一下后續(xù)的處理,在將每一句的詞向量補齊之后就開始了劃分?jǐn)?shù)據(jù)集,本實驗使用K折交叉驗證,其中本實驗延續(xù)上一個實驗繼續(xù)將K值設(shè)為10,即把數(shù)據(jù)分成十份,訓(xùn)練集九份、驗證集一份,然后每一份都做一次驗證集來訓(xùn)練,這樣可以是模型更加的具有魯棒性和泛化性。
(2) CNN模型構(gòu)建
????????在數(shù)據(jù)預(yù)處理之后,就需要開始構(gòu)建一個基本符合本實驗的CNN的算法模型了(包括詞嵌入層、卷積層、池化層和全連接層等,其中激活函數(shù)使用ReLU,損失函數(shù)使用交叉熵,優(yōu)化器使用Adam)。首先使用Keras的Sequential()方法定義一個可以按照層次結(jié)構(gòu)依次添加神經(jīng)網(wǎng)絡(luò)層的序貫?zāi)P?/strong>(這個模型容器在神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)中非常的方便),然后添加一個詞嵌入層 (Embedding Layer),將每個單詞的整數(shù)編碼映射為一個密集向量表示(本來此處是應(yīng)該使用預(yù)訓(xùn)練的詞嵌入矩陣的,它們是基于大型語料庫訓(xùn)練的,能夠更好表達(dá)單詞之間的語義關(guān)系,但是由于被百度網(wǎng)盤限速下載數(shù)據(jù)集實在太慢,就放棄了),在這一層,我們設(shè)置了詞匯表的大小為 25000(本來有十七萬多的詞袋,但是太大了實在是跑不動,截取前兩萬五的詞做個代表,之所以不用TDF-IDF來根據(jù)重要程度排序是因為在情感分析中有些出現(xiàn)頻率高的詞可能對文本的情感影響更大,所以就直接默認(rèn)按照出現(xiàn)頻率降序來排),每個單詞的嵌入維度為 150(根據(jù)ChatGPT的建議,從我們的數(shù)據(jù)集的大小出發(fā),選了幾個100到300維度的來試過幾次),輸入序列的最大長度為 280(在數(shù)據(jù)預(yù)處理時已經(jīng)說過了),這里的結(jié)果是直接基于Embedding層的隨機初始化的矩陣得出的,直接根據(jù)對應(yīng)的整數(shù)ID編號輸出(由于權(quán)重矩陣初始化的時候是隨機生成的,所以不能很好的把不同詞之間的不同關(guān)系表現(xiàn)出來,不過不用擔(dān)心,后面會使用反向傳播算法來更新這些權(quán)重矩陣)。
????????然后就是添加一維卷積層,在這里本實驗設(shè)置了128個卷積核,每個卷積核的大小是5(一開始設(shè)置少了,最后跑出來的效果很不理想,這里每個單個的卷積核中每個元素(就是大小是5就有5個元素)的維度在一開始是會自適應(yīng)詞向量的維度的,所以不用擔(dān)心維度不會匹配的情況,當(dāng)然如果是自己去單獨實現(xiàn)一個卷積的操作可能就需要自己去規(guī)定維度要相同了,這里使用的是現(xiàn)成的Keras中的一維卷積),這相當(dāng)于對每個樣本從前五個詞向量開始,與每個卷積核做點乘,然后在一步一步向后滑動,正常來說對每個樣本輸入來說這里會輸出一個由128個276維向量的組合特征圖,本實驗使用的激活函數(shù)為ReLU函數(shù)。激活函數(shù)是用來對神經(jīng)元的輸出進(jìn)行非線性變換的,即輸入大于零時就輸出它本身,小于零時就輸出零,可以防止過擬合以及提高運算速度,又可以防止梯度消失。
????????接下來就是利用池化層對卷積之后的結(jié)果進(jìn)行一個降維操作,這里我們使用的是最大池化操作,使用的是Keras的GlobalMaxPooling1D()來做最大池化操作,其原理是把卷積層輸出的特征圖的每個通道的最大值選取出來組成一個新的特征向量,從而達(dá)到降維的效果(這里之所以不用平均池化,是應(yīng)為最大池化會保留序列里面最顯著的特征,對情感分析來說這種最顯著的特征對文本的情感通常是由較大的影響的,而平均池化類似于一種平滑,會丟失這種顯著的特征所以在這里我們選擇使用最大池化操作),這個新的特征向量就是這個樣本最顯著的特征,就將作為池化層的輸出進(jìn)入到下一層。
????????接下來就是全連接層,就是把全連接層所有的神經(jīng)元都和池化層的輸出也就是全連接層的輸入相連,如果全連接層的輸入不是一維的特征向量,那么該特征向量將會被壓縮成一維向量再參與運算,如果是自己單獨實現(xiàn)這一層的話,而池化層輸出的又不是一維的特征向量的話這里就需要自己去實現(xiàn)向量維度的壓縮(池化層使用平均池化的話可能就會輸出多維的特征向量),這里的全連接運算過程其實也就是使用它每個神經(jīng)元的權(quán)重矩陣的轉(zhuǎn)置(這是為了確保連個矩陣滿足矩陣的乘積要求)和輸入的特征向量做一個簡易乘積運算。
????????在之后的Dropout層是一個作用于它前面的全連接層的防止過擬合的技術(shù),它可以使前面一層的神經(jīng)元隨機失活(注意這里不是真正意義上的失活,而是會以一定概率(這個概率是我們自己設(shè)置的)把前面一層的神經(jīng)元的輸出置零(所以并不會影響輸出的樣本的特征向量的長度),以此來防止過擬合,使模型不會過度的依賴某些特定的神經(jīng)元,讓模型的魯棒性更強)。
????????最后的就是整個卷積神經(jīng)網(wǎng)絡(luò)的輸出層,這個輸出層我們使用的是一個全連接層來實現(xiàn),由于做的只是二分類任務(wù),所以我們設(shè)置兩個神經(jīng)元,并使用softmax函數(shù)作為激活函數(shù)來使特征向量轉(zhuǎn)化為概率密度,再從兩個概率中輸出最大概率的那個分類(神經(jīng)網(wǎng)絡(luò)在訓(xùn)練的時候會保證輸出的概率分類的順序和驗證的標(biāo)簽分類順序一致),這兩個神經(jīng)元的長度還是和特征向量的長度自適應(yīng),而權(quán)重矩陣一開始也是隨機生成的對全連接層來說在Keras中默認(rèn)的是使用Glorot均勻分布(也稱為Xavier均勻分布)進(jìn)行初始化,偏置向量默認(rèn)初始化為0,主要就是根據(jù)神經(jīng)元的輸入和輸出個數(shù)來進(jìn)行隨機數(shù)范圍的限制(這里就不多做闡述了)。到這里模型的神經(jīng)元層基本就算是構(gòu)建完成了。
# 建立一個神經(jīng)網(wǎng)絡(luò)模型,一層層添加神經(jīng)元層
model = Sequential()
model.add(Embedding(25000, 150, input_length=max_len))
model.add(Conv1D(128, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
(3) 模型編譯和訓(xùn)練驗證
????????在構(gòu)建完一個模型之后,我們就需要對這個模型進(jìn)行編譯來指定優(yōu)化器(優(yōu)化器就是用于更新權(quán)重矩陣和偏置的、除此之外還有學(xué)習(xí)率等)、損失函數(shù)、和評估指標(biāo)等,本實驗使用的是Adam模型優(yōu)化器(主要是方便又可以在訓(xùn)練的過程中自適應(yīng)學(xué)習(xí)率),而我們所使用的損失函數(shù)是categorical_crossentropy(多類別交叉熵?fù)p失函數(shù)),它能夠直接衡量模型預(yù)測的概率分布和真實標(biāo)簽的概率分布的之間的差異,經(jīng)常和softmax一起使用。最后在編譯階段再設(shè)置一個評估指標(biāo),這里我們使用的是accuracy(準(zhǔn)確度)作為評估指標(biāo)。
????????再經(jīng)過模型編譯之后就是對模型進(jìn)行訓(xùn)練驗證了,但是在這里我們?yōu)榱烁玫姆乐褂?xùn)練過程中出現(xiàn)過擬合現(xiàn)象,還需要設(shè)置兩個Keras回調(diào)函數(shù)EarlyStopping(本實驗中將將它的檢測目標(biāo)定為驗證集上損失,其原理是當(dāng)驗證集上的損失不再下降的時候就提前終止訓(xùn)練防止過擬合,其中patience=3的意思是連續(xù)三個epoch的損失不再下降就結(jié)束訓(xùn)練) 和 ReduceLROnPlateau(它用于在驗證集損失不再下降時降低學(xué)習(xí)率,monitor='val_loss' 表示監(jiān)控驗證集損失,factor=0.2 表示每次降低學(xué)習(xí)率時將其乘以 0.2,patience=2 表示當(dāng)驗證集損失在連續(xù) 2 個 epoch 內(nèi)都沒有下降時,降低學(xué)習(xí)率,min_lr=0.0001 表示學(xué)習(xí)率的最小值為 0.0001)來動態(tài)調(diào)整訓(xùn)練中的學(xué)習(xí)率和檢測訓(xùn)練過程提前終止訓(xùn)練避免過擬合的現(xiàn)象出現(xiàn)。
????????在之后我們將進(jìn)行模型的訓(xùn)練及驗證直接使用Keras的fit方法對模型進(jìn)行訓(xùn)練。train_seq和train_labels是訓(xùn)練數(shù)據(jù)和標(biāo)簽,batch_size=128表示批大小為128,epochs=20表示訓(xùn)練20個epoch,validation_data所設(shè)置的test_seq和test_labels表示使用 test_seq和test_labels作為驗證數(shù)據(jù),callbacks=[early_stop, reduce_lr]表示在訓(xùn)練過程中使用early_stop和reduce_lr兩個回調(diào)函數(shù),verbose=0表示不輸出訓(xùn)練日志。在訓(xùn)練過程中,模型會在每個 epoch結(jié)束后計算在驗證數(shù)據(jù)上的損失和準(zhǔn)確度,并根據(jù)這些信息調(diào)整學(xué)習(xí)率或提前終止訓(xùn)練。訓(xùn)練完成后,返回一個History對象,其中包含了訓(xùn)練過程中的損失和評估指標(biāo)等信息。最后在輸出一下模型的評估結(jié)果就算是整體的實驗步驟結(jié)束了。
????????最后說明一下,本實驗使用了十折交叉驗證加多批次訓(xùn)練,就是說所有的訓(xùn)練數(shù)據(jù)被分成十份分別以以9:1的比例來進(jìn)行訓(xùn)練和驗證,總共進(jìn)行十次,而每次訓(xùn)練又將訓(xùn)練多個epoch(一般都會不到20個就會收斂),每個epoch又會被分成多個批次(每個批次的大小為128)分批進(jìn)行訓(xùn)練,這樣能夠加快訓(xùn)練速度并提高模型性能,通過在每個epoch中分批處理數(shù)據(jù),可以減少內(nèi)存占用并利用矩陣運算加速計算。
# 編譯剛剛建立的卷積神經(jīng)網(wǎng)絡(luò)模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 設(shè)置 EarlyStopping 和 ReduceLROnPlateau 來避免過擬合
early_stop = EarlyStopping(monitor='val_loss', patience=3)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=2, min_lr=0.0001)
# 訓(xùn)練以及驗證卷積神經(jīng)網(wǎng)絡(luò)模型的效果
history = model.fit(train_seq, tf.keras.utils.to_categorical(train_labels), batch_size=128, epochs=20, validation_data=(test_seq, tf.keras.utils.to_categorical(test_labels)), callbacks=[early_stop, reduce_lr], verbose=0)
四、實驗結(jié)果分析
1、模型的準(zhǔn)確性分析
????????從實驗的結(jié)果來看,我們一共進(jìn)行了十次(十折)整體的訓(xùn)練,每一折的訓(xùn)練都會輸出一幅accuracy的圖和loss圖,上面展示了每次訓(xùn)練截至之前的每一個epoch對應(yīng)的訓(xùn)練集和測試驗證集上的準(zhǔn)確度以及熵?fù)p失。從下面的部分結(jié)果圖來看,每次訓(xùn)練基本都會在第二個epoch就會收斂了,超過這個epoch模型就出現(xiàn)了過擬合的現(xiàn)象,而在這十次訓(xùn)練中,基本上模型的最終的準(zhǔn)確度都穩(wěn)定在97%,算是一個比較高的準(zhǔn)確度了。如下圖(部分圖例):
2、模型評估指標(biāo)分析
????????由模型最終生成的評估結(jié)果分析可知本實驗所構(gòu)建的神經(jīng)網(wǎng)絡(luò)模型在每一折的訓(xùn)練中的正面和負(fù)面的文本的準(zhǔn)確率都幾乎維持在97%、98%左右,而且召回率和F1-score也差不多維持在這個水準(zhǔn),都是比較好的,而且模型最后的準(zhǔn)確度也在97%左右,具體的生成圖例如下所示(部分圖例):
?模型最終的準(zhǔn)確度和損失:
五、實驗結(jié)論
????????使用卷積神經(jīng)網(wǎng)絡(luò)來進(jìn)行文本情感分析可以在訓(xùn)練時進(jìn)行并行化,也就是可以并行訓(xùn)練和執(zhí)行;可以經(jīng)過多層的疊加實現(xiàn)和RNN一樣的長序列依賴。但是,使用卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行文本情感分析的模型可解釋性不強,在調(diào)優(yōu)模型的時候,很難根據(jù)訓(xùn)練的結(jié)果去針對性地調(diào)整具體的特征。
????????綜上所述,此外如果還需要提升這個模型的性能的話,可以增加神經(jīng)元的個數(shù),也可以通過增大詞袋的大小,也可以調(diào)整規(guī)定單個詞向量的維度,或者使用其他的模型優(yōu)化器來達(dá)到更好的效果。
【注】:深度模型的針對性可能有時候有些強,這和訓(xùn)練的數(shù)據(jù)集有關(guān),即便有時候防止了模型的過擬合,但是數(shù)據(jù)集的來源單一,可能最后的泛化性都不會有那么好,對該來源的數(shù)據(jù)可能預(yù)測效果好,但是其它來源就不一定了;就比如說我所使用的是一些微博評論的數(shù)據(jù)集,導(dǎo)致的結(jié)果就是對微博評論這種類型的文本的預(yù)測效果好一些,對其他領(lǐng)域的可能就不太理想,它對符合它訓(xùn)練的數(shù)據(jù)集的那種語法、語言模式的文本的效果比較好,對其他的可能就不是很理想,所以各位讀者在自行測試的時候可能就會發(fā)現(xiàn)有時候?qū)τ谀爿斎氲奈谋?,模型給出的結(jié)果不太好。
本實驗的代碼倉庫位置及數(shù)據(jù)集都在倉庫的CNN目錄下,倉庫鏈接如下:
? ? ? ? GitHub - XSJWF/MachineLearning: 一些機器學(xué)習(xí)分入門算法實現(xiàn)分享
或者下面這Gitee的倉庫:
? ? ? ??Gitee倉庫文章來源:http://www.zghlxwxcb.cn/news/detail-442084.html
本篇文章到此結(jié)束,感謝各位讀者的閱讀!文章來源地址http://www.zghlxwxcb.cn/news/detail-442084.html
到了這里,關(guān)于【深度學(xué)習(xí)&NLP】基于卷積神經(jīng)網(wǎng)絡(luò)(CNN)實現(xiàn)中文文本情感分析(分類)附代碼以及數(shù)據(jù)集鏈接的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!