1. 程式人生 > 其它 >使用樸素貝葉斯對電影評論分類

使用樸素貝葉斯對電影評論分類

本文內容:

使用樸素貝葉斯對電影評論分類

1.資料集講解:

​ 該資料集是IMDB電影資料集的一個子集,已經劃分好了測試集和訓練集,訓練集包括25000條電影評論,測試集也有25000條,該資料集已經經過預處理,將每條評論的具體單詞序列轉化為詞庫裡的整數序列,其中每個整數代表該單詞在詞庫裡的位置。例如,整數104代表該單詞是詞庫的第104個單詞。為實驗簡單,詞庫僅僅保留了10000個最常出現的單詞,低頻詞彙被捨棄。每條評論都具有一個標籤,0表示為負面評論,1表示為正面評論。

​ 訓練資料在train_data.txt檔案下,每一行為一條評論,訓練集標籤在train_labels.txt檔案下,每一行為一條評論的標籤;測試資料在test_data.txt檔案下,測試資料標籤未給出。

2.具體實現:

  1. 取出資料集:

    從txt中取出訓練集與測試集:

    with open("test/test_data.txt", "rb") as fr:
    
      test_data_n = [inst.decode().strip().split(' ') for inst in fr.readlines()]
    
      test_data = [[int(element) for element in line] for line in test_data_n]
    
    test_data = np.array(test_data)
    
  2. 資料處理:

    對每條評論,先將其解碼為英文單詞,再鍵值顛倒,將整數索引對映為單詞。

    把整數序列編碼為二進位制序列。

    最後把訓練集標籤向量化。

    # 將某條評論解碼為英文單詞
    
    word_index = imdb.get_word_index() # word_index是一個將單詞對映為整數索引的字典
    
    reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
    
    # 鍵值顛倒,將整數索引對映為單詞
    
    decode_review = ' '.join(
    
      [reverse_word_index.get(i - 3, '?') for i in train_data[0]]
    
    )
    \# 將評論解碼 \# 注意,索引減去了3,因為0,1,2是為padding填充 \# "start sequence"序列開始,"unknow"未知詞分別保留的索引 \# 將整數序列編碼為二進位制矩陣 def vectorize_sequences(sequences, dimension=10000): results = np.zeros((len(sequences), dimension)) # 建立一個形狀為(len(sequences), dimension)的矩陣 for i, sequence in enumerate(sequences): results[i, sequence] = 1 # 將results[i]的指定索引設為 1 return results x_train = vectorize_sequences(train_data) x_test = vectorize_sequences(test_data) \# 標籤向量化 y_train = np.asarray(train_labels).astype('float32')
  3. 建立模型:

    可選多項式模型或者伯努利模型。

    二者的計算粒度不一樣,多項式模型以單詞為粒度,伯努利模型以檔案為粒度,因此二者的先驗概率和類條件概率的計算方法都不同。
    計算後驗概率時,對於一個文件d,多項式模型中,只有在d中出現過的單詞,才會參與後驗概率計算,伯努利模型中,沒有在d中出現,但是在全域性單詞表中出現的單詞,也會參與計算,不過是作為“反方”參與的。
    當訓練集文件較短,也就說不太會出現很多重複詞的時候,多項式和伯努利模型公式的分子相等,多項式分母值大於伯努利分子值,因此多項式的似然估計值會小於伯努利的似然估計值。
    所以,當訓練集文字較短時,我們更傾向於使用伯努利模型。而文字較長時,我們更傾向於多項式模型,因為,在一篇文件中的高頻詞,會使該詞的似然概率值相對較大。

    使用拉普拉斯平滑

    alpha:先驗平滑因子,預設等於1,當等於1時表示拉普拉斯平滑。

    # model = MultinomialNB()
    model = BernoulliNB()
    model.fit(X_train, y_train)
    
  4. 輸出測試集上的預測結果:

    將結果寫入txt

    # model evaluation
    print("model accuracy is " + str(accuracy_score(y_test, y_pred)))
    print("model precision is " + str(precision_score(y_test, y_pred, average='macro')))
    print("model recall is " + str(recall_score(y_test, y_pred, average='macro')))
    print("model f1_score is " + str(f1_score(y_test, y_pred, average='macro')))
    
    des = y_pred_local.astype(int)
    np.savetxt('Text3_result.txt', des, fmt='%d', delimiter='\n')
    

3.實驗結果:

使用多項式模型:

在這裡插入圖片描述

使用伯努利模型:

在這裡插入圖片描述

在該場景下,兩者差別不大。

實驗總結

  1. 貝葉斯概率及貝葉斯 準則提供了一種利用已知值來估計位置概率的有效方法;
  2. 樸素貝葉斯假設資料特徵之間相互獨立,雖然該假設在一般情況下並不嚴格成立,但使用樸素貝葉斯進行分類,仍然可以取得很好的效果;
  3. 貝葉斯網路的優點:在資料較少的情況下仍然有效,可以處理多類別問題;
  4. 貝葉斯網路的缺點:對輸入資料的準備方式較為敏感。
  5. 拉普拉斯平滑對於改善樸素貝葉斯分類器的分類效果有著積極的作用。