資料探勘研究與實務_情感分析(Kaggle Amazon Fine Food Reviews)
"Kaggle Amazon Fine Food Reviews" 是一個在 Kaggle 平台上的資料集,它包含了 Amazon 的食品評論數據。這個資料集是為了提供一個實際的文本數據集,供研究者和數據科學家進行自然語言處理 (NLP) 和情感分析的練習。
以下是該資料集的基本介紹:
數據來源:這些評論是從 Amazon 網站上收集的,涵蓋了多種食品產品。
評論時間範圍:這個資料集包含了從 1999 年到 2012 年的評論。
數據大小:資料集包含了超過 500,000 條評論。
資料欄位:主要的欄位包括:
- Id: 評論的唯一識別碼。
- ProductId: 產品的唯一識別碼。
- UserId: 使用者的唯一識別碼。
- ProfileName: 使用者的名稱。
- HelpfulnessNumerator: 評論被認為有幫助的次數。
- HelpfulnessDenominator: 評論被評價的總次數。
- Score: 產品的評分,範圍從 1 到 5。
- Time: 評論的時間戳記。
- Summary: 評論的摘要。
- Text: 評論的完整內容。
應用場景:這個資料集可以用於多種 NLP 任務,例如情感分析、文本分類、詞彙特徵提取等。它也可以用於探索性數據分析,以瞭解消費者對食品的喜好和不喜好。
如果你已經有這個資料集的 Reviews.csv 檔案,我可以幫助你進行更深入的分析。請上傳該檔案,我將為你進行初步的數據探索。
1. 資料前處理
a. 讀取 csv 檔後取前 1 萬筆資料
僅保留"Text"、"Score"兩個欄位
並將 "Score" 欄位內值大於等於4的轉成1,其餘轉成0
1: positive
0: negative
並將text欄位內的文字利用分割符號切割
b. 去除停頓詞stop words
使用 pandas 和 NLTK
nltk 提供了一個現成的停頓詞列表,可以方便地去除不需要的詞。
資料前處裡
將 "Score" 欄位內值大於等於4的轉成1,其餘轉成0
1 2 3 4 5 6 | # 定義轉換 "Score" 欄位的函數 def convert_score(score): if score >= 4: return 1 else: return 0 |
將text欄位內的文字利用分割符號切割並且去除停頓詞stop words
1 2 3 4 5 6 7 8 9 | # 下載停頓詞列表 nltk.download('stopwords') stop_words = set(stopwords.words('english')) # 定義切割 "Text" 欄位並去除停頓詞的函數 def process_text(text): words = text.split() filtered_words = [word for word in words if word.lower() not in stop_words] return ' '.join(filtered_words) |
nlk提供的英文停頓詞有以下這幾些
在 process_text 函數中,以下這行程式碼:
words = text.split()
會將 text 字串以空白符號(包括空格、換行符號等)作為分割符號,將其切割成一個單詞的列表。所以這個函數不僅去除了停頓詞,還將文本切割成了單詞。
版本 1: 使用 TF-IDF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | import pandas as pd import nltk from nltk.corpus import stopwords from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.feature_extraction.text import TfidfVectorizer from gensim.models import Word2Vec # 讀取 CSV 檔案 df = pd.read_csv('Reviews.csv', nrows=10000) # 保留 "Text" 和 "Score" 欄位 df = df[['Text', 'Score']] # 資料前處理 # 定義轉換 "Score" 欄位的函數 def convert_score(score): if score >= 4: return 1 else: return 0 df['Score'] = df['Score'].apply(convert_score) # 下載停頓詞列表 nltk.download('stopwords') stop_words = set(stopwords.words('english')) # 定義切割 "Text" 欄位並去除停頓詞的函數 def process_text(text): words = text.split() filtered_words = [word for word in words if word.lower() not in stop_words] return ' '.join(filtered_words) df['Text'] = df['Text'].apply(process_text) # 使用 TF-IDF 轉換文本數據 vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(df['Text']) y = df['Score'] # 初始化 Random Forest 分類器 clf = RandomForestClassifier() # 進行 k-fold cross-validation scores = cross_val_score(clf, X, y, cv=4) accuracy = scores.mean() print(f"4-Fold Cross-Validation Accuracy using Tfidf: {accuracy:.4f}") |
使用 TF-IDF 將文本數據轉換為數值格式。
接著,它使用 Random Forest 分類器進行建模,並使用 4-fold cross-validation 進行模型評估。
最後,它將輸出 4-fold cross-validation 的平均準確率。
4-Fold Cross-Validation Accuracy using Tfidf: 0.7992
版本 2: 使用 Word2Vec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | import pandas as pd import nltk from nltk.corpus import stopwords from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.feature_extraction.text import TfidfVectorizer from gensim.models import Word2Vec # 讀取 CSV 檔案 df = pd.read_csv('Reviews.csv', nrows=10000) # 保留 "Text" 和 "Score" 欄位 df = df[['Text', 'Score']] # 資料前處理 # 定義轉換 "Score" 欄位的函數 def convert_score(score): if score >= 4: return 1 else: return 0 df['Score'] = df['Score'].apply(convert_score) # 下載停頓詞列表 nltk.download('stopwords') stop_words = set(stopwords.words('english')) # 定義切割 "Text" 欄位並去除停頓詞的函數 def process_text(text): words = text.split() filtered_words = [word for word in words if word.lower() not in stop_words] return ' '.join(filtered_words) df['Text'] = df['Text'].apply(process_text) # 使用 Word2Vec 轉換文本數據 sentences = [text.split() for text in df['Text']] model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4) model.train(sentences, total_examples=len(sentences), epochs=10) # 將每個文本轉換為向量 def get_vector(text): words = text.split() vector = sum([model.wv[word] for word in words if word in model.wv.index_to_key]) return vector / len(words) if words else vector X = df['Text'].apply(get_vector).tolist() y = df['Score'] # 初始化 Random Forest 分類器 clf = RandomForestClassifier() # 進行 k-fold cross-validation scores = cross_val_score(clf, X, y, cv=4) accuracy = scores.mean() print(f"4-Fold Cross-Validation Accuracy using Word2Vec: {accuracy:.4f}") |
大多數的機器學習模型(例如 Random Forest)需要數值輸入。然而,文本數據是非結構化的,不能直接用於這些模型。因此,我們需要將文本數據轉換為數值格式。這就是為什麼我們需要這個步驟的原因。
Word2Vec 訓練
sentences 是一個列表,其中每個元素都是一個文本的詞列表。
使用這些 sentences,我們訓練了一個 Word2Vec 模型。這個模型會學習每個詞的向量表示,這些表示是基於詞的上下文。
Word2Vec 的訓練參數對模型的效果和性能有很大的影響
vector_size=100:
這是每個詞的向量的維度。一般來說,更大的 vector_size 可能會捕捉到更多的詞的細微差異,但也會增加模型的計算量。
常見的值包括 100、200 和 300。選擇的具體值取決於數據集的大小和複雜性。
window=5:
訓練模型時考慮的上下文詞的數量。例如,window=5 表示對於每個詞,模型將考慮其前5個和後5個詞作為其上下文。
較大的 window 值可能會捕捉到更遠的詞之間的關係,但也可能使模型更難訓練。
min_count=1:
這是詞必須出現的最少次數,才會被考慮在模型的詞彙中。
設定 min_count 可以過濾掉非常罕見的詞。在這裡,min_count=1 表示所有出現的詞都會被考慮。
workers=4:
訓練模型時使用的並行Thread數。增加 workers 可以加速模型的訓練,特別是在多核心的機器上。通常,這個值設定為機器的核心數。
將每個文本轉換為向量
get_vector 函數的目的是將一個文本轉換為一個向量。
這是通過將文本中的每個詞的向量加總,然後除以詞的數量來實現的。
如果文本中的某個詞不在 Word2Vec 模型的詞彙中,我們將忽略它。
最後,將每個文本的向量存儲在 X 列表中。
4-Fold Cross-Validation Accuracy using Word2Vec: 0.7803
使用 Word2Vec 的 4-Fold Cross-Validation 準確率為:0.7803
使用 TF-IDF 的 4-Fold Cross-Validation 準確率為:0.7992
TF-IDF 的準確率略高於 Word2Vec。Word2Vec 則是基於詞的上下文來學習詞的向量表示,它能捕捉到詞的語義信息,但在某些情境下可能不如 TF-IDF 那麼有效。
評估可能是因為數據量
Word2Vec 通常需要大量的數據來訓練一個有效的模型。在只有 1 萬筆資料的情境下,Word2Vec 可能沒有足夠的數據來學習有效的詞向量。
特徵維度:TF-IDF 會產生一個高維的稀疏向量,而 Word2Vec 產生的是低維的密集向量。這兩種表示方式在不同的模型和應用中可能有不同的效果。
留言
張貼留言