基於機器學習的情感分析方法

2021-02-14 數據挖掘與AI算法
上次課程我們介紹了基於情感詞典的情感分析方法,本節課我們嘗試基於機器學習的情感分析方法,以電影中文文本情感分析為例,最常見的就是對電影評論數據進行情感分類,如積極情感(positive)、消極情感(negative)等。而目前可以用來處理這類問題的機器學習模型有很多,如樸素貝葉斯、邏輯回歸、SVM、CNN等等,本文採用深度學習TextCNN模型進行電影評論數據的情感分類,下面看其具體實現的過程。

首先,介紹下本次處理的數據集,數據集包括:

訓練集。包含約20000條中文電影評論,其中積極與消極評論各10000條左右。

驗證集 。包含約6000條中文電影評論,其中積極與消極評論各3000條左右。

測試集。包含約360條中文電影評論,其中積極與消極評論各180條左右。

導入本次訓練所需要的模塊

import gensimimport torchimport torch.nn as nnimport torch.nn.functional as Fimport numpy as npfrom collections import Counterfrom torch.utils.data import TensorDataset,DataLoader


1、數據預處理

(1)預訓練詞向量,本文使用的是中文維基百科詞向量word2vec,構建詞彙表並存儲,形如{word: id}:

def build_word2id(file, save_to_path=None):"""    :file: word2id保存地址    :save_to_path: 保存訓練語料庫中的詞組對應的word2vec到本地    :return: None    """    word2id = {'_PAD_': 0}    path = ['./Dataset/train.txt', './Dataset/validation.txt']
for _path in path:with open(_path, encoding='utf-8') as f:for line in f.readlines(): sp = line.strip().split()for word in sp[1:]:if word not in word2id.keys(): word2id[word] = len(word2id)if save_to_path: with open(file, 'w', encoding='utf-8') as f:for w in word2id: f.write(w+'\t') f.write(str(word2id[w])) f.write('\n')
return word2id

下面是函數調用後的結果:

(2)基於預訓練的word2vec構建訓練語料中所含詞語的word2vec:

def build_word2vec(fname, word2id, save_to_path=None):"""    :fname: 預訓練的word2vec    :word2id: 語料文本中包含的詞彙集    :save_to_path: 保存訓練語料庫中的詞組對應的word2vec到本地    :return: 語料文本中詞彙集對應的word2vec向量{id: word2vec}    """    n_words = max(word2id.values()) + 1    model = gensim.models.KeyedVectors.load_word2vec_format(fname, binary=True)    word_vecs = np.array(np.random.uniform(-1., 1., [n_words, model.vector_size]))for word in word2id.keys():try:            word_vecs[word2id[word]] = model[word]except KeyError:passif save_to_path:with open(save_to_path, 'w', encoding='utf-8') as f:for vec in word_vecs:                vec = [str(w) for w in vec]                f.write(' '.join(vec))                f.write('\n')return word_vecs

下面是函數調用結果:

(3)將分類類別對應為數值並以詞典方式保存{pos:0, neg:1}:

def cat_to_id(classes=None):"""    :classes: 分類標籤;默認為0:pos, 1:neg    :return: {分類標籤:id}    """if not classes:        classes = ['0', '1']    cat2id = {cat: idx for (idx, cat) in enumerate(classes)}return classes, cat2id

(4)加載語料庫:train/dev/test:

def load_corpus(path, word2id, max_sen_len=50):"""    :path: 樣本語料庫的文件    :return: 文本內容contents,以及分類標籤labels(onehot形式)    """    _, cat2id = cat_to_id()    contents, labels = [], []with open(path, encoding='utf-8') as f:for line in f.readlines():            sp = line.strip().split()            label = sp[0]            content = [word2id.get(w, 0) for w in sp[1:]]            content = content[:max_sen_len]if len(content) < max_sen_len:                content += [word2id['_PAD_']] * (max_sen_len - len(content))            labels.append(label)            contents.append(content)    counter = Counter(labels)    print('總樣本數為:%d' % (len(labels)))    print('各個類別樣本數如下:')for w in counter:        print(w, counter[w])
contents = np.asarray(contents) labels = np.array([cat2id[l] for l in labels])
return contents, labels

下面是具體的函數調用結果:

經過數據預處理,最終數據的格式如下:

x: [1434, 5454, 2323, ..., 0, 0, 0]

y: [1]

x為構成一條語句的單詞所對應的id。y為類別: pos(積極):0, neg(消極):1。

2、構建模型

構建TextCNN模型,模型結構如下圖所示:

模型包括詞嵌入層、卷積層、池化層和全連接層。TextCNN模型與CNN模型結構類似,具體可回顧老shi前面介紹CNN模型的文章 利用Tensorflow2.0實現卷積神經網絡CNN

(1)配置模型相關參數:

class CONFIG():    update_w2v = True           # 是否在訓練中更新w2v    vocab_size = 58954          # 詞彙量,與word2id中的詞彙量一致    n_class = 2                 # 分類數:分別為pos和neg    embedding_dim = 50          # 詞向量維度    drop_keep_prob = 0.5        # dropout層,參數keep的比例    num_filters = 256           # 卷積層filter的數量    kernel_size = 3             # 卷積核的尺寸    pretrained_embed = word2vec # 預訓練的詞嵌入模型

(2)構建TextCNN模型:

class TextCNN(nn.Module):def __init__(self, config):super(TextCNN, self).__init__()        update_w2v = config.update_w2v        vocab_size = config.vocab_size        n_class = config.n_class        embedding_dim = config.embedding_dim        num_filters = config.num_filters        kernel_size = config.kernel_size        drop_keep_prob = config.drop_keep_prob        pretrained_embed = config.pretrained_embed
# 使用預訓練的詞向量self.embedding = nn.Embedding(vocab_size, embedding_dim)self.embedding.weight.data.copy_(torch.from_numpy(pretrained_embed))self.embedding.weight.requires_grad = update_w2v# 卷積層self.conv = nn.Conv2d(1,num_filters,(kernel_size,embedding_dim))# Dropoutself.dropout = nn.Dropout(drop_keep_prob)# 全連接層self.fc = nn.Linear(num_filters, n_class)
def forward(self, x): x = x.to(torch.int64) x = self.embedding(x) x = x.unsqueeze(1) x = F.relu(self.conv(x)).squeeze(3) x = F.max_pool1d(x, x.size(2)).squeeze(2) x = self.dropout(x) x = self.fc(x)return x


3、訓練模型

(1)設置超參數:

config = CONFIG()          # 配置模型參數learning_rate = 0.001      # 學習率     batch_size = 32            # 訓練批量epochs = 4                 # 訓練輪數model_path = None          # 預訓練模型路徑verbose = True             # 列印訓練過程device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')print(device)

(2)加載訓練數據:

# 混合訓練集和驗證集contents = np.vstack([train_contents, val_contents])labels = np.concatenate([train_labels, val_labels])
# 加載訓練用的數據train_dataset = TensorDataset(torch.from_numpy(contents).type(torch.float), torch.from_numpy(labels).type(torch.long))train_dataloader = DataLoader(dataset = train_dataset, batch_size = batch_size, shuffle = True, num_workers = 2)

(3)模型訓練:

def train(dataloader):
# 配置模型,是否繼續上一次的訓練 model = TextCNN(config)if model_path: model.load_state_dict(torch.load(model_path)) model.to(device)
# 設置優化器 optimizer = torch.optim.Adam(model.parameters(), lr = learning_rate)
# 設置損失函數 criterion = nn.CrossEntropyLoss()
# 定義訓練過程for epoch in range(epochs):for batch_idx, (batch_x, batch_y) in enumerate(dataloader): batch_x, batch_y = batch_x.to(device), batch_y.to(device) output = model(batch_x) loss = criterion(output, batch_y)
if batch_idx % 200 == 0 & verbose: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch+1, batch_idx * len(batch_x), len(dataloader.dataset),100. * batch_idx / len(dataloader), loss.item()))
optimizer.zero_grad() loss.backward() optimizer.step()
# 保存模型 torch.save(model.state_dict(), 'model.pth')

下面是具體模型訓練結果:

4、測試模型

測試模型在測試集的準確率:

(1)設置超參數

model_path = 'model.pth'   # 模型路徑batch_size = 32            # 測試批量大小

(2)加載測試集

test_dataset = TensorDataset(torch.from_numpy(test_contents).type(torch.float),                             torch.from_numpy(test_labels).type(torch.long))test_dataloader = DataLoader(dataset = test_dataset, batch_size = batch_size,                             shuffle = False, num_workers = 2)

(3)測試模型在測試集上的準確率:

def predict(dataloader):
# 讀取模型 model = TextCNN(config) model.load_state_dict(torch.load(model_path)) model.eval() model.to(device)
# 測試過程 count, correct = 0, 0for _, (batch_x, batch_y) in enumerate(dataloader): batch_x, batch_y = batch_x.to(device), batch_y.to(device) output = model(batch_x) correct += (output.argmax(1) == batch_y).float().sum().item() count += len(batch_x)
# 列印準確率 print('test accuracy is {:.2f}%.'.format(100*correct/count))

結果可以看出,在測試集上TextCNN模型的準確率為85.37%,在文本分類模型中已經算是非常不錯的準確率,說明該模型在處理中文文本情感分類問題方面表現還是非常優異的。好了,本節課到此,有興趣學習更多機器學習方面知識的同學,可以持續關注老shi的公眾號文章,了解更多乾貨內容,感謝大家的支持!

相關焦點

  • 文本情感分析:讓機器讀懂人類情感
    在中文方面,大連理工大學的情感詞彙本體 將情感分為七個基本大類和二十一個小類,收錄情感詞語27466條。可以看到,人工構建詞典需要較大的代價,規模也會受限。(人們開始研究自動構建情感詞典的方法,已有方法一般分為兩種:基於詞典資源和基於語料庫的方法。
  • 「情感計算」讓機器也可以察言觀色 它是怎麼做到的?
    在近日中國科協發布的12個領域60個重大問題中,人機情感交互位列其中。「無情感不智能」已經成為眾多研究者的共識。 日前,在杭州舉行的第七屆UCAN用戶體驗設計論壇上,阿里巴巴人機自然交互實驗室聯合達摩院機器智能技術實驗室和浙江大學推出了一款可以基於圖文內容自動生成短視頻的人工智慧Aliwood。
  • Facebook基於機器學習的應用程式
    原文連結:http://aiehive.com/facebooks-human-like-learning-applications/研究人員越來越傾向用機器學習的方法來解決現實世界的問題
  • 專欄 | 情感計算是人機互動核心?談深度學習在情感分析中的應用
    其中針對中文語境裡人機互動中的情感、情緒識別與理解,竹間智能已經做了許多有益的探索,特別是如何利用情感、情緒分析,來幫助機器人實現對「對話意圖」與「深層語義」的更好理解。本文將梳理一下情感計算在人機互動中的價值,同時分享一些情感分析的工具與方法。希望對從事人機互動研究的朋友們有所啟發。
  • 就喜歡看綜述論文:情感分析中的深度學習
    近年來,深度學習有了突破性發展,NLP 領域裡的情感分析任務逐漸引入了這種方法,並形成了很多業內最佳結果。本文中,來自領英與伊利諾伊大學芝加哥分校的研究人員對基於深度學習的情感分析研究進行了詳細論述。情感分析或觀點挖掘是對人們對產品、服務、組織、個人、問題、事件、話題及其屬性的觀點、情感、情緒、評價和態度的計算研究。該領域的開始和快速發展與社交媒體的發展相一致,如評論、論壇、博客、微博、推特和社交網絡,因為這是人類歷史上第一次擁有如此海量的以數字形式記錄的觀點數據。
  • 情感計算:讓機器更加智能
    人類的情感機制也使我們能夠完成太難編程或難以讓當前機器學習的任務 [1]。例如,我們的恐懼情緒使我們能夠意識到危險並保持安全。我們感知他人的情感並站在對方的角度思考問題使我們在複雜的世界中可以做出恰當的決策。飢餓、好奇心、驚喜和喜悅等情感使我們能夠規範自己的行為,並讓我們追求我們希望實現的目標。
  • 基於機器學習的密碼強度檢測
    但所有的這些檢測都是基於規則的。一個密碼在Google這邊可能是強密碼但在Dropbox就變成了弱密碼。我在想我們能否讓機器學習算法來決定一個密碼是弱密碼還是強密碼。於是,這個帖子誕生了。讓我們開始吧。數據收集此次分析所使用的密碼數據來自於000webhost洩漏,此數據可在網上下載。那麼我們是如何決定哪些密碼是高強度的哪些密碼是低強度的呢?
  • 一種基於腦電圖情感識別的新型深度學習模型
    其中一部分機器學習技術中是通過分析腦電圖(EEG)信號來工作的,這些信號本質上是對從一個人的頭皮上收集的腦電活動的記錄。過去十多年來,大多數基於腦電圖的情緒分類方法都採用了傳統的機器學習方法,例如支持向量機(SVM)模型,因為這些方法需要的訓練樣本較少。事實上之所以使用需要訓練樣本量少的方法是因為過去缺乏大規模的EEG數據集。
  • 基於機器學習的數值天氣預報模式釋用方法
    本研究提出了數值天氣預報模式輸出機器學習(MOML)方法作為數值天氣預報模式的釋用技術。MOML方法是一個基於機器學習的模式後處理方法,它通過一個回歸函數將數值預報結果跟觀測數據進行匹配,這種方法可以提取某點的空間特徵和時間特徵。配合合適的特徵工程方案,MOML得到的預報結果比傳統的MOS算法好,尤其是冬季更明顯。
  • 基於機器學習的微博情感分析
    後邊還會繼續學習LSTM、TextCNN、Bert等模型,以及其他數據預處理方法,相信能有更好的預測效果。
  • 基於機器學習的數值天氣預報風速訂正研究
    近年來一些學者嘗試基於機器學習方法對數值天氣預報模式結果進行訂正,達到對風速的精細化預報。與傳統的訂正模型相比,基於機器學習方法的訂正模型則能捕捉非線性風速變化,在風速預報上表現出良好的性能。本文採用目前較為常用的三種機器學習(LASSO回歸、隨機森林和深度學習)以及MOS方法(經典天氣預報的統計訂正方法),對ECMWF數值天氣預報模式預測的近地面(10m)風速進行訂正。
  • 中文情感分析之TextCNN
    情感分析應用場景情感分析方法情感分析方法可以分為兩大類:一是基於情感詞典的方法,一是基於機器學習算法的方法。基於情感詞典的情感分析基於情感詞典的方法屬於傳統的情感分析方法,是對人的記憶和判斷思維的最簡單的模擬。直觀來講,它先通過學習來記憶一些基本詞彙,從而在大腦中形成一個包含積極詞彙、消極詞彙、否定詞、程度副詞的情感詞典。
  • 情感分析的新方法基於Word2Vec/Doc2Vec/Python
    情感分析是一種常見的自然語言處理(NLP)方法的應用,特別是在以提取文本的情感內容為目標的分類方法中。
  • 情感計算是人機互動核心?談深度學習在情感分析中的應用
    其中針對中文語境裡人機互動中的情感、情緒識別與理解,竹間智能已經做了許多有益的探索,特別是如何利用情感、情緒分析,來幫助機器人實現對「對話意圖」與「深層語義」的更好理解。 本文將梳理一下情感計算在人機互動中的價值,同時分享一些情感分析的工具與方法。希望對從事人機互動研究的朋友們有所啟發。
  • 頂會論文解讀|北大提出ELSA跨語言情感分析模型
    作為用戶情境感知和理解中一個重要方面,情感分析得到了包括數據挖掘、系統軟體、人機互動等多領域研究者的廣泛關注,成為交叉研究熱點並取得一系列進展。現有情感分析工作主要基於英語文本開展。在其他語言上,研究較少、標註語料稀缺,現有方法效果較差。但是,75%的網際網路用戶為非英語用戶,大約一半的Web內容為非英語內容。
  • NLP專欄丨情感分析方法入門上
    情感分析問題可以劃分為許多個細分的領域,下面的思維導圖[2]展示了情感分析任務的細分任務:句子級/文檔級情感分析研究的是如何給整個句子或文檔打情感標籤。而目標級情感分析是考慮了具體的目標,該目標可以是實體、某個實體的屬性或實體加屬性的組合。
  • 人工智慧技術落地:情感分析概述
    如果一個句子直接表達或隱含了情感信息,則認為這個句子是含有情感觀點的,對於不含情感觀點的句子則可以進行過濾。目前對於句子是否含有情感信息的分類技術大多都是採用有監督的學習算法,這種方法需要大量的人工標註數據,基於句子特徵來對句子進行分類。
  • 一個基於 FPGA 的機器學習平臺及其使用方法
    但是此類器件大都處於早期開發階段,因為設計人員正在努力尋找最有效的算法,甚至人工智慧 (AI) 研究人員也在迅速推演新方法。目前,開發人員一般使用針對 ML 的可用 FPGA 平臺來構建嵌入式視覺系統,以期滿足更高的性能要求。與此同時,他們可以保持所需的靈活性,以跟上機器學習發展的步伐。本文將介紹 ML 處理的要求,以及為何 FPGA 能解決許多性能問題。
  • Alink:基於Flink的機器學習平臺
    分享嘉賓:楊旭 阿里巴巴 資深算法專家編輯整理:朱榮導讀:Alink是基於Flink流批一體的機器學習平臺,提供一系列算法,可以幫助處理各種機器學習任務,比如統計分析、機器學習、實時預測、個性化推薦和異常檢測。
  • 如何構建基於機器學習的入侵檢測系統
    本文將涵蓋機器學習模型構建機器學習項目的必要步驟如何評估一個機器學習模型最有用的數據科學和機器學習代碼庫人工神經網絡和深度學習基於機器學習的下一代入侵檢測系統人工智慧人工智慧是讓電腦程式變得像人一樣行為的藝術