LSTM實現中文文本情感分析


1. 背景介紹

文本情感分析是在文本分析領域的典型任務,實用價值很高。本模型是第一個上手實現的深度學習模型,目的是對深度學習做一個初步的了解,並入門深度學習在文本分析領域的應用。在進行模型的上手實現之前,已學習了吳恩達的機器學習和深度學習的課程,對理論有了一定的了解,感覺需要來動手實現一下了。github對應網址https://github.com/ble55ing/LSTM-Sentiment_analysis

LSTM(Long Short-Term Memory)是長短期記憶網絡,在自然語言處理的領域有着較好的效果。因此本文使用LSTM網絡來幫助進行文本情感分析。本文將從分詞、向量化和模型訓練三個方面對所訓練的模型進行講解,本文所實現的模型達到了在測試集99%的准確率。

2. 中文文本分詞

首先需要得到兩個文檔,即積極情感的文本和消極情感的文本,作為訓練用到的數據集,積極和消極的各8000條左右。然后程序在載入了這兩個文本的內容后,需要進行一部分的預處理,而預處理部分中最關鍵的就是分詞。

2.1 分詞 or 分字

一般在中文文本的分詞處理上,最常使用的就是jieba分詞,因此在一開始訓練模型的時候,也是使用的jieba分詞。但后來感覺效果並不太好,最好的時候准確率也就達到92%,而且存在較為嚴重的過擬合問題(同時測試集准確率達到99%)。因此去和搞過一段時間的自然語言處理的大佬討論了一下,大佬給出的建議是直接分字,因為所收集的訓練集還是相對來說少了一點,分詞完會導致訓練集縮小,再進行embedding(數據降維)之后詞表更小了,就不太方便獲取文本間的內在聯系。

因而最后分詞時比較了直接分字和jieba分詞的效果,最終相比之下還是直接分字的效果會更好一些(大佬就是大佬),所以選用了直接分字。直接分字的思路是將中文單字分為一個字,英文單詞分為一個字。這里需要考慮到utf-8編碼,從而正確的對文本進行分字。

2.2 去停用詞

停用詞:一些在文本中相對來說對語義的影響不明顯的詞,在分詞的同時可以將這些停用詞去掉,使得文本分類的效果更好。但同樣的由於采集到的樣本比較小的原因,在進行了嘗試之后還是沒有使用去停用詞。因為雖然對語義的影響不大,但還是存在着一些情感在里頭,這部分信息也有一定的意義。

2.3 utf-8編碼的格式

utf-8的編碼格式為:

如果該字符占用一個字節,那么第一個位為0。

如果該字符占用n個字節(4>=n>1),那么第一個字節的前n位為1,第n+1位為0。

也就是不會出現第一個字符的第一個字節為1,第二個字節為0的情況。

2.4 實現

#將中文分成一個一個的字
def onecut(doc):
    #print len(doc),ord(doc[0])
    #print doc[0]+doc[1]+doc[2]
    ret = [];
    i=0
    while i < len(doc):
        c=""
        #utf-8的編碼格式,小於128的為1個字符,n個字符的化第一個字符的前n+1個字符是1110
        #print i,ord(doc[i])
        if ord(doc[i])>=128 and ord(doc[i])<192:
            print ord(doc[i])
            assert 1==0#所以其實這里是不應該到達的
            c = doc[i]+doc[i+1];
            i=i+2
            ret.append(c)
        elif ord(doc[i])>=192 and ord(doc[i])<224:
            c = doc[i] + doc[i + 1];
            i = i + 2
            ret.append(c)
        elif ord(doc[i])>=224 and ord(doc[i])<240:
            c = doc[i] + doc[i + 1] + doc[i + 2];
            i = i + 3
            ret.append(c)
        elif ord(doc[i])>=240 and ord(doc[i])<248:
            c = doc[i] + doc[i + 1] + doc[i + 2]+doc[i + 3];
            i = i + 4
            ret.append(c)
        else :
            assert ord(doc[i])<128
            while ord(doc[i])<128:
                c+=doc[i]
                i+=1
                if (i==len(doc)) :
                    break
                if doc[i] is " ":
                    break;
                elif doc[i] is ".":
                    break;
                elif doc[i] is ";":
                    break;
            ret.append(c)
    return ret

3. 文本向量化

接下來是需要對分完字的文本進行向量化,這里使用到了word2Vec,一款文本向量化的常用工具。主要就是解決將語言文本處理成緊湊的向量。簡單的文本轉化往往是相當稀疏的矩陣,即One-Hot編碼。轉換的文本向量就是把文本中所含的詞的編號的位置置為1.這樣的編碼方式顯然是不適合進行深度學習模型訓練的,因為數據過於離散了。因此,需要將向量維數進行縮減。word2Vec就能夠較好的解決這個問題。

3.1 Word2Vec

Word2Vec能夠將文本生成相對緊湊的向量,這個過程稱為詞嵌入(embedding),其本身也是一個神經網絡模型。訓練完成之后,就能夠得到每個詞所對應的低維向量了。使用這個低維向量來進行訓練,能夠達到較好的訓練效果。

3.2 實現

def word2vec_train(X_Vec):
    model_word = Word2Vec(size=voc_dim,
                     min_count=min_out,
                     window=window_size,
                     workers=cpu_count,
                     iter=5)
    model_word.build_vocab(X_Vec)
    model_word.train(X_Vec, total_examples=model_word.corpus_count, epochs=model_word.iter)
    model_word.save('../model/Word2vec_model.pkl')

    input_dim = len(model_word.wv.vocab.keys()) + 1 #下標0空出來給不夠10的字
    embedding_weights = np.zeros((input_dim, voc_dim)) 
    w2dic={}
    for i in range(len(model_word.wv.vocab.keys())):
        embedding_weights[i+1, :] = model_word [model_word.wv.vocab.keys()[i]]
        w2dic[model_word.wv.vocab.keys()[i]]=i+1
    return input_dim,embedding_weights,w2dic

4. 模型訓練

4.1 激活函數

LSTM模型的訓練,其激活函數選用了Softsign,是一個對於LSTM來說的時候比tanh更加合適的激活函數。

4.2 模型層數

在全連接層數的選取上,本來是使用了一層的全連接層,0.5的dropout,但在一開始的分詞方式下,產生了較為嚴重的過擬合情況,因此就嘗試着再添加一層Relu的全連接層,0.5的dropout,效果是確實可以解決過擬合的問題,但並沒有提升准確率。因此就還是回到了一層全連接層的狀況。相比之下,一層比兩層的訓練逼近速度快得多。

4.3 損失函數

損失函數的選取:這一部分嘗試了三個損失函數,mse,hinge和binary_crossentropy,最終選用了binary_crossentropy。

mse這個損失函數相對普通,hingo和binary_crossentropy是較為專用於二分類問題的,而binary_crossentropy還往往與sigmoid作為激活函數一同使用。也可能是在使用hinge的時候沒有用對激活函數吧。

4.4 評估標准

一開始的時候,評估標准定的是只有准確率(acc),然后准確率一直上不去。后來添加了平均絕對誤差(mae,mean_absolute_error),准確率一下子就上去了,很有意思。

5. 總結

總的來說,自己搭模型調參的過程還是很必要的一個過程,內心很煎熬,沒有自動調參的工具嗎。。能夠調出一個效果不錯的模型還是很開心的。感覺在深度學習這塊還是有很多的經驗在里面,是需要花些時間的。

附上結果圖一張。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM