1. 程式人生 > >電商產品評論資料情感分析程式碼詳解

電商產品評論資料情感分析程式碼詳解

本章程式碼建議在linux下面執行,windows下安裝gensim會比較麻煩。

我是在python3.5.2的pycharm下執行的

下面程式碼的意思是從評論資料中抽取品牌是美的的資料(15-1)

#-*- coding: utf-8 -*-
import pandas as pd

inputfile = '../data/huizong.csv' #評論彙總檔案
outputfile = '../data/meidi_jd.txt' #評論提取後儲存路徑
data = pd.read_csv(inputfile, encoding = 'utf-8')
data = data[[u'評論']][data[u'品牌'] == u'美的']
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')


這裡一句話概括接下來的去重概念,文字去重和機械壓縮去重

文字去重指的是資料條之間的去重。

機械壓縮去重指的是資料條內部,詞語與詞語之間的去重。

下面程式碼是用來文字去重的(15-2)。

#-*- coding: utf-8 -*-
import pandas as pd

inputfile = '../data/meidi_jd.txt' #評論檔案
outputfile = '../data/meidi_jd_process_1.txt' #評論處理後儲存路徑
data = pd.read_csv(inputfile, encoding = 'utf-8', header = None)
l1 = len(data)
data = pd.DataFrame(data[0].unique())
l2 = len(data)
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')
print(u'刪除了%s條評論。' %(l1 - l2))

下面程式碼的作用是把評論前面的評分刪除(15-3):

#-*- coding: utf-8 -*-
import pandas as pd

#引數初始化
inputfile1 = '../data/meidi_jd_process_end_負面情感結果.txt'
inputfile2 = '../data/meidi_jd_process_end_正面情感結果.txt'
outputfile1 = '../data/meidi_jd_neg.txt'
outputfile2 = '../data/meidi_jd_pos.txt'

data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #讀入資料
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None)
print("data1=",data1[0])

data1 = pd.DataFrame(data1[0].str.replace('.*?\d+?\\t ', '')) #用正則表示式修改資料
data2 = pd.DataFrame(data2[0].str.replace('.*?\d+?\\t ', ''))#這裡的意思其實是用‘’(也就是代表什麼都沒有)來代替前面的符合特徵的字串,等效於實現了刪除的功能
print("###############################")
print("data1=",data1[0])
#以上正則表示式的效果,可以通過把正則篩選前後的data[0]分別輸出來進行比較
data1.to_csv(outputfile1, index = False, header = False, encoding = 'utf-8') #儲存結果
data2.to_csv(outputfile2, index = False, header = False, encoding = 'utf-8')


接下來是進行分詞(詳細解釋請見程式碼中註釋)(15-4)

#-*- coding: utf-8 -*-
import pandas as pd
import jieba #匯入結巴分詞,需要自行下載安裝

#引數初始化
inputfile1 = '../data/meidi_jd_neg.txt'
inputfile2 = '../data/meidi_jd_pos.txt'
outputfile1 = '../data/meidi_jd_neg_cut.txt'
outputfile2 = '../data/meidi_jd_pos_cut.txt'

data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #讀入資料
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None)

mycut = lambda s: ' '.join(jieba.cut(s)) #自定義簡單分詞函式,先識別句子中的中文單詞,然後把中文單詞通過空格連線起來
#上面一句程式碼中,s是入口引數,.join前面的空格表示把jieba庫處理過後的s中的詞語jieba.cut(s),用空格來連線。
data1 = data1[0].apply(mycut) #通過“廣播”形式分詞,加快速度。
data2 = data2[0].apply(mycut)

data1.to_csv(outputfile1, index = False, header = False, encoding = 'utf-8') #儲存結果
data2.to_csv(outputfile2, index = False, header = False, encoding = 'utf-8')

最後是LDA程式碼(15-5)

#-*- coding: utf-8 -*-
import pandas as pd

#引數初始化
negfile = '../data/meidi_jd_neg_cut.txt'
posfile = '../data/meidi_jd_pos_cut.txt'
stoplist = '../data/stoplist.txt'

neg = pd.read_csv(negfile, encoding = 'utf-8', header = None) #讀入資料
pos = pd.read_csv(posfile, encoding = 'utf-8', header = None)
stop = pd.read_csv(stoplist, encoding = 'utf-8', header = None, sep = 'tipdm',engine='python')
#sep設定分割詞,由於csv預設以半形逗號為分割詞,而該詞恰好在停用詞表中,因此會導致讀取出錯(這裡的出錯的意思就是程式碼執行報錯,編譯器直接不讓編譯通過)
#所以解決辦法是手動設定一個不存在的分割詞,如tipdm。
#這裡先解釋下什麼是“停用詞”,停用詞指的是本文中出現頻率很高、但是實際意義不大的詞語,比如
#“今天好嗨森啊啊啊啊啊啊啊啊”,那麼這句話中的“啊啊啊啊啊啊啊啊”就是停用詞
#講通俗點的話,停用詞就是“廢話”。  。

stop = [' ', ''] + list(stop[0]) #Pandas自動過濾了空格符,這裡手動新增(在每條資料的開頭加個空格)

#下面這段程式碼可以分為兩小段,這兩小段程式碼幾乎一致,前面一個是針對負面評論,後一個是針對正面評論,所以只詳解其中一個
neg[1] = neg[0].apply(lambda s: s.split(' ')) #定義一個分割函式,然後用apply廣播
neg[2] = neg[1].apply(lambda x: [i for i in x if i not in stop]) #逐詞判斷是否停用詞,思路同上
#上面這句程式碼的語法是:列表推導式子。意思是說,如果i不在停用詞列表(stop)中,就保留該詞語(也就是最前面的一個i),否則就進行刪除
#上面的這句程式碼中,把for i in x看做整體,把if i not in stop看做判斷語句,把最前面的i看做滿足if語句之後的執行語句即可。
pos[1] = pos[0].apply(lambda s: s.split(' '))
pos[2] = pos[1].apply(lambda x: [i for i in x if i not in stop])

#上面的lamda s和lamda x中的s和x都是表示入口引數,apply的意思是,把apply前面的字串當做入口引數,輸入到appy後面所定義的函式中

from gensim import corpora, models

#負面主題分析
#這段程式碼和下面的“正面主題分析”幾乎是完全一樣的,作用講得通俗點其實就是聚類。
neg_dict = corpora.Dictionary(neg[2]) #建立詞典
neg_corpus = [neg_dict.doc2bow(i) for i in neg[2]] #建立語料庫
neg_lda = models.LdaModel(neg_corpus, num_topics = 3, id2word = neg_dict) #LDA模型訓練
for i in range(3):
  neg_lda.print_topic(i) #輸出每個主題(這個其實就是聚類結果的輸出)

#正面主題分析
pos_dict = corpora.Dictionary(pos[2])
pos_corpus = [pos_dict.doc2bow(i) for i in pos[2]]
pos_lda = models.LdaModel(pos_corpus, num_topics = 3, id2word = pos_dict)
for i in range(3):
  neg_lda.print_topic(i) #輸出每個主題

通俗解釋下LDA演算法幹嘛的,我們知道:

K-means是聚類的,他主要是處理資料的,對資料進行聚類。

LDA其實也是聚類的,主要是處理字串的,對字串進行聚類。