畢業(yè)設(shè)計 深度學(xué)習(xí)新聞算法研究與實現(xiàn)
0 前言
?? 這兩年開始畢業(yè)設(shè)計和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點,往往達不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長自己做的項目系統(tǒng)達不到老師的要求。
為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長分享優(yōu)質(zhì)畢業(yè)設(shè)計項目,今天要分享的是
?? ?機器學(xué)習(xí)新聞算法實現(xiàn)
??學(xué)長這里給一個題目綜合評分(每項滿分5分)
工作量:3分
創(chuàng)新點:3分
畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個人主頁
https://space.bilibili.com/33886978
簡介
新聞分類課題是在算法類畢業(yè)設(shè)計中比較熱門的, 本質(zhì)上是屬于自然語言分類, 可以使用機器學(xué)習(xí)算法去處理, 也可以使用深度學(xué)習(xí)算法去處理.
基本步驟如下 :
文本數(shù)據(jù)采集 --> 選擇訓(xùn)練算法(機器學(xué)習(xí)/深度學(xué)習(xí)) --> 進行訓(xùn)練 ?--> 檢效果.
本文章博主將介紹:
從頭開始實踐中文短文本分類
運用多種機器學(xué)習(xí)(深度學(xué)習(xí) + 傳統(tǒng)機器學(xué)習(xí))方法比較短文本分類處理過程與結(jié)果差別
參與及比較算法
使用下面的算法來進行文本分類, 并對最后分類準(zhǔn)確率進行比較
CNN 、 CNN + word2vec
LSTM 、 LSTM + word2vec
MLP(多層感知機)
樸素貝葉斯
KNN
SVM
SVM + word2vec 、SVM + doc2vec
先說結(jié)論

引入預(yù)訓(xùn)練的 word2vec 模型會給訓(xùn)練帶來好處,具體來說:(1)間接引入外部訓(xùn)練數(shù)據(jù),防止過擬合;(2)減少需要訓(xùn)練的參數(shù)個數(shù),提高訓(xùn)練效率
LSTM 需要訓(xùn)練的參數(shù)個數(shù)遠小于 CNN,但訓(xùn)練時間大于 CNN。CNN 在分類問題的表現(xiàn)上一直很好,無論是圖像還是文本;而想讓 LSTM 優(yōu)勢得到發(fā)揮,首先讓訓(xùn)練數(shù)據(jù)量得到保證
將單詞在 word2vec 中的詞向量加和求平均獲得整個句子的語義向量的方法看似 naive 有時真挺奏效,當(dāng)然僅限于短句子,長度 100 以內(nèi)應(yīng)該問題不大
機器學(xué)習(xí)方法萬千,具體選擇用什么樣的方法還是要取決于數(shù)據(jù)集的規(guī)模以及問題本身的復(fù)雜度,對于復(fù)雜程度一般的問題,看似簡單的方法有可能是墜吼地
實現(xiàn)過程
數(shù)據(jù)爬取
爬蟲這里不公開提供, 爬取的是各大新聞網(wǎng)站數(shù)據(jù)
數(shù)據(jù)預(yù)處理
將下載的原始數(shù)據(jù)進行轉(zhuǎn)碼,然后給文本標(biāo)類別的標(biāo)簽,然后制作訓(xùn)練與測試數(shù)據(jù),然后控制文本長度,分詞,去標(biāo)點符號
哎,坑多,費事,比較麻煩
首先,下載下來是 xml 格式,并且是 GBK (萬惡之源)編碼,需要轉(zhuǎn)成 UTF8,并整理成 json 方便處理。原始數(shù)據(jù)長這個樣:

對成功標(biāo)出來的15個類的新聞,統(tǒng)計一下類別的分布,結(jié)果如下:

分布比較不均,第 14 類和第 15 類的新聞很少,另外第 8 類和第 11 類一個新聞也沒有
所以最后選了剩下的11個類,每個類抽2000個新聞,按4:1分成訓(xùn)練與測試,如圖

上一步選出來的訓(xùn)練新聞長這樣,因為考慮到新聞標(biāo)題的意義重大,這里就將新聞標(biāo)題和新聞內(nèi)容接到一起,用空格隔開,然后截取每條新聞的前 100 個字

最后得到以下結(jié)果文件:(1)新聞文本數(shù)據(jù),每行 1 條新聞,每條新聞由若干個詞組成,詞之間以空格隔開,訓(xùn)練文本 17600 行,測試文本 4324 行;(2)新聞標(biāo)簽數(shù)據(jù),每行 1 個數(shù)字,對應(yīng)這條新聞所屬的類別編號,訓(xùn)練標(biāo)簽 17600行,測試標(biāo)簽 4324 行
CNN文本分類
深度學(xué)習(xí)用的 keras 工具,操作簡單易懂,模型上手飛快,居家旅行必備。keras 后端用的 Tensorflow,雖然用什么都一樣
首先一些先設(shè)定一些會用到的參數(shù)
MAX_SEQUENCE_LENGTH = 100 # 每條新聞最大長度
EMBEDDING_DIM = 200 # 詞向量空間維度
VALIDATION_SPLIT = 0.16 # 驗證集比例
TEST_SPLIT = 0.2 # 測試集比例
第一步先把訓(xùn)練與測試數(shù)據(jù)放在一起提取特征,使用 keras 的 Tokenizer 來實現(xiàn),將新聞文檔處理成單詞索引序列,單詞與序號之間的對應(yīng)關(guān)系靠單詞的索引表 word_index 來記錄,這里從所有新聞中提取到 65604 個單詞,比如 [茍,國家,生死] 就變成了 [1024, 666, 233] ;然后將長度不足 100 的新聞用 0 填充(在前端填充),用 keras 的 pad_sequences 實現(xiàn);最后將標(biāo)簽處理成 one-hot 向量,比如 6 變成了 [0,0,0,0,0,0,1,0,0,0,0,0,0],用 keras 的 to_categorical 實現(xiàn)
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
import numpy as np
tokenizer = Tokenizer()
tokenizer.fit_on_texts(all_texts)
sequences = tokenizer.texts_to_sequences(all_texts)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)
labels = to_categorical(np.asarray(all_labels))
print('Shape of data tensor:', data.shape)
print('Shape of label tensor:', labels.shape)
再將處理后的新聞數(shù)據(jù)按 6.4:1.6:2 分為訓(xùn)練集,驗證集,測試集
p1 = int(len(data)*(1-VALIDATION_SPLIT-TEST_SPLIT))
p2 = int(len(data)*(1-TEST_SPLIT))
x_train = data[:p1]
y_train = labels[:p1]
x_val = data[p1:p2]
y_val = labels[p1:p2]
x_test = data[p2:]
y_test = labels[p2:]
print 'train docs: '+str(len(x_train))
print 'val docs: '+str(len(x_val))
print 'test docs: '+str(len(x_test))
然后就是搭建模型,首先是一個將文本處理成向量的 embedding 層,這樣每個新聞文檔被處理成一個 100 x 200 的二維向量,100 是每條新聞的固定長度,每一行的長度為 200 的行向量代表這個單詞在空間中的詞向量。下面通過 1 層卷積層與池化層來縮小向量長度,再加一層 Flatten 層將 2 維向量壓縮到 1 維,最后通過兩層 Dense(全連接層)將向量長度收縮到 12 上,對應(yīng)新聞分類的 12 個類(其實只有 11 個類,標(biāo)簽 0 沒有用到)。
from keras.layers import Dense, Input, Flatten, Dropout
from keras.layers import Conv1D, MaxPooling1D, Embedding
from keras.models import Sequential
model = Sequential()
model.add(Embedding(len(word_index) + 1, EMBEDDING_DIM, input_length=MAX_SEQUENCE_LENGTH))
model.add(Dropout(0.2))
model.add(Conv1D(250, 3, padding='valid', activation='relu', strides=1))
model.add(MaxPooling1D(3))
model.add(Flatten())
model.add(Dense(EMBEDDING_DIM, activation='relu'))
model.add(Dense(labels.shape[1], activation='softmax'))
model.summary()
網(wǎng)絡(luò)模型如下

實驗結(jié)果如下

準(zhǔn)確度 0.81459521
擁有11個分類的問題達到這個準(zhǔn)確度,應(yīng)該也不錯(易滿足)。并且搜狗給的數(shù)據(jù)本來也不是很好(甩鍋)??梢钥吹皆谟?xùn)練集上的準(zhǔn)確度達到了 0.88,但是測試集上的準(zhǔn)確度只有 0.81,說明還是有些過擬合。另外,整個模型需要訓(xùn)練的參數(shù)接近 1500 萬,其中 1300 萬都是 embedding 層的參數(shù),說明如果利用 word2vec 模型替換 embedding 層,解放這 1300 萬參數(shù),肯定會讓訓(xùn)練效率得到提高
畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個人主頁
https://space.bilibili.com/33886978