TF-IDF และการวิเคราะห์ความถี่ของคำ
ให้คะแนนความสำคัญของคำในเอกสารต่าง ๆ ด้วย bind_tf_idf()
TF-IDF และการวิเคราะห์ความถี่ของคำ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
TF-IDF คืออะไร
TF-IDF (ความถี่ของคำ–ความถี่ผกผันของเอกสาร) ใช้วัดว่าคำหนึ่งมีความโดดเด่นต่อเอกสารใดเอกสารหนึ่งภายในคลังข้อความเพียงใด คะแนน TF-IDF สูงหมายความว่าคำนั้นปรากฏบ่อยในเอกสารดังกล่าว แต่พบได้น้อยในเอกสารทั้งหมด จึงเป็นตัวบ่งชี้ที่ดีของหัวข้อสำคัญในเอกสาร
# TF-IDF formula
# TF(w, d) = count of w in document d / total words in d
# IDF(w) = log(N / number of docs containing w)
# TF-IDF(w, d) = TF(w, d) * IDF(w)
# Manual example
N <- 4 # total documents
docs_with_word <- 1 # 'neural' appears in only 1 doc
tf <- 5 / 100 # word appears 5 times in 100-word doc
idf <- log(N / docs_with_word)
tfidf <- tf * idf
cat('TF: ', round(tf, 4), '\n')
cat('IDF: ', round(idf, 4), '\n')
cat('TF-IDF: ', round(tfidf, 4), '\n')การเตรียมจำนวนโทเค็น
ก่อนคำนวณ TF-IDF คุณต้องมีดาต้าเฟรมที่ประกอบด้วยคอลัมน์ document (ตัวระบุเอกสาร), word (โทเค็น) และ n (จำนวนครั้ง) ให้ใช้ unnest_tokens() ตามด้วย count(document, word)
library(tidytext)
library(dplyr)
# Simulate a 4-document corpus on tech topics
docs <- tibble::tibble(
document = c(rep('ML', 3), rep('Stats', 3), rep('DB', 3), rep('Web', 3)),
text = c(
'machine learning neural networks training',
'deep learning models gradient descent',
'reinforcement learning reward policy agent',
'probability distributions hypothesis testing',
'bayesian inference regression analysis variance',
'statistics sampling confidence intervals normal',
'database sql joins indexes queries transactions',
'relational tables primary keys foreign constraints',
'nosql document store mongodb redis cassandra',
'html css javascript frontend react components',
'dom events browser api fetch requests',
'responsive design flexbox grid layout'
)
)
word_counts <- docs |>
unnest_tokens(word, text) |>
count(document, word, sort = TRUE)
cat('Document-word pairs:', nrow(word_counts), '\n')
print(head(word_counts, 8))bind_tf_idf: การคำนวณ TF-IDF
bind_tf_idf(word, document, n) รับดาต้าเฟรมจำนวนคำในรูปแบบ tidy แล้วเพิ่มสามคอลัมน์ ได้แก่ tf (ความถี่ของคำ), idf (ความถี่ผกผันของเอกสาร) และ tf_idf (ผลคูณของทั้งสองค่า) โดยคำนวณ IDF จากเอกสารที่มีอยู่ในดาต้าเฟรม
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c(rep('ML', 2), rep('Stats', 2), rep('DB', 2)),
text = c(
'machine learning neural gradient',
'deep networks training epochs',
'probability distributions variance covariance',
'bayesian inference prior posterior',
'sql database tables joins indexes',
'queries transactions foreign primary'
)
)
tfidf <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n)
cat('Columns added:', names(tfidf), '\n')
print(head(arrange(tfidf, desc(tf_idf)), 8))arrange(desc(tf_idf)): คำที่มีอันดับสูงสุด
เรียงตาม tf_idf จากมากไปน้อยเพื่อดูว่าคำใดบ่งบอกลักษณะของแต่ละเอกสารได้ดีที่สุด คำที่มี IDF เป็นศูนย์ (ปรากฏในทุกเอกสาร) จะมีค่า TF-IDF เป็นศูนย์ไม่ว่าจะมีความถี่เท่าใด เพราะไม่สามารถใช้แยกความแตกต่างระหว่างเอกสารได้
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c(rep('Python', 3), rep('R', 3), rep('Julia', 3)),
text = c(
'python pandas numpy scipy programming',
'machine learning scikit tensorflow keras',
'jupyter notebooks scripts debugging modules',
'ggplot2 dplyr tidyverse statistics vectors',
'shiny rmarkdown knitr cran bioconductor',
'linear models factors dataframes packages',
'julia multiple dispatch type system macros',
'package ecosystem flux diffeq parallel',
'scientific computing performance benchmarks'
)
)
top_terms <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n) |>
arrange(desc(tf_idf))
cat('Top distinctive terms per language:\n')
print(head(top_terms[, c('document', 'word', 'tf_idf')], 9))คำ TF-IDF อันดับสูงสุดในแต่ละเอกสาร
ใช้ group_by(document) |> slice_max(tf_idf, n = 5) เพื่อดึงคำที่มีความโดดเด่นสูงสุด N คำในแต่ละเอกสาร วิธีนี้เป็นการสรุปคลังข้อความที่มีประสิทธิภาพ เพราะคำศัพท์เฉพาะของแต่ละเอกสารจะแสดงให้เห็นอย่างชัดเจน
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c(rep('Cooking', 3), rep('Finance', 3), rep('Sports', 3)),
text = c(
'recipe ingredients oven bake flour butter',
'cooking temperature boil simmer saute',
'kitchen knife chopping herbs spices garnish',
'investment portfolio returns dividends stocks bonds',
'market equity risk hedge fund derivatives',
'inflation interest rate treasury balance sheet',
'goal tackle pass dribble goalkeeper penalty',
'tournament league championship trophy season',
'athlete training stamina sprint endurance'
)
)
top5 <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n) |>
group_by(document) |>
slice_max(tf_idf, n = 3) |>
ungroup()
print(top5[, c('document', 'word', 'tf_idf')])การแสดงภาพ TF-IDF ในแต่ละเอกสาร
แผนภูมิแท่งของคะแนน TF-IDF ที่แบ่งแผงตามเอกสารจะเผยให้เห็นคำศัพท์เฉพาะของแต่ละเอกสารได้ในทันที ใช้ facet_wrap(~document, scales = 'free_y') เพื่อให้แต่ละแผงแสดงคำอันดับต้น ๆ ของตนเองอย่างอิสระ
library(tidytext)
library(dplyr)
library(ggplot2)
docs <- tibble::tibble(
document = c(rep('AI', 3), rep('DB', 3), rep('Web', 3)),
text = c(
'neural networks gradient backpropagation',
'deep learning transformer attention bert',
'reinforcement policy reward exploration',
'sql database indexes joins transactions',
'relational schema normalization queries',
'nosql mongodb redis cassandra document',
'html css javascript react dom',
'frontend api fetch async components',
'responsive flexbox grid webpack bundle'
)
)
plot_data <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n) |>
group_by(document) |>
slice_max(tf_idf, n = 4) |>
ungroup()
ggplot(plot_data, aes(reorder(word, tf_idf), tf_idf, fill = document)) +
geom_col(show.legend = FALSE) +
facet_wrap(~document, scales = 'free_y') +
coord_flip() +
labs(x = NULL, y = 'TF-IDF', title = 'Top TF-IDF Terms per Topic') +
theme_minimal()IDF: คำที่ปรากฏในเอกสารทั้งหมด
คำที่ปรากฏในทุกเอกสารจะมีค่า IDF = log(N/N) = 0 และด้วยเหตุนี้ TF-IDF = 0 ระบบจึงลดน้ำหนักคำที่พบบ่อยทั่วทั้งคลังข้อความโดยอัตโนมัติ โดยไม่ต้องใช้รายการคำหยุด อย่างไรก็ตาม การลบคำหยุดยังมีประโยชน์สำหรับคลังข้อความขนาดเล็กมาก
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c('A', 'B', 'C'),
text = c(
'data analysis statistics regression probability',
'data engineering pipelines etl transformation',
'data visualisation ggplot2 charts dashboards'
)
)
tfidf <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n)
# 'data' appears in all 3 docs: tf_idf should be 0
data_rows <- filter(tfidf, word == 'data')
cat('TF-IDF for "data" across documents:\n')
print(data_rows[, c('document', 'word', 'idf', 'tf_idf')])การเปรียบเทียบเอกสารสองฉบับ
TF-IDF ช่วยให้เปรียบเทียบเอกสารได้ง่าย ค้นหาคำที่มี TF-IDF สูงในเอกสารหนึ่ง แต่มีค่าต่ำหรือเป็นศูนย์ในอีกเอกสารหนึ่ง เพื่อทำความเข้าใจว่าอะไรทำให้เอกสารแต่ละฉบับมีลักษณะเฉพาะ ใช้ inner join ตาราง TF-IDF ด้วย word แล้วเปรียบเทียบคะแนน
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c(rep('Doc1', 3), rep('Doc2', 3)),
text = c(
'bayesian statistics prior posterior mcmc',
'markov chain monte carlo sampling',
'probability distributions conjugate inference',
'convolutional neural network image classification',
'pooling activation relu softmax batch',
'convolution filter feature map stride padding'
)
)
tfidf <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n)
# Top 3 unique terms per document
tfidf |>
group_by(document) |>
slice_max(tf_idf, n = 3) |>
select(document, word, tf_idf) |>
print()TF-IDF กับนวนิยายของ Jane Austen
แพ็กเกจ janeaustenr มีข้อความฉบับเต็มของนวนิยาย Austen จำนวนหกเรื่อง นี่เป็นชุดทดสอบ TF-IDF แบบคลาสสิก แฟน ๆ ของ Austen สามารถระบุคำศัพท์เฉพาะของนวนิยายแต่ละเรื่องได้ โดยคำว่า "wentworth" แทบจะเป็นคำเฉพาะของ Persuasion เท่านั้น
library(tidytext)
library(dplyr)
# Requires janeaustenr package
# library(janeaustenr)
# austen_books() returns: book, text
# Simulated mini-Austen corpus
mini_austen <- tibble::tibble(
book = c(rep('Sense', 3), rep('Pride', 3), rep('Emma', 3)),
text = c(
'elinor marianne dashwood willoughby colonel',
'edward ferrars barton cottage sister sense',
'brandon feelings attachment sensibility heart',
'darcy bennet bingley netherfield wickham',
'jane lizzy lydia longbourn pemberley',
'pride prejudice proposal marriage happiness',
'emma woodhouse knightley harriet weston',
'highbury match social governess niece',
'frank jane fairfax box hill picnic'
)
)
top <- mini_austen |>
unnest_tokens(word, text) |>
count(book, word) |>
bind_tf_idf(word, book, n) |>
group_by(book) |>
slice_max(tf_idf, n = 3) |>
select(book, word, tf_idf)
print(top)TF-IDF สำหรับการสร้างคุณลักษณะ
สามารถใช้คะแนน TF-IDF เป็นคุณลักษณะในตัวจำแนกประเภทของการเรียนรู้ของเครื่องได้ แปลงผลลัพธ์ TF-IDF แบบ tidy เป็นเมทริกซ์เอกสาร-คำโดยใช้ cast_dtm() หรือ cast_sparse() แล้วส่งต่อให้ glmnet, xgboost หรือตัวจำแนกประเภทอื่น ๆ
library(tidytext)
library(dplyr)
docs <- tibble::tibble(
document = c(rep('Positive', 4), rep('Negative', 4)),
text = c(
'excellent product love recommend quality',
'amazing fast delivery five star perfect',
'great value money satisfied happy return',
'wonderful experience purchase outstanding best',
'terrible waste money broken arrived damaged',
'horrible quality slow delivery disappointed awful',
'poor value cheap plastic flimsy broken',
'worst experience refund needed useless junk'
)
)
# TF-IDF as features
tfidf_wide <- docs |>
unnest_tokens(word, text) |>
count(document, word) |>
bind_tf_idf(word, document, n) |>
cast_dtm(document, word, tf_idf)
cat('DTM dimensions:', dim(tfidf_wide), '\n')
cat('(rows=documents, cols=unique words)\n')ข้อจำกัดและทางเลือกอื่น
TF-IDF มีข้อจำกัด คือถือว่าคำต่าง ๆ เป็นอิสระต่อกัน ไม่สนใจลำดับคำและบริบท และอาจถูกครอบงำด้วยคำสะกดผิดที่พบได้ยาก ทางเลือกสมัยใหม่ ได้แก่ word embeddings (word2vec, GloVe) และ contextual embeddings (BERT) แต่ TF-IDF ยังคงยอดเยี่ยมสำหรับการค้นคืนเอกสารและใช้เป็นแบบจำลองพื้นฐานในการจำแนกประเภท
# TF-IDF strengths and weaknesses summary
criteria <- data.frame(
Criterion = c('Speed', 'Interpretability', 'Context', 'Word order',
'Rare words', 'Scalability'),
TF_IDF = c('Fast', 'High', 'None', 'Ignored',
'High IDF (inflated)', 'Excellent'),
BERT = c('Slow', 'Low', 'Rich', 'Captured',
'Handled', 'Moderate')
)
print(criteria, row.names = FALSE)ตรวจสอบอย่างรวดเร็ว
คำหนึ่งปรากฏในเอกสารทั้งหมดในคลังข้อความของคุณ คะแนน TF-IDF ของคำนั้นจะเป็นเท่าใด
สรุป: การวิเคราะห์ TF-IDF
ประเด็นสำคัญ:
- TF-IDF = ความถี่ของคำ × ความถี่ผกผันของเอกสาร คะแนนสูงหมายถึงคำที่มีความโดดเด่น
- ลำดับการทำงาน:
unnest_tokens()→count(document, word)→bind_tf_idf(word, document, n) bind_tf_idf()เพิ่มคอลัมน์tf,idfและtf_idfarrange(desc(tf_idf))/slice_max(tf_idf, n = 5)แสดงคำอันดับต้น ๆ ของแต่ละเอกสาร- คำที่อยู่ในเอกสารทั้งหมดจะมี IDF = 0 และ TF-IDF = 0 โดยอัตโนมัติ
cast_dtm(document, word, tf_idf)แปลงข้อมูลเป็นเมทริกซ์เอกสาร-คำสำหรับการเรียนรู้ของเครื่อง- แผนภูมิแท่งแบบแบ่งแผงเป็นรูปแบบการแสดงภาพมาตรฐานสำหรับผลลัพธ์ TF-IDF
library(tidytext)
library(dplyr)
# Minimal TF-IDF pipeline
tibble::tibble(
doc = c('A', 'A', 'B', 'B'),
text = c('neural networks deep', 'learning training', 'sql database query', 'joins indexes')
) |>
unnest_tokens(word, text) |>
count(doc, word) |>
bind_tf_idf(word, doc, n) |>
arrange(desc(tf_idf)) |>
print()คำถามที่พบบ่อย
บทเรียน “TF-IDF และการวิเคราะห์ความถี่ของคำ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “TF-IDF และการวิเคราะห์ความถี่ของคำ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “TF-IDF และการวิเคราะห์ความถี่ของคำ”
ให้คะแนนความสำคัญของคำในเอกสารต่าง ๆ ด้วย bind_tf_idf() คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “TF-IDF และการวิเคราะห์ความถี่ของคำ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การตัดคำเป็นโทเคนและการลบคำหยุด
- TF-IDF และการวิเคราะห์ความถี่ของคำ
- การวิเคราะห์ความรู้สึกใน R
- การสร้างโมเดลหัวข้อด้วย LDA