العودة إلى المدونة

تحليل مشاعر Twitter باستخدام Spark

تحليل مشاعر Twitter باستخدام Spark

في منشورنا السابق، توصلت إلى طريقة لاستخراج بيانات Twitter في الوقت الفعلي باستخدام Apache Flume. حاليًا، حصلت على الكثير من البيانات من Twitter. لذلك، أود تحليلها واستخراج بعض الاتجاهات منها. ومن أجل إجراء تحليل المشاعر لبيانات Twitter، سأستخدم أداة أخرى للبيانات الضخمة، وهي Apache Spark.

وفقًا لـ Hortonworks, “إن Apache Spark هو محرك سريع لمعالجة البيانات في الذاكرة مع واجهات برمجة تطبيقات تطوير أنيقة ومعبرة للسماح للعاملين في مجال البيانات بتنفيذ مهام البث أو التعلم الآلي أو أعباء عمل SQL بكفاءة والتي تتطلب وصولاً تكراريًا سريعًا إلى مجموعات البيانات. ومع تشغيل Spark على Apache Hadoop YARN، يمكن للمطورين في كل مكان الآن إنشاء تطبيقات لاستغلال قوة Spark، واستخلاص الأفكار، وإثراء أعباء عمل علم البيانات الخاصة بهم ضمن مجموعة بيانات واحدة مشتركة في Hadoop.”

يمكن كتابة برنامج Spark بلغة JAVA أو Scala أو Python أو R. وفي هذه الحالة، سنستخدم JAVA جنبًا إلى جنب مع Maven. بالإضافة إلى ذلك، يأتي Spark مع كل من توزيعتي HDP و Cloudera. الإصدار Spark 2 هو الإصدار الحالي المستخدم.

من أجل إجراء تحليل المشاعر باستخدام Spark، أقوم بإنشاء مشروع Maven جديد. وسأطلق عليه اسم Twitter Sentiment Analyzer’. بعد ذلك، أقوم بإنشاء فئة باسم “TwitterDataFlow.java” والتي سأقوم فيها بتنفيذ جميع الطرق المطلوبة.

أداة اللغة: مصحح الأخطاء الإملائية

في البداية، في إثبات المفهوم (POC)، وجدت أنه إذا كان الإملاء في التغريدات خاطئًا، فإن نتائج تحليل المشاعر تتأثر سلبًا. لذلك، سأقوم بتقديم SpellChecker. سيساعدنا ذلك في تصحيح إملاء التغريدات قبل استخدامها في تحليل المشاعر.

سأقوم بذلك عن طريق إنشاء طريقة ثابتة جديدة باسم ‘CorrectSpell’. علاوة على ذلك، سأستخدم LanguageTool للتحقق من الإملاء وتصحيحه.

وفقًا لـ GIT الخاص بـ LanguageTool’s, “إن LanguageTool هو برنامج تدقيق لغوي مفتوح المصدر للغات الإنجليزية والفرنسية والألمانية والبولندية والروسية وأكثر من 20 لغة أخرى. فهو يكتشف العديد من الأخطاء التي لا يمكن لمصحح إملائي بسيط اكتشافها.”

بعد ذلك، سأقوم بإضافة تبعية لأداة اللغة في ملف pom.xml:

<dependency>
<groupId>org.languagetool</groupId>
<artifactId>language-en</artifactId>
<version>4.0</version>
</dependency>

بعد ذلك، أقوم بتعريف متغير ثابت على مستوى الفئة langTool من الفئة JLanguageTool. ثم أقوم بتهيئة langTool بكائن من الفئة AmericanEnglish.

بعد ذلك، أقوم بكتابة كود الطريقة المسماة SpellChecker مع إدخال كـ String text (نص عادي) ونوع إرجاع كـ String (نص ذو إملاء صحيح) أيضًا. سأستخدم طريقة check الخاصة بـ JLanguageTool مع تمرير النص غير المفحوص كمعلمة. بعد ذلك، تقوم بإرجاع قائمة من RuleMatch. وفقًا لمستندات JLanguageTool Java Docs، توفر فئة RuleMatch “معلومات حول قاعدة الخطأ التي تطابق النص وموضع المطابقة.”

بعد ذلك، أقوم بتعريف ثلاثة متغيرات، ‘result’ من نوع String، و ‘lastPos’ من نوع integer، و ‘tmp’ من نوع String. بالإضافة إلى ذلك، مع كل RuleMatch، أقوم بإعادة إنشاء الجملة باستخدام أول إملاء مقترح من الأداة. ومع ذلك، قمت بإضافة كتل try-catch اللازمة عند الحاجة.

 

محلل المشاعر: Stanford CoreNLP

الخطوة التالية في تحليل المشاعر باستخدام Spark هي العثور على المشاعر من النص. للقيام بذلك، أستخدم مكتبة Stanford’s Core NLP للعثور على قيم المشاعر. بعد ذلك، أقوم بإنشاء فئة باسم ‘StanfordSentiment’ حيث سأقوم بتطبيق المكتبة للعثور على المشاعر داخل نصنا.

للقيام بذلك، أقوم بإضافة التبعيات التالية في ملف pom.xml:

<!– هذه هي مكتبة stanford Core NLP –>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
</dependency>

<!– هذا هو ملف نماذج stanford Core NLP’s –>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
<classifier>models</classifier>
</dependency>

أقوم بإنشاء متغير كائن ثابت، ‘props’، والذي يحدد خصائص خط أنابيب Stanford Core NLP. لقد اخترت الحد الأدنى من الخصائص لجعله خفيفًا قدر الإمكان. بعد ذلك، أقوم بتعيين أدوات التعليق التوضيحي إلى tokenize، ssplit، pos، parse، sentiment. أقوم بإنشاء متغير كائن ثابت آخر، ‘pipeline’ من الفئة StanfordCoreNLP. أخيرًا، أقوم بتهيئة خط الأنابيب باستخدام خصائص ‘props’.

GetSentiment:

لقد أنشأت دالة باسم GetSentiment بمدخلات كـ String ومخرجات كـ Double. أستخدم دالة CorrectSpell التي أنشأتها في ملف LanguageCheck.java. تعيد لي دالة CorrectSpell لكائن LanguageCheck التهجئة الصحيحة للتغريدة المدخلة. أستخدم دالة annotate لـ StanfordCoreNLP مع هذا النص المصحح. قيم المشاعر التي تقدمها هذه المكتبة هي:

0 => سلبي جدًا

1 => سلبي

2 => محايد

3 => إيجابي

4 => إيجابي جدًا

 

أقوم بطرح النتيجة بمقدار 2 لكل جملة للحصول على فئات المشاعر الجديدة التالية:

-2 => سلبي جدًا

-1 => سلبي

0 => محايد

1 => إيجابي

2 => إيجابي جدًا

 

أقوم بإرجاع نتيجة مشاعر كل تغريدة كمتوسط لمشاعر كل جملة في التغريدة. لا تتم كتابة التغريدات بأي تنسيق منظم. وبالتالي، لا يمكنني تخصيص وزن أعلى لسطر معين من التغريدة مقارنة بالأسطر الأخرى. لذلك، أفترض أن كل سطر في التغريدة له أهمية متساوية. أقوم بإرجاع المتغير ‘total’ من النوع Double والذي يحتوي على قيمة المشاعر الناتجة للتغريدة.

 

بدء البرنامج:

الآن بعد أن انتهينا من هاتين الفئتين، سنمضي قدمًا لاستخدامهما. وبالتالي، أقوم بإنشاء فئة جديدة، “TwitterDataFlow.java”. أولاً، أقوم بكتابة فحص شرطي يقوم بتشغيل البرنامج فقط إذا كان عدد وسيطات الإدخال التي تم تمريرها هو 2 تمامًا. إذا لم يكن عدد الوسيطات مساويًا لـ 2، فإنه يطبع رسالة الاستخدام غير الصحيحة ويخرج أيضًا بحالة خروج 1.

أقوم ببناء SparkSession باسم تطبيق Sentiment Analyzer. أقوم بتعيين خاصية تكوين hadoop لـ spark context، وهي “mapreduce input fileinputformat input dir recursive” كـ true. سيسمح لي هذا باسترداد الملفات بشكل متكرر من المجلدات. أقوم بإنشاء متغير، ‘inputPath’ من الفئة String حيث أقوم بتعيين وسيطة الإدخال بالإضافة إلى ‘/*/*’ مما سيسمح لي بقراءة البيانات المقسمة المخزنة بواسطة Flume. أقوم بقراءة بيانات json الخاصة بـ Flume في Dataset<Row> ‘data’.

بعد ذلك، أقوم بتسجيل UDF (وظيفة محددة من قبل المستخدم) مع Spark SQL Context، باسم ‘Sentiment’ والتي تأخذ String وتطبق طريقة GetSentiment الخاصة بـ StanfordSentiment عليها وتعيد نوع بيانات القيمة Double.

حالياً، لدي بيانات للكلمات الرئيسية Apple و Google و Tesla و Infosys و TCS و Oracle و Microsoft و Facebook من flume. لذلك، أقوم بإنشاء قائمة من String بهذه الكلمات الرئيسية. لكل شركة من هذه الشركات، أقوم بتشغيل العمليات التالية.

تدفق العمليات:

أولاً، أقوم بإنشاء outPath حيث أريد حفظ النتائج. أقوم بإنشاء عرض مؤقت، ‘complete’ على مجموعة البيانات، ‘data’. بعد ذلك، أقوم باستخراج timestamp و partitionBy (من أجل تقسيم البيانات أثناء تخزين النتائج) و text و main_text (لاستخدامها في التعبيرات العادية) و followers من البيانات.

أقوم بإنشاء عرض مؤقت على النتائج وتصفية بيانات شركة معينة من ذلك. أيضًا، أقوم بتطبيق Sentiment UDF، والذي يعيد لي قيم المشاعر في العمود ‘seVal’. أقوم بحفظ البيانات المتسلسلة في الذاكرة وكمساحة قرص احتياطية. من هذه البيانات، أحصل على NetSentiment، وهو حاصل ضرب عدد المتابعين وقيمة المشاعر لتلك التغريدة. يساعد هذا في معرفة التأثير الذي يمكن أن تحدثه تلك التغريدة. يمكنني الحصول على صيغ مختلفة لنفس الشيء.

نحن نقوم بحفظ البيانات المتسلسلة في الذاكرة والقرص لأننا نريد تخزين النتيجة بأكملها، حيث أن تحليل المشاعر هو مهمة حسابية ثقيلة. إذا لم نقم بحفظ هذا وخططنا لاستخدام صيغ متعددة لحساب NetSentiment أو التأثير، في الاستعلام السابق حيث سنستخدم قيمة طريقة Sentiment عدة مرات، فإنه سيقوم بإجراء تحليل المشاعر للتغريدة عدة مرات.

تجميع البيانات:

الآن، أقوم بتجميع البيانات حسب الطابع الزمني وعمود partitionBy وحساب متوسط NetSentiment مع هذا التجميع. يعطيني هذا متوسط تأثير الشركة، إيجابيًا أو سلبيًا في دقيقة معينة. وبناءً على ذلك، أقوم بكتابة النتائج لكل شركة في outPath وتقسيمها حسب عمود partitionBy.

أيضًا، بعد اكتمال الكود، أقوم بتصدير ملف jar قابل للتشغيل يحتوي على جميع التبعيات ونسخه إلى الخادم، حيث أريد تشغيل هذه المهمة. بعد ذلك، يمكنني تقديمه باستخدام الأمر التالي،

حيث (المصدر):

  • --deploy-mode: ما إذا كان سيتم نشر برنامج التشغيل (driver) الخاص بك على عقد العمل (cluster) أو محليًا كعميل خارجي (client) (الافتراضي: client)
  • application-jar: المسار إلى ملف jar مجمع يتضمن تطبيقك وجميع التبعيات. ضع في الاعتبار أن عنوان URL يجب أن يكون مرئيًا بشكل عام داخل العنقود الخاص بك، على سبيل المثال، مسار hdfs:// أو مسار file:// موجود على جميع العقد.
  • application-arguments: الوسائط التي يتم تمريرها إلى الدالة الرئيسية (main method) للفئة الرئيسية الخاصة بك، إن وجدت. هنا، مسار الإدخال والإخراج

الخطوات النهائية:

بعد ذلك، سنحصل على نتائج تحليل المشاعر باستخدام Spark من مسار الإخراج. على سبيل المثال، هذه نتيجة محتملة لـ apple:

{“timestamp”:”Apr 30 2018 20:31:00″,”avg(NetSentiment)”:-3678.768518518518}
{“timestamp”:”Apr 30 2018 20:32:00″,”avg(NetSentiment)”:-883.002824858757}

لقد قمت بنشر هذا التطبيق على CloudSigma مع عنقود HDP مكون من 5 عقد. وتحديدًا، تتمتع كل عقدة بالتكوين التالي:

256 جيجابايت SSD
16 جيجابايت رام
20 جيجاهرتز معالج

بشكل عام، تمكنت من الحصول على نتائج تحليل المشاعر باستخدام Spark في غضون 19 ساعة تقريبًا. علاوة على ذلك، قمت بتضمين حسابات أكثر تقدمًا من البرنامج على مجموعة بيانات تزيد عن 80 جيجابايت.

يمكن العثور على الكود على GITHUB.

 

author

Akshay Nagpal

المؤلف · CloudSigma

Preslav Dobrev هو مصمم إبداعي في CloudSigma، يركز على هوية أعمال متسقة باستخدام قنوات التسويق التقليدية والمبتكرة. هو بارع في دمج الرؤية الفنية مع التسويق الاستراتيجي لخلق سرد قصصي مؤثر للعلامة التجارية.

التعليقات

لا توجد تعليقات بعد. كن أول من يعلق.