使用TensorFlow進行中文自然語言處理的情感分析


1 TensorFlow使用

分析流程:

1.1  使用gensim加載預訓練中文分詞embedding

 加載預訓練詞向量模型:https://github.com/Embedding/Chinese-Word-Vectors/

from gensim.models import KeyedVectors
cn_model = KeyedVectors.load_word2vec_format('H:/詞向量/word+Ngram/sgns.zhihu.bigram', binary=False)

 

查看詞語的向量模型表示: 維度為300

 

 詞語相似度:向量余弦值

 

最相似的詞:

 

1.2 訓練樣本預料

  准備一個訓練集,4000個酒店評論,其中2000條為pos積極的,2000條為消極的,每條評論放在一個文件中。

 1)文本預處理,分詞、索引化

讀取數據

import os
import re

import jieba
from gensim.models import KeyedVectors

cn_model = KeyedVectors.load_word2vec_format('H:/word+Ngram/sgns.zhihu.bigram', binary=False)

baseDir = "H:/譚松波老師8++酒店評論++語料/utf-8/4000"
pos_txts = os.listdir("H:/譚松波老師8++酒店評論++語料/utf-8/4000/pos")
neg_txts = os.listdir("H:/bishe/NLP/訓練集/譚松波老師8++酒店評論++語料/utf-8/4000/neg")

train_text_orig = []

for i in range(len(pos_txts)):
    with open(baseDir+"/pos/"+pos_txts[i], errors="ignore", encoding="utf-8") as f:
        text = f.read().strip()
        train_text_orig.append(text)
        f.close()
for i in range(len(neg_txts)):
    with open(baseDir+"/neg/"+neg_txts[i], errors="ignore", encoding="utf-8") as f:
        text = f.read().strip()
        train_text_orig.append(text)
        f.close()

 

分詞,建立索引:

# [[句子詞索引],[]]
train_tokens = []
for text in train_text_orig:
    # 去掉標點符號
    text = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、~@#¥%……&*()]+", "", text)
    # 結巴分詞
    cut = jieba.cut(text)
    # 結巴分詞結果為一個生成器
    cut_list = [i for i in cut]
    for i, word in enumerate(cut_list):
        try:
            # 將詞轉換成索引
            cut_list[i] = cn_model.vocab[word].index
        except KeyError:
            cut_list[i] = 0
    train_tokens.append(cut_list)

 

 

2)文本長度標准化:

長度參差不齊,我們需要將長度標准化,方便模型進行訓練,如果長度太短,會損失太多的信息,而長度太長會浪費太多計算資源
所以說我們要取一個這種的方案,讓這個長度基本上涵蓋所有的訓練樣本,又不損失太多的信息

樣本長度分布圖:

# 看一下樣本長度分布圖
import matplotlib.pyplot as plt

plt.hist(num_tokens, bins=100)
plt.xlim(0, 400)
plt.ylabel("number of tokens")
plt.xlabel("length of tokens")
plt.title("Distribution of tokens length")
plt.show()

 

 

 

# 取tokens平均值加上兩個tokens的標准差
# 假設tokens長度的分布符合正太分布,則max_tokens這個值可以涵蓋95%左右的樣本
max_tokens = np.mean(num_tokens) + 2 * np.std(num_tokens)

 

 

 

# 取tokens的長度為236時,大約95%左右的樣本被涵蓋
# 對於長度不足的進行padding,過長的進行修剪
np.sum(num_tokens<max_tokens)/len(num_tokens)

 

 

反tokenize

def reverse_token(tokens):
    '''
    將索引化的句子還原
    :param tokens: 句子 [詞語,..]
    :return:
    '''
    text = ""
    for i in tokens:
        if i!=0:
            text = text+cn_model.index2word[i]
        else:
            text =text+" "
    return text

 

 

3)准備Emdedding Matrix(詞向量矩陣)

    根據Keras的要求,我們需要准一個維度為(numwords, embeddingdim)的矩陣,num words代表我們使用的詞匯的數量,emdedding dimension在我們預訓練詞向量模型中是300,每個詞匯都用長度為300的向量表示(例如: 較好 ->[  0.056964, -0.127308, -0.118041,...]),注意詞向量矩陣是作為訓練模型的工具,

# 初始化詞向量矩陣-embedding matrix(只用前50000個詞)
num_words = 50000
embedding_matrix = np.zeros((num_words, embedding_dim))
# 維度為(50000, 300)的矩陣
for i in range(num_words):
    embedding_matrix[i,:]=cn_model[cn_model.index2word[i]]  # 將詞向量賦值到詞向量矩陣中
embedding_matrix = embedding_matrix.astype("float32")

# 檢查賦值是否正確
np.sum(cn_model[cn_model.index2word[333]]==embedding_matrix[333])

 

 詞向量矩陣維度:

4) padding(填充)和truncating(修剪)

  我們把問轉換成token(索引)后,每一串索引的長度都不相等,所以為了方便模型的訓練我們需要將索引的長度標准化,上面我們選擇了使用236這個可以涵蓋95%的訓練樣本的長度,接下來進行padding和truncating,我們一個采用‘pre’的方法,在文本索引的前面填充0。

# 返回一個numpy array
train_pad = pad_sequences(train_tokens, maxlen=max_tokens, padding="pre", truncating="pre")

 

 准備目標向量:

# 准備target向量,前2000個位1,后2000個位0
train_target = np.concatenate((np.ones(2000), np.zeros(2000))) 

 

訓練樣本和測試樣本分離,使用90%的樣本來做訓練,10%的樣本用來做測試:

# 進行訓練和測試樣本的分割
from sklearn.model_selection import train_test_split
# 90用作訓練,正面和負面打亂
X_train, X_test, y_train, y_test = train_test_split(train_pad, train_target, test_size=0.1, random_state=12)

 

 

 

5)使用Keras搭建神經網絡模型(LSTM),模型的第一層是Embedding層

 

 

end


免責聲明!

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



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