相信經過前兩天的科普(強迫灌輸??)之後,大家對 SVM 都有了相當的認識。不過,昨天的實作主要為了讓大家了解 SVM 切割方式,因此用了很簡單的資料集來做示範。然而,想必大家一定都知道,實際 NLP 任務時不會有那麼簡易的資料,不僅資料預處理很繁雜,提取語料特徵也是一門藝術 XD 因此,這篇要運用相對比較複雜的資料集、提取語言相關之特徵、使用之前提過的 TF 和 TF-IDF 作為其中一項訓練特徵以及偏向語言學的分析來帶大家更進一步認識 SVM。
本篇使用的資料集為電商平台女裝評論(Women’s E-Commerce Clothing Reviews),資料來源自 Kaggle 平台(https://www.kaggle.com/datasets/nicapotato/womens-ecommerce-clothing-reviews)。因為這是一份真實的商業數據,因此評論進行了匿名處理,並將評論文本中公司和廠商的名字替換為「零售商」。這份資料集中包含10個欄位,分別為:
而本篇要處理的分類問題是判斷客戶購買的產品是什麼(分為裙子 Dresses 和其他 Others),希望能夠透過評論的文本分類出哪些客戶購買裙裝,哪些不是。
本篇分類目的為找出透過評論的文本分類出哪些客戶購買裙裝,哪些不是。判斷的方式是利用每一位顧客的評論文本,將其製作為一份 corpus,分別製作 TF 和 TF-IDF 兩種 SVM 分類器讓機器進行分類與預測。判斷是否能單純利用評論文本的 TF 或 TF-IDF 來預測顧客到底是不是購買裙裝。首先,先設定分類標籤,將購買裙裝的定為Dresses,非裙裝的產品則是 Others,接下來對評論文本進行預處理,包括斷詞、刪除停止詞、移除標點符號等等,將處理好的文本製作成 corpus 並且算出 TF 和 TF-IDF,將這兩份資料分別訓練出兩個 SVM 模型,最後進行預測。
# Preprocessing
review = read.csv('Womens Clothing E-Commerce Reviews.csv')
review<-review[!is.na(review$Review.Text), ]
review<-review[!is.na(review$Title), ] # 刪除 NA
labels = c()
for (i in seq_along(review$Class.Name)){
if (review$Class.Name[i] == "Dresses"){
labels[i] = 'Dresses'
}else{
labels[i] = 'Others'
}
}
review$Label = labels # 把產品分為裙子 Dresses 和其他 Others,作為分類目標
library(tm)
library(tokenizers)
r <-as.vector(review$Review.Text)
r <-tokenize_words(r)
myStopwords= c(stopwords(), "the", "was", "a", "an", "this", "and", "to", "it", "that", "i")
# 製作 TF 的 dtm corpus
corpus_review = Corpus(VectorSource(r))
dtm_review = DocumentTermMatrix(corpus_review,
control = list(weighting = weightTf,# 在這邊設定!!
stopwords = myStopwords,
removePunctuation = T,
removeNumbers = T,
stemming = T))
# 調整一下 sparsity
dtm_review = removeSparseTerms(dtm_review, 0.8)
# Train SVM classifier with TF
library(caret)
review <- subset(review, select = -c(Clothing.ID, Title, Age, Department.Name, Rating, X, Positive.Feedback.Count, Class.Name))# 刪除不需要的欄位
set.seed(123)
trainIndex <- createDataPartition(review$Label, p=0.8, list=FALSE)
train_set <- as.matrix(dtm_review[trainIndex,])
test_set <- as.matrix(dtm_review[-trainIndex,])
train_labels <- review$Label[trainIndex]
test_labels <- review$Label[-trainIndex]
require(e1071)
svm_model = svm(x = train_set, y = as.factor(train_labels))
# confusion matrix
test_pred = predict(svm_model, test_set)
table(predict=test_pred, real=test_labels)
執行結果為:
# performance metrics + confusion matrix
table_matrix <- confusionMatrix(test_pred, as.factor(test_labels))
table_matrix
table_matrix$byClass["F1"] # 單獨看 F1-score
執行結果為:
F1-score
0.8120063
# TF-IDF Classifier
# Preprocessing
review = read.csv('/Womens Clothing E-Commerce Reviews.csv')
review<-review[!is.na(review$Review.Text), ]
review<-review[!is.na(review$Title), ]
labels = c()
for (i in seq_along(review$Class.Name)){
if (review$Class.Name[i] == "Dresses"){
labels[i] = 'Dresses'
}else{
labels[i] = 'Others'
}
}
review$Label = labels
library(tm)
library(tokenizers)
r <-as.vector(review$Review.Text)
r <-tokenize_words(r)
# 製作 TF-IDF corpus
myStopwords= c(stopwords(), "the", "was", "a", "an", "this", "and", "to", "it", "that", "i")
corpus_review = Corpus(VectorSource(r))
dtm_review = DocumentTermMatrix(corpus_review,
control = list(weighting = weightTfIdf, # 在這裡調喔!!
stopwords = myStopwords,
removePunctuation = T,
removeNumbers = T,
stemming = T))
dtm_review = removeSparseTerms(dtm_review, 0.8)
# Train SVM classifier with TF-IDF
library(caret)
review <- subset(review, select = -c(Clothing.ID, Title, Age, Department.Name, Rating, X, Positive.Feedback.Count, Class.Name))# 刪除不需要的欄位
set.seed(123)
trainIndex <- createDataPartition(review$Label, p=0.8, list=FALSE)
train_set <- as.matrix(dtm_review[trainIndex,])
test_set <- as.matrix(dtm_review[-trainIndex,])
train_labels <- review$Label[trainIndex]
test_labels <- review$Label[-trainIndex]
require(e1071)
svm_model = svm(x = train_set, y = as.factor(train_labels))
table_matrix <- confusionMatrix(test_pred, as.factor(test_labels), mode='prec_recall')
table_matrix
table_matrix$byClass["F1"]
執行結果為:
F1-score
0.8123776
比較 TF 和 TF-IDF 模型,以 F1-score 來看的話,是 TF-IDF 的模型表現比較好,不過整體而言其實差異不大,所以也許之後可以不只使用 TF 或 TF-IDF 的方式來做 SVM ,而是可以多調 SVM 裡面不同的參數,看看是否能讓模型的預測更精準。
今天就介紹到這~感謝大家,我們明天見!