R Academy · درس

تحليل المشاعر في R

صِل الرموز بمعاجم المشاعر لقياس النبرة الإيجابية والسلبية

الدرس 3 من 413 خطوة

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

نظرة عامة على تحليل المشاعر

يسند تحليل المشاعر قيمة عاطفية إلى النص. ويطابق منهج tidytext الكلمات المفردة مع معجم مشاعر، ثم يجمع الدرجات. تتوفر ثلاثة معاجم مضمّنة: AFINN (درجات رقمية)، وBing (إيجابي/سلبي)، وNRC (فئات المشاعر).

library(tidytext)

# Available sentiment lexicons
# AFINN: -5 to +5 numeric score
# Bing:  binary positive/negative
# NRC:   emotion categories (joy, fear, anger, ...)

# Preview AFINN
afinn_sample <- get_sentiments('afinn')
cat('AFINN rows:', nrow(afinn_sample), '\n')
cat('Score range:', range(afinn_sample$value), '\n')
print(head(afinn_sample, 5))

get_sentiments('afinn')

يسند معجم AFINN درجات صحيحة من −5 (سلبي جدًا) إلى +5 (إيجابي جدًا) إلى 2,477 كلمة إنجليزية. وقد جمعه Finn Årup Nielsen، ويعمل جيدًا مع نصوص وسائل التواصل الاجتماعي والمراجعات.

library(tidytext)
library(dplyr)

afinn <- get_sentiments('afinn')

# Most positive and most negative words
cat('Most positive words:\n')
print(afinn |> slice_max(value, n = 5))

cat('\nMost negative words:\n')
print(afinn |> slice_min(value, n = 5))

# Score distribution
cat('\nScore distribution:\n')
print(table(afinn$value))

get_sentiments('bing')

يصنّف معجم Bing (من إعداد Bing Liu وآخرين) 6,786 كلمة على أنها إيجابية أو سلبية. وهو أكبر من AFINN، ومناسب لمراجعات المنتجات وملاحظات العملاء التي تكفي فيها القطبية البسيطة.

library(tidytext)
library(dplyr)

bing <- get_sentiments('bing')

cat('Bing lexicon size:', nrow(bing), '\n')
cat('Positive words:', sum(bing$sentiment == 'positive'), '\n')
cat('Negative words:', sum(bing$sentiment == 'negative'), '\n')

# Sample positive and negative words
cat('\nSample positive:', head(bing$word[bing$sentiment == 'positive'], 8), '\n')
cat('Sample negative:', head(bing$word[bing$sentiment == 'negative'], 8), '\n')

inner_join: تسجيل الكلمات

تحتفظ inner_join(tokens, afinn, by = 'word') فقط بالرموز التي تظهر في معجم AFINN، وتضيف درجاتها. أما الكلمات غير الموجودة في المعجم فتُحذف بصمت — وهذا يُعد ميزةً لأنه يركّز على كلمات المشاعر المعروفة، وقيدًا في الوقت نفسه.

library(tidytext)
library(dplyr)

reviews <- tibble::tibble(
  review_id = 1:3,
  text = c(
    'The product is excellent and outstanding quality',
    'Terrible experience, broken and disappointing',
    'Good value but slow delivery, acceptable overall'
  )
)

scored <- reviews |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('afinn'), by = 'word')

cat('Scored words:\n')
print(scored[, c('review_id', 'word', 'value')])

صافي المشاعر لكل مستند

اجمع درجات AFINN لكل مستند باستخدام group_by(document) |> summarise(sentiment = sum(value)) للحصول على درجة صافي المشاعر. تشير المجاميع الموجبة إلى مشاعر إيجابية عامة، بينما تشير المجاميع السالبة إلى مشاعر سلبية.

library(tidytext)
library(dplyr)

reviews <- tibble::tibble(
  review_id = 1:5,
  text = c(
    'excellent outstanding perfect love best amazing',
    'terrible broken horrible awful waste money',
    'good acceptable okay decent average',
    'brilliant fantastic outstanding love recommend',
    'poor bad disappointing slow useless'
  )
)

net_sentiment <- reviews |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('afinn'), by = 'word') |>
  group_by(review_id) |>
  summarise(
    sentiment  = sum(value),
    word_count = n()
  ) |>
  mutate(polarity = ifelse(sentiment > 0, 'positive', 'negative'))

print(net_sentiment)

مشاعر Bing: عدد الكلمات الإيجابية مقابل السلبية

باستخدام معجم Bing، قارن عدد الكلمات الإيجابية والسلبية لكل مستند. احسب sentiment = positive_n - negative_n للحصول على درجة صافي القطبية، أو مثّل العددين في أعمدة مجمّعة لرؤية مكوّناتهما.

library(tidytext)
library(dplyr)

corpus <- tibble::tibble(
  chapter = 1:4,
  text = c(
    'the hero was brave courageous strong and victorious in battle',
    'disaster struck terrible losses failure defeat mourning grief',
    'love joy happiness beautiful peaceful wonderful morning',
    'evil darkness corrupt wicked terrible pain suffering fear'
  )
)

bing_sentiment <- corpus |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('bing'), by = 'word') |>
  count(chapter, sentiment) |>
  tidyr::pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) |>
  mutate(net = positive - negative)

print(bing_sentiment)

المشاعر حسب الفصل أو القسم

لتتبّع المشاعر عبر مسار سردي، احسب صافي المشاعر لكل فصل أو لكل نافذة متحركة. يكشف ذلك البنية العاطفية: تصاعد الأحداث، والذروة، والحل. استخدم ggplot2 مع geom_line() أو geom_bar() لعرض المسار بصريًا.

library(tidytext)
library(dplyr)
library(ggplot2)

# Simulate a 10-chapter story arc
set.seed(42)
chapters <- tibble::tibble(
  chapter = 1:10,
  text    = c(
    'peaceful beautiful joy love happy wonderful',
    'good friends happy carefree enjoyable fun',
    'worried anxious trouble fear uncertain dark',
    'danger terrible threat awful pain suffering',
    'fear horror disaster terrible devastation loss',
    'fight battle struggle hard difficult challenge',
    'hope courage determination brave strong resist',
    'triumph victory success celebrate joy love',
    'relief peace gratitude wonderful blessed happy',
    'love joy peace beautiful grateful wonderful'
  )
)

arc <- chapters |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('afinn'), by = 'word') |>
  group_by(chapter) |>
  summarise(net_sentiment = sum(value))

ggplot(arc, aes(chapter, net_sentiment)) +
  geom_line(color = 'steelblue', linewidth = 1.2) +
  geom_hline(yintercept = 0, linetype = 'dashed') +
  labs(x = 'Chapter', y = 'Net Sentiment', title = 'Story Sentiment Arc') +
  theme_minimal()

معجم NRC: فئات المشاعر

يصنّف معجم NRC (Saif Mohammad وPeter Turney) عددًا قدره 13,901 كلمة ضمن ثمانية مشاعر (الغضب، والترقّب، والاشمئزاز، والخوف، والفرح، والحزن، والمفاجأة، والثقة)، بالإضافة إلى الإيجابية والسلبية. صفِّ النتائج حسب المشاعر باستخدام filter(sentiment == 'joy').

library(tidytext)
library(dplyr)

nrc <- get_sentiments('nrc')
cat('NRC size:', nrow(nrc), '\n')
cat('Emotions:', paste(unique(nrc$sentiment), collapse = ', '), '\n')

# Words associated with 'joy'
joy_words <- nrc |> filter(sentiment == 'joy')
cat('\nJoy words:', nrow(joy_words), '\n')
cat('Sample:', head(joy_words$word, 10), '\n')

# Count words per emotion
nrc |>
  count(sentiment, sort = TRUE) |>
  print()

تطبيق NRC على مجموعة نصوص

اربط النص المُجزّأ إلى رموز مع NRC لتسجيل كل شعور على حدة. اجمع النتائج حسب المستند والشعور باستخدام count(doc_id, sentiment) لمعرفة المشاعر المهيمنة في كل مستند.

library(tidytext)
library(dplyr)

docs <- tibble::tibble(
  doc_id = c(1, 1, 2, 2, 3, 3),
  text   = c(
    'wonderful joyful happy love peace',
    'excited surprise anticipation trust',
    'fear anger terrible hate disgust',
    'dark horrible awful suffering pain',
    'curious wonder discovery learning',
    'hope trust anticipation future growth'
  )
)

nrc_scores <- docs |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('nrc'), by = 'word') |>
  filter(!sentiment %in% c('positive', 'negative')) |>  # keep only emotions
  count(doc_id, sentiment, sort = TRUE)

cat('Emotion counts per document:\n')
print(nrc_scores)

مفهوم سحابة الكلمات

تُصوّر سحابة الكلمات تكرارات الكلمات، بحيث يُعرض حجم كل كلمة بما يتناسب مع عدد مرات ظهورها. تنشئ الحزمتان wordcloud وwordcloud2 هذه السحابات انطلاقًا من إطار بيانات للكلمات وتكراراتها. لوّن الكلمات حسب المشاعر باستخدام معجم Bing لإنشاء سحابة ملوّنة وفقًا للمشاعر.

library(tidytext)
library(dplyr)

# Prepare word frequencies coloured by Bing sentiment
corpus_text <- tibble::tibble(
  text = c(
    'excellent performance amazing results love beautiful',
    'terrible failure poor broken horrible waste',
    'brilliant outstanding success happy wonderful joy',
    'awful disappointing bad slow useless frustrating'
  )
)

word_freq <- corpus_text |>
  unnest_tokens(word, text) |>
  count(word, sort = TRUE) |>
  left_join(get_sentiments('bing'), by = 'word') |>
  mutate(
    sentiment = replace(sentiment, is.na(sentiment), 'neutral'),
    colour    = case_when(
      sentiment == 'positive' ~ '#2196F3',
      sentiment == 'negative' ~ '#F44336',
      TRUE                    ~ '#9E9E9E'
    )
  )

print(word_freq)
# In practice: wordcloud2(word_freq[, c('word','n')], color = word_freq$colour)

قيود تحليل المشاعر القائم على المعاجم

يتضمن تحليل المشاعر القائم على المعاجم حالات فشل معروفة: النفي (تُسجَّل عبارة "not good" على أنها إيجابية)، والسخرية ("oh great, another bug")، وعدم تطابق المجال (كلمة "sick" إيجابية في اللغة العامية)، والكلمات غير الموجودة في المفردات. ضع هذه القيود في اعتبارك عند تفسير النتائج.

library(tidytext)
library(dplyr)

# Negation problem
neg_examples <- tibble::tibble(
  text = c(
    'not good at all',   # negative, but 'good' scores +3
    'not bad',           # positive, but 'bad' scores -3
    'sick beats bro'     # slang positive, 'sick' is negative in AFINN
  )
)

scored <- neg_examples |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('afinn'), by = 'word')

cat('Lexicon scores (naive - ignores negation):\n')
print(scored[, c('word', 'value')])
cat('\nNote: "not" is a stop word - the negation is lost!\n')

تحقّق سريع

تستخدم inner_join(tokens, afinn, by = 'word') لتسجيل المشاعر. ماذا يحدث للكلمات الموجودة في الرموز لديك والتي لا توجد في معجم AFINN؟

مراجعة: تحليل المشاعر

أهم النقاط:

  • المعاجم الرئيسية الثلاثة: AFINN (درجات من −5 إلى +5)، وBing (إيجابي/سلبي)، وNRC (8 مشاعر)
  • تسترجع get_sentiments('afinn') / 'bing' / 'nrc' المعجم في صورة tibble
  • تسجّل inner_join(tokens, lexicon, by = 'word') الكلمات المتطابقة فقط (وتُحذف الكلمات غير المتطابقة)
  • صافي المشاعر = group_by(doc) |> summarise(sentiment = sum(value))
  • في Bing: قارن عدد الكلمات positive - negative لكل مستند أو قسم
  • في NRC: صفِّ النتائج حسب اسم الشعور لعزل الخوف والفرح والغضب وغير ذلك
  • القيد الرئيسي: لا تتعامل الأساليب القائمة على المعاجم مع النفي أو السخرية أو العامية الخاصة بالمجال
library(tidytext)
library(dplyr)

tibble::tibble(text = 'excellent amazing love joy beautiful happy') |>
  unnest_tokens(word, text) |>
  inner_join(get_sentiments('afinn'), by = 'word') |>
  summarise(net_sentiment = sum(value)) |>
  print()
البدء مجانًا

تعلم R مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
43
الدروس
159

الأسئلة الشائعة

هل درس «تحليل المشاعر في R» مجاني؟

نعم — نص درس «تحليل المشاعر في R» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.

ماذا ستتعلم في «تحليل المشاعر في R»؟

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

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

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

كم من الوقت يستغرق درس «تحليل المشاعر في R»؟

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

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

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

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

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