
- กรณีใช้งาน Data Science ในงานขาย: การวิเคราะห์อารมณ์ความรู้สึกของลูกค้า
- การเตรียมชุดข้อมูล
- การใช้วิธี BOW
- การใช้โมเดลแมชชีนเลิร์นนิงแบบกำกับเพื่อพยากรณ์อารมณ์ความรู้สึก
- สรุป
กรณีใช้งานของวิทยาการข้อมูลสามารถเชื่อมโยงได้เกือบทุกอุตสาหกรรมที่มีหรือสามารถสะสมข้อมูลจำนวนมากได้ ร้านค้าและเว็บไซต์อีคอมเมิร์ซคือต้นทางของประสบการณ์จริงของลูกค้าที่ถูกดึงดูดด้วยแคมเปญการตลาด และเป็นที่ที่มีการเก็บข้อมูลการซื้อที่มีคุณค่าของแบรนด์หรือบริษัทหนึ่งๆ ที่นี่เองที่ผู้คนตัดสินใจขั้นสุดท้ายว่าจะซื้อสินค้าชิ้นหนึ่งหรือไม่ จะสนใจสิ่งอื่นที่เดิมไม่ได้ตั้งใจจะซื้อหรือไม่ พร้อมทั้งยอมจ่ายเท่าไร จะกลับมาที่ร้านนี้อีกหรือไม่ และจะทิ้งรีวิวเกี่ยวกับประสบการณ์การใช้งานไว้อย่างไรบ้าง
ที่จริงแล้ว รีวิวของลูกค้าเป็นแหล่งข้อมูลชั้นดีสำหรับการวิเคราะห์และทำความเข้าใจว่าส่วนใดในกระบวนการขายทั้งหมดที่ควรปรับปรุงหรือเสริมให้แข็งแรง การวิเคราะห์ข้อมูลในลักษณะนี้ช่วยลดต้นทุน เพิ่มประสิทธิภาพการปฏิบัติงาน ยกระดับประสบการณ์ลูกค้า เปิดโอกาสใหม่ๆ ขยายธุรกิจ และท้ายที่สุดเพิ่มรายได้ มาดูกันอย่างใกล้ชิดว่าข้อมูลล้ำค่านี้สามารถนำมาวิเคราะห์และสร้างแบบจำลองด้วยอัลกอริทึมวิทยาการข้อมูลได้อย่างไร เพื่อค้นหาอินไซต์ที่ซ่อนอยู่และจับใจความโดยรวมจากลูกค้าแต่ละราย
กรณีใช้งาน Data Science ในงานขาย: การวิเคราะห์อารมณ์ความรู้สึกของลูกค้า
การวิเคราะห์อารมณ์ความรู้สึกของลูกค้าเป็นกระบวนการอัตโนมัติในการระบุอารมณ์ของลูกค้าเมื่อใช้บริการหรือผลิตภัณฑ์ของบริษัทหนึ่งๆ โดยทั่วไปเป็นข้อมูลข้อความที่ไม่มีโครงสร้าง ซึ่งเก็บมาจากแบบสำรวจออนไลน์ โซเชียลมีเดีย ทิกเก็ตซัพพอร์ต แบบฟอร์มคำติชม รีวิวสินค้า ฟอรัม สายโทรศัพท์ อีเมล และแชตบอต ในแมชชีนเลิร์นนิง การวิเคราะห์อารมณ์ความรู้สึกทำผ่านการประมวลผลภาษาธรรมชาติ (NLP) ที่ใช้วิธีเชิงสถิติและภาษาศาสตร์เพื่อดึงอารมณ์เชิงบวก เชิงลบ และเป็นกลางตรงจากข้อมูลข้อความ โดยหลักแล้วจะให้ผลลัพธ์เป็นสองพารามิเตอร์:
- Polarity: บ่งชี้ว่าอารมณ์เป็นเชิงบวกหรือลบ
- Magnitude: บ่งชี้ความรุนแรงของอารมณ์นั้น
การวิเคราะห์อารมณ์ความรู้สึกของลูกค้าเป็นเครื่องมือสำคัญสำหรับธุรกิจสมัยใหม่ เพราะช่วยให้ได้อินไซต์ที่นำไปใช้ได้จริง มองเห็นและแก้ปัญหาสำคัญที่เกิดซ้ำซึ่งทำให้ลูกค้าไม่พอใจ เสริมฟีเจอร์ของผลิตภัณฑ์หรือบริการที่ก่อให้เกิดอารมณ์เชิงบวก และโดยรวมช่วยให้ตัดสินใจเชิงข้อมูลได้มีประสิทธิภาพมากขึ้น ในระดับที่ลงลึกยิ่งขึ้น การวิเคราะห์อารมณ์ช่วยให้:
- ยกระดับงานบริการลูกค้าและส่งผลให้ประสบการณ์ดีขึ้น
- เพิ่มความภักดีของลูกค้า
- ลดอัตราการยกเลิกใช้บริการ
- อัปเกรดผลิตภัณฑ์และบริการได้ทันเวลา
- ปรับแคมเปญการตลาดให้เหมาะสม
- คาดการณ์เทรนด์และตลาดใหม่
- รักษาชื่อเสียงที่ดีของบริษัท
- เพิ่มกำไร
เช่นเดียวกับงานวิเคราะห์ข้อความอื่นๆ ระหว่างการวิเคราะห์อารมณ์ของลูกค้าอาจพบหลุมพรางบางอย่าง ตัวอย่างเช่น อัลกอริทึม NLP อาจไม่เข้าใจถ้อยคำประชดประชันในรีวิวบางรายการและจัดหมวดหมู่ผิดพลาด อีกทั้งบางครั้งอาจตีความตัวย่อเฉพาะทางมากๆ หรือคำสแลงที่ไม่ค่อยใช้ไม่ออก
การเตรียมชุดข้อมูล
มาลองดูการทำงานของการวิเคราะห์อารมณ์ในทางปฏิบัติ โดยใช้ชุดข้อมูลรีวิวภาพยนตร์จาก IMDB:
import pandas as pd
movies = pd.read_csv('movies.csv', index_col=0).reset_index(drop=True)
print(f'Number of reviews: {movies.shape[0]:,}\n')
print(movies.head())
Number of reviews: 7,501
review label
0 This short spoof can be found on Elite's Mille... 0
1 A singularly unfunny musical comedy that artif... 0
2 An excellent series, masterfully acted and dir... 1
3 The master of movie spectacle Cecil B. De Mill... 1
4 I was gifted with this movie as it had such a ... 0
มีสองคอลัมน์: คอลัมน์หนึ่งเป็นข้อความของแต่ละรีวิว และอีกคอลัมน์เป็นการประเมินอารมณ์โดยรวมว่าเป็นบวก (1) หรือลบ (0)
มาคำนวณสัดส่วนเปอร์เซ็นต์ของรีวิวเชิงบวกและเชิงลบกัน:
round(movies['label'].value_counts()*100/len(movies['label'])).convert_dtypes()
0 50
1 50
Name: label, dtype: Int64
ดังนั้น สัดส่วนรีวิวเชิงบวกและเชิงลบจึงเกือบเท่ากัน
การใช้วิธี BOW
ขั้นต่อไปคือต้องแปลงข้อมูลข้อความให้เป็นเชิงตัวเลข เพราะโมเดลแมชชีนเลิร์นนิงทำงานได้กับฟีเจอร์แบบตัวเลขเท่านั้น โดยเฉพาะเราจะสร้างฟีเจอร์ที่นับจำนวนครั้งที่แต่ละคำปรากฏในรีวิว วิธีพื้นฐานและตรงไปตรงมาที่สุดคือ bag-of-words (BOW) ซึ่งจะสร้างคลังคำจากคำทั้งหมดที่เกิดขึ้นในเอกสาร และนับความถี่ของแต่ละคำในแต่ละรีวิว ผลลัพธ์คือจะได้ฟีเจอร์ใหม่หนึ่งฟีเจอร์ต่อหนึ่งคำ พร้อมค่าความถี่ที่สอดคล้องกัน
มาลองใช้วิธี BOW กับชุดข้อมูลของเรา:
from sklearn.feature_extraction.text import CountVectorizer
# Creating new features
vect = CountVectorizer(max_features=200)
vect.fit(movies.review)
X_review = vect.transform(movies.review)
X_df = pd.DataFrame(X_review.toarray(), columns=vect.get_feature_names())
# Combining the new features with the label
movies_bow = pd.concat([movies['label'], X_df], axis=1)
print(movies_bow.head())
label 10 about acting action actors actually after again all ... \
0 0 0 0 0 0 0 0 0 0 0 ...
1 0 1 0 1 0 1 0 0 0 3 ...
2 1 0 0 0 0 0 0 1 0 0 ...
3 1 0 0 0 1 0 0 0 0 0 ...
4 0 1 0 0 1 0 0 0 0 3 ...
will with without work world would years you young your
0 0 1 0 0 0 1 0 0 0 0
1 2 7 1 0 0 2 0 3 0 2
2 0 2 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 0 1 1 0
4 0 2 0 1 0 0 0 0 0 0
[5 rows x 201 columns]
ข้างต้น เราใช้พารามิเตอร์เสริม max_features เพื่อพิจารณาเฉพาะ 200 คำที่ใช้บ่อยที่สุด และหลีกเลี่ยงการ overfitting ของโมเดลที่อาจเกิดขึ้น
การใช้โมเดลแมชชีนเลิร์นนิงแบบกำกับเพื่อพยากรณ์อารมณ์ความรู้สึก
ต่อไปจะใช้โมเดลแมชชีนเลิร์นนิงแบบกำกับเพื่อพยากรณ์อารมณ์ความรู้สึก เนื่องจากเป้าหมายคือประเมินว่าอารมณ์จากรีวิวใหม่จัดอยู่ในหมวดบวกหรือลบ โดยอ้างอิงจากรีวิวที่ติดป้ายกำกับไว้แล้ว เราจึงกำลังจัดการกับปัญหาจำแนกประเภทอีกครั้ง คราวนี้มาลองใช้อัลกอริทึมโลจิสติกรีเกรสชันและวัดความแม่นยำของโมเดล:
Accuracy score: 0.754
Confusion matrix:
[[37.62772101 13.23856064]
[11.32829853 37.80541981]]
จะเห็นว่าโมเดลติดป้ายกำกับรีวิวที่เป็นบวกทั้งหมด 11% ว่าเป็นลบ และ 13% ว่าเป็นบวกทั้งที่เป็นลบ วิธีต่อไปที่อาจช่วยเพิ่มความแม่นยำของโมเดล ได้แก่ การตัดคำหยุด (เช่น คำที่มีข้อมูลต่ำแต่พบได้บ่อยมากอย่าง "about", "will", "you" เป็นต้น) และการเพิ่มขนาดคลังคำ
เมื่อใช้วิธี BOW เราอาจได้ฟีเจอร์ใหม่เป็นหลักร้อยหรือหลักพันคอลัมน์ในดาต้าเฟรม ซึ่งอาจนำไปสู่การสร้างโมเดลที่ซับซ้อนเกินไป มีการ overfit และมีฟีเจอร์กับพารามิเตอร์ที่ไม่จำเป็นมากเกินไป วิธีหนึ่งที่ช่วยแก้คือการทำ regularization ซึ่งจำกัดฟังก์ชันของโมเดล พารามิเตอร์ที่ต้องปรับคือ C ซึ่งแทนความแรงของ regularization มาลองทดสอบค่า C สองค่า: 100 และ 0.1 แล้วดูว่าค่าใดให้ประสิทธิภาพดีที่สุดบนข้อมูลทดสอบ:
lr_1 = LogisticRegression(C=100)
lr_1.fit(X_train, y_train)
predictions_1 = lr_1.predict(X_test)
lr_2 = LogisticRegression(C=0.1)
lr_2.fit(X_train, y_train)
predictions_2 = lr_2.predict(X_test)
print(f'Accuracy score, lr_1 model: {round(accuracy_score(y_test, predictions_1), 3)}\n'
f'Accuracy score, lr_2 model: {round(accuracy_score(y_test, predictions_2), 3)}\n\n'
f'Confusion matrix for lr_1 model, %:\n{confusion_matrix(y_test, predictions_1)/len(y_test)*100}\n\n'
f'Confusion matrix for lr_2 model, %:\n{confusion_matrix(y_test, predictions_2)/len(y_test)*100}')
Accuracy score, lr_1 model: 0.753
Accuracy score, lr_2 model: 0.756
Confusion matrix for lr_1 model, %:
[[37.53887161 13.32741004]
[11.32829853 37.80541981]]
Confusion matrix for lr_2 model, %:
[[37.67214571 13.19413594]
[11.19502443 37.93869391]]
ความต่างของความแม่นยำเมื่อใช้ค่าพารามิเตอร์ C ที่เลือกมานั้นน้อยมาก อาจหาได้ค่าที่ช่วยเพิ่มประสิทธิภาพของโมเดลมากขึ้นโดยทดลองกับค่าอื่นเพิ่มเติม อย่างไรก็ตาม ที่นี่เรามีฟีเจอร์ใหม่เพียง 200 ตัว โมเดลจึงไม่ซับซ้อนนัก และขั้นตอน regularization จึงไม่จำเป็นมากในกรณีนี้
แทนที่จะพยากรณ์ป้ายกำกับ 0 หรือ 1 ด้วยฟังก์ชัน predict สามารถพยากรณ์ความน่าจะเป็นของอารมณ์ได้ด้วย predict_proba ทั้งนี้ต้องคำนึงว่าไม่สามารถนำ accuracy score หรือ confusion matrix มาใช้กับค่าความน่าจะเป็นโดยตรงได้ เพราะเมตริกเหล่านี้ทำงานกับคลาสเท่านั้น จึงต้องเข้ารหัสกลับเป็นคลาสอีกครั้ง โดยปริยายแล้ว ความน่าจะเป็นตั้งแต่ 0.5 ขึ้นไปจะแปลงเป็นคลาส 1 มิฉะนั้นเป็นคลาส 0
lr = LogisticRegression()
lr.fit(X_train, y_train)
# Predicting the probability of the 0 class
predictions_prob_0 = lr.predict_proba(X_test)[:, 0]
# Predicting the probability of the 1 class
predictions_prob_1 = lr.predict_proba(X_test)[:, 1]
print(f'First 10 predicted probabilities of class 0: {predictions_prob_0[:10].round(3)}\n'
f'First 10 predicted probabilities of class 1: {predictions_prob_1[:10].round(3)}')
First 10 predicted probabilities of class 0: [0.246 0.143 0.123 0.708 0.001 0.828 0.204 0.531 0.121 0.515]
First 10 predicted probabilities of class 1: [0.754 0.857 0.877 0.292 0.999 0.172 0.796 0.469 0.879 0.485]
สรุป
ยังมีแนวทางที่เป็นประโยชน์อีกมากมายที่สามารถประยุกต์ใช้กับชุดข้อมูลเพื่อทำการวิเคราะห์อารมณ์เชิงลึกมากขึ้น:
- ใช้ n-grams (ชุดคำ) แทนคำเดี่ยวเพื่อคงบริบท
- ตัดคำหยุด
- จำกัดขนาดคลังคำโดยอิงจากค่าความถี่สูงสุดหรือต่ำสุด
- สร้างฟีเจอร์เชิงตัวเลขเพิ่มเติมเพื่ออธิบายความยาวของแต่ละรีวิวหรือจำนวนเครื่องหมายวรรคตอน (ซึ่งบางครั้งสัมพันธ์กับความรุนแรงของอารมณ์)
- ตัดตัวเลข อักขระบางชนิด คำที่ยาวตามเกณฑ์หนึ่ง หรือพิจารณาแพตเทิร์นคำที่ซับซ้อนกว่า
- ใช้ stemming และ lemmatization คือการลดคำให้เหลือรากศัพท์
- ใช้วิธีที่ซับซ้อนกว่า BOW ในการสร้างคลังคำ เช่น TfIdf (term frequency–inverse document frequency) ที่คำนึงถึงความถี่ของคำในรีวิวเทียบกับรีวิวอื่นๆ
- ใช้ไลบรารีเฉพาะทางเพื่อการวิเคราะห์อารมณ์ เช่น TextBlob, SentiWordNet, VADER (Valence Aware Dictionary and Sentiment Reasoner)
หากสนใจสำรวจเทคนิคเหล่านี้และวิธีที่มีประโยชน์อื่นๆ สำหรับการวิเคราะห์อารมณ์อย่างมีอินไซต์ ลองดูคอร์ส Sentiment Analysis in Python ได้เลย