0Pricing
R Academy · درس

تحليل TF-IDF وتكرار المصطلحات

قيّم أهمية المصطلحات عبر المستندات باستخدام bind_tf_idf()

تحليل TF-IDF وتكرار المصطلحات درس مجاني في R Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.

ما 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) إطار بيانات منظّمًا للتعداد، وتضيف إليه ثلاثة أعمدة: 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 النص الكامل لست روايات لأوستن. وهذا مثال تقليدي لاختبار TF-IDF؛ إذ يستطيع محبو أوستن تحديد المفردات المميزة لكل رواية، فكلمة "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 المنظّم إلى مصفوفة مستند-مصطلح باستخدام 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 بعض القيود: فهو يتعامل مع الكلمات بوصفها مستقلة، ويتجاهل ترتيب الكلمات والسياق، وقد تهيمن عليه الأخطاء الإملائية النادرة. وتشمل البدائل الحديثة تضمينات الكلمات (word2vec وGloVe) والتضمينات السياقية (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_idf
  • تُظهر arrange(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 وتكرار المصطلحات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.

ماذا ستتعلم في «تحليل TF-IDF وتكرار المصطلحات»؟

قيّم أهمية المصطلحات عبر المستندات باستخدام bind_tf_idf() تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟

لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تحليل TF-IDF وتكرار المصطلحات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟

نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تجزئة النص وإزالة كلمات التوقف
  2. تحليل TF-IDF وتكرار المصطلحات
  3. تحليل المشاعر في R
  4. نمذجة الموضوعات باستخدام LDA
← العودة إلى R Academy