كيفية إنشاء روبوت لتحليل المشاعر عبر البريد الإلكتروني: برنامج تعليمي في البرمجة اللغوية العصبية
نشرت: 2022-03-11أصبحت تقنيات معالجة اللغة الطبيعية معقدة للغاية خلال السنوات القليلة الماضية. من عمالقة التكنولوجيا إلى الهواة ، يسارع الكثيرون لبناء واجهات ثرية يمكنها تحليل اللغة الطبيعية وفهمها والاستجابة لها. تهدف كل من Amazon's Alexa و Microsoft Cortana و Google Home من Google و Apple's Siri إلى تغيير طريقة تفاعلنا مع أجهزة الكمبيوتر.
يتكون تحليل المشاعر ، وهو حقل فرعي من معالجة اللغة الطبيعية ، من تقنيات تحدد نغمة النص أو الكلام. اليوم ، مع التعلم الآلي والكميات الكبيرة من البيانات التي يتم حصادها من وسائل التواصل الاجتماعي ومواقع المراجعة ، يمكننا تدريب النماذج لتحديد مشاعر ممر اللغة الطبيعية بدقة معقولة.
في هذا البرنامج التعليمي ، ستتعلم كيف يمكنك إنشاء روبوت يمكنه تحليل مشاعر رسائل البريد الإلكتروني التي يتلقاها وإعلامك برسائل البريد الإلكتروني التي قد تتطلب انتباهك على الفور.
تحليل المشاعر في رسائل البريد الإلكتروني
سيتم إنشاء الروبوت باستخدام مزيج من تطوير Java و Python. ستتواصل العمليتان مع بعضهما البعض باستخدام التوفير. إذا لم تكن معتادًا على إحدى هاتين اللغتين أو كلتيهما ، فلا يزال بإمكانك القراءة لأن المفاهيم الأساسية لهذه المقالة تنطبق على اللغات الأخرى أيضًا.
لتحديد ما إذا كانت رسالة بريد إلكتروني تحتاج إلى انتباهك ، سيقوم الروبوت بتحليلها وتحديد ما إذا كانت هناك نغمة سلبية قوية. ثم يرسل تنبيهًا نصيًا إذا لزم الأمر.
سنستخدم Sendgrid للاتصال بصندوق البريد الخاص بنا و Twilio لإرسال تنبيهات نصية.
تحليل المشاعر: مشكلة بسيطة مخادعة
هناك كلمات نربطها بالمشاعر الإيجابية ، مثل الحب والفرح والسرور. وهناك كلمات نربطها بالمشاعر السلبية ، مثل الكراهية والحزن والألم. لماذا لا تدرب النموذج على التعرف على هذه الكلمات وحساب التردد والقوة النسبية لكل كلمة إيجابية وسلبية؟
حسنًا ، هناك مشكلتان في ذلك.
أولاً ، هناك مشكلة النفي. على سبيل المثال ، تشير جملة مثل "الخوخ ليس سيئًا" إلى عاطفة إيجابية باستخدام كلمة نربطها غالبًا بكونها سلبية. لن يتمكن نموذج بسيط من الكلمات من التعرف على النفي في هذه الجملة.
علاوة على ذلك ، أثبتت المشاعر المختلطة أنها مشكلة أخرى في تحليل المشاعر الساذج. على سبيل المثال ، جملة مثل "الخوخ ليس سيئًا ، لكن التفاحة مريعة حقًا" تحتوي على مشاعر مختلطة من الشدة المختلطة التي تتفاعل مع بعضها البعض. لن يكون النهج البسيط قادرًا على حل المشاعر المشتركة أو الحدة المختلفة أو التفاعلات بين المشاعر.
تحليل المشاعر باستخدام شبكة التنسور العصبي التكراري
تحل مكتبة معالجة اللغات الطبيعية في ستانفورد لتحليل المشاعر هذه المشكلات باستخدام شبكة التنسور العصبي العودية (RNTN).
تقوم خوارزمية RNTN أولاً بتقسيم الجملة إلى كلمات فردية. ثم تقوم ببناء شبكة عصبية حيث تكون العقد هي الكلمات الفردية. أخيرًا ، تتم إضافة طبقة موتر بحيث يمكن للنموذج ضبط التفاعلات بين الكلمات والعبارات بشكل صحيح.
يمكنك العثور على عرض مرئي للخوارزمية على موقع الويب الرسمي الخاص بهم.
قامت مجموعة Stanford NLP بتدريب شبكة Recursive Neural Tensor Network باستخدام مراجعات أفلام IMDB الموسومة يدويًا ووجدت أن نموذجهم قادر على التنبؤ بالمشاعر بدقة جيدة جدًا.
الروبوت الذي يتلقى رسائل البريد الإلكتروني
أول شيء تريد القيام به هو إعداد تكامل البريد الإلكتروني بحيث يمكن نقل البيانات إلى برنامج الروبوت الخاص بك.
هناك العديد من الطرق لتحقيق ذلك ، ولكن من أجل البساطة ، دعنا نجهز خادم ويب بسيطًا ونستخدم خطاف التحليل الوارد من Sendgrid لتوجيه رسائل البريد الإلكتروني إلى الخادم. يمكننا إعادة توجيه رسائل البريد الإلكتروني إلى عنوان التحليل الوارد الخاص بـ Sendgrid. سيرسل Sendgrid بعد ذلك طلب POST إلى خادم الويب الخاص بنا ، وسنتمكن بعد ذلك من معالجة البيانات من خلال خادمنا.
لبناء الخادم ، سنستخدم Flask ، وهو إطار عمل ويب بسيط لبايثون.
بالإضافة إلى بناء خادم الويب ، سنريد توصيل خدمة الويب بمجال. للإيجاز ، سنتخطى الكتابة عن هذا في المقالة. ومع ذلك ، يمكنك قراءة المزيد عنها هنا.
يعد إنشاء خادم ويب في Flask أمرًا بسيطًا للغاية.
ما عليك سوى إنشاء app.py
وإضافته إلى الملف:
from flask import Flask, request import datetime app = Flask(__name__) @app.route('/analyze', methods=['POST']) def analyze(): with open('logfile.txt', 'a') as fp_log: fp_log.write('endpoint hit %s \n' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) return "Got it" app.run(host='0.0.0.0')
إذا نشرنا هذا التطبيق خلف اسم المجال وضربنا نقطة النهاية "/ تحليل" ، يجب أن ترى شيئًا مثل هذا:
> >> requests.post('http://sentiments.shanglunwang.com:5000/analyze').text 'Got it'
بعد ذلك ، نريد إرسال رسائل بريد إلكتروني إلى نقطة النهاية هذه.
يمكنك العثور على المزيد من الوثائق هنا ولكنك تريد بشكل أساسي إعداد Sendgrid ليكون معالج البريد الإلكتروني الخاص بك وتطلب من Sendgrid إعادة توجيه رسائل البريد الإلكتروني إلى خادم الويب الخاص بنا.
هنا هو الإعداد الخاص بي على Sendgrid. سيؤدي هذا إلى إعادة توجيه رسائل البريد الإلكتروني إلى @sentibot.shanglunwang.com
POST إلى "http://sentiments.shanglunwang.com/analyze":
يمكنك استخدام أي خدمة أخرى تدعم إرسال رسائل البريد الإلكتروني الواردة عبر خطافات الويب.
بعد إعداد كل شيء ، حاول إرسال بريد إلكتروني إلى عنوان Sendgrid الخاص بك ، يجب أن ترى شيئًا كهذا في السجلات:
endpoint hit 2017-05-25 14:35:46
هذا عظيم! لديك الآن روبوت قادر على استقبال رسائل البريد الإلكتروني. هذا نصف ما نحاول القيام به.
الآن ، تريد أن تمنح هذا الروبوت القدرة على تحليل المشاعر في رسائل البريد الإلكتروني.
تحليل المشاعر بالبريد الإلكتروني مع Stanford NLP
نظرًا لأن مكتبة Stanford NLP مكتوبة بلغة Java ، فسنرغب في إنشاء محرك التحليل في Java.
لنبدأ بتنزيل مكتبة Stanford NLP ونماذجها في Maven. قم بإنشاء مشروع Java جديد ، وأضف ما يلي إلى تبعيات Maven الخاصة بك ، وقم بالاستيراد:
<dependency> <groupId>edu.stanford.nlp</groupId> <artifactId>stanford-corenlp</artifactId> <version>3.6.0</version> </dependency>
يمكن الوصول إلى محرك تحليل المشاعر الخاص بـ Stanford NLP من خلال تحديد المعلق التوضيحي للمشاعر في كود تهيئة خط الأنابيب. يمكن بعد ذلك استرجاع التعليق التوضيحي كبنية على شكل شجرة.
لأغراض هذا البرنامج التعليمي ، نريد فقط معرفة المشاعر العامة للجملة ، لذلك لن نحتاج إلى تحليل الشجرة. نحتاج فقط إلى إلقاء نظرة على العقدة الأساسية.
هذا يجعل الكود الرئيسي بسيطًا نسبيًا:
package seanwang; import edu.stanford.nlp.pipeline.*; import edu.stanford.nlp.util.CoreMap; import edu.stanford.nlp.ling.CoreAnnotations; import edu.stanford.nlp.sentiment.SentimentCoreAnnotations; import java.util.*; public class App { public static void main( String[] args ) { Properties pipelineProps = new Properties(); Properties tokenizerProps = new Properties(); pipelineProps.setProperty("annotators", "parse, sentiment"); pipelineProps.setProperty("parse.binaryTrees", "true"); pipelineProps.setProperty("enforceRequirements", "false"); tokenizerProps.setProperty("annotators", "tokenize ssplit"); StanfordCoreNLP tokenizer = new StanfordCoreNLP(tokenizerProps); StanfordCoreNLP pipeline = new StanfordCoreNLP(pipelineProps); String line = "Amazingly grateful beautiful friends are fulfilling an incredibly joyful accomplishment. What an truly terrible idea."; Annotation annotation = tokenizer.process(line); pipeline.annotate(annotation); // normal output for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { String output = sentence.get(SentimentCoreAnnotations.SentimentClass.class); System.out.println(output); } } }
جرب بعض الجمل وسترى التعليقات التوضيحية المناسبة. تشغيل مخرجات كود المثال:
Very Positive Negative
دمج الروبوت ومحرك التحليل
لذلك لدينا برنامج محلل المشاعر مكتوب بلغة Java وروبوت بريد إلكتروني مكتوب بلغة Python. كيف نجعلهم يتحدثون مع بعضهم البعض؟
هناك العديد من الحلول الممكنة لهذه المشكلة ، ولكن هنا سنستخدم التوفير. سنقوم بتدوير محلل المشاعر كخادم Thrift وروبوت البريد الإلكتروني كعميل Thrift.
Thrift هو منشئ رمز وبروتوكول يستخدم لتمكين تطبيقين ، غالبًا ما يكتبان بلغات مختلفة ، من التواصل مع بعضهما البعض باستخدام بروتوكول محدد. تستخدم فرق Polyglot Thrift لبناء شبكات من الخدمات المصغرة للاستفادة من أفضل ما في كل لغة يستخدمونها.
لاستخدام Thrift ، سنحتاج إلى شيئين: ملف .thrift
لتحديد نقاط نهاية الخدمة ، وكود مُنشأ للاستفادة من البروتوكول المحدد في ملف .proto
. بالنسبة لخدمة المحلل ، يبدو sentiment.thrift
.thrift كما يلي:
namespace java sentiment namespace py sentiment service SentimentAnalysisService { string sentimentAnalyze(1:string sentence), }
يمكننا إنشاء رمز العميل والخادم باستخدام هذا الملف .thrift. يركض:

thrift-0.10.0.exe --gen py sentiment.thrift thrift-0.10.0.exe --gen java sentiment.thrift
ملاحظة: لقد أنشأت الرمز على جهاز يعمل بنظام Windows. سترغب في استخدام المسار المناسب لملف Thrift القابل للتنفيذ في بيئتك.
الآن ، دعنا نجري التغييرات المناسبة على محرك التحليل لإنشاء خادم. يجب أن يبدو برنامج Java الخاص بك كما يلي:
العاطفة Handler.java
package seanwang; public class SentimentHandler implements SentimentAnalysisService.Iface { SentimentAnalyzer analyzer; SentimentHandler() { analyzer = new SentimentAnalyzer(); } public String sentimentAnalyze(String sentence) { System.out.println("got: " + sentence); return analyzer.analyze(sentence); } }
هذا المعالج هو المكان الذي نتلقى فيه طلب التحليل عبر بروتوكول Thrift.
العاطفةAnalyzer.java
package seanwang; // ... public class SentimentAnalyzer { StanfordCoreNLP tokenizer; StanfordCoreNLP pipeline; public SentimentAnalyzer() { Properties pipelineProps = new Properties(); Properties tokenizerProps = new Properties(); pipelineProps.setProperty("annotators", "parse, sentiment"); pipelineProps.setProperty("parse.binaryTrees", "true"); pipelineProps.setProperty("enforceRequirements", "false"); tokenizerProps.setProperty("annotators", "tokenize ssplit"); tokenizer = new StanfordCoreNLP(tokenizerProps); pipeline = new StanfordCoreNLP(pipelineProps); } public String analyze(String line) { Annotation annotation = tokenizer.process(line); pipeline.annotate(annotation); String output = ""; for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { output += sentence.get(SentimentCoreAnnotations.SentimentClass.class); output += "\n"; } return output; } }
يستخدم المحلل مكتبة Stanford NLP لتحديد شعور النص وينتج سلسلة تحتوي على التعليقات التوضيحية للمشاعر لكل جملة في النص.
الشعور بالخادم
package seanwang; // ... public class SentimentServer { public static SentimentHandler handler; public static SentimentAnalysisService.Processor processor; public static void main(String [] args) { try { handler = new SentimentHandler(); processor = new SentimentAnalysisService.Processor(handler); Runnable simple = new Runnable() { public void run() { simple(processor); } }; new Thread(simple).start(); } catch (Exception x) { x.printStackTrace(); } } public static void simple(SentimentAnalysisService.Processor processor) { try { TServerTransport serverTransport = new TServerSocket(9090); TServer server = new TSimpleServer(new Args(serverTransport).processor(processor)); System.out.println("Starting the simple server..."); server.serve(); } catch (Exception e) { e.printStackTrace(); } } }
لاحظ أنني لم أقم بتضمين ملف SentimentAnalysisService.java
هنا لأنه ملف تم إنشاؤه. سترغب في وضع الشفرة التي تم إنشاؤها في مكان يمكن لبقية الكود الخاص بك الوصول إليه.
الآن بعد أن أصبح لدينا الخادم ، فلنكتب عميل Python لاستخدام الخادم.
client.py
from sentiment import SentimentAnalysisService from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol class SentimentClient: def __init__(self, server='localhost', socket=9090): transport = TSocket.TSocket(server, socket) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) self.transport = transport self.client = SentimentAnalysisService.Client(protocol) self.transport.open() def __del__(self): self.transport.close() def analyze(self, sentence): return self.client.sentimentAnalyze(sentence) if __name__ == '__main__': client = SentimentClient() print(client.analyze('An amazingly wonderful sentence'))
قم بتشغيل هذا وسترى:
Very Positive
رائعة! الآن بعد أن أصبح الخادم قيد التشغيل والتحدث إلى العميل ، دعنا ندمجه مع روبوت البريد الإلكتروني عن طريق إنشاء مثيل للعميل ونقل البريد الإلكتروني إليه.
import client # ... @app.route('/analyze', methods=['POST']) def analyze(): sentiment_client = client.SentimentClient() with open('logfile.txt', 'a') as fp_log: fp_log.write(str(request.form.get('text'))) fp_log.write(request.form.get('text')) fp_log.write(sentiment_client.analyze(request.form.get('text'))) return "Got it"
قم الآن بنشر خدمة Java الخاصة بك على نفس الجهاز حيث تقوم بتشغيل خادم الويب ، وابدأ الخدمة ، وأعد تشغيل التطبيق. أرسل بريدًا إلكترونيًا إلى الروبوت مع جملة اختبارية وسترى شيئًا كهذا في ملف السجل:
Amazingly wonderfully positive and beautiful sentence. Very Positive
تحليل البريد الإلكتروني
حسنا! الآن لدينا روبوت بريد إلكتروني قادر على إجراء تحليل للمشاعر! يمكننا إرسال بريد إلكتروني وتلقي علامة عاطفية لكل جملة أرسلناها. الآن ، دعنا نستكشف كيف يمكننا جعل الذكاء قابلاً للتنفيذ.
لتبسيط الأمور ، دعنا نركز على رسائل البريد الإلكتروني حيث يوجد تركيز عالٍ للجمل السلبية والسالبة للغاية. دعنا نستخدم نظام تسجيل بسيط ونقول أنه إذا كان البريد الإلكتروني يحتوي على أكثر من 75٪ من جمل المشاعر السلبية ، فسنضع علامة على ذلك باعتباره بريدًا إلكترونيًا محتملاً للإنذار قد يتطلب استجابة فورية. دعنا ننفذ منطق التسجيل في مسار التحليل:
@app.route('/analyze', methods=['POST']) def analyze(): text = str(request.form.get('text')) sentiment_client = client.SentimentClient() text.replace('\n', '') # remove all new lines sentences = text.rstrip('.').split('.') # remove the last period before splitting negative_sentences = [ sentence for sentence in sentences if sentiment_client.analyze(sentence).rstrip() in ['Negative', 'Very negative'] # remove newline char ] urgent = len(negative_sentences) / len(sentences) > 0.75 with open('logfile.txt', 'a') as fp_log: fp_log.write("Received: %s" % (request.form.get('text'))) fp_log.write("urgent = %s" % (str(urgent))) return "Got it"
يقدم الكود أعلاه بعض الافتراضات ولكنه سيعمل لأغراض العرض التوضيحي. أرسل رسالتي بريد إلكتروني إلى الروبوت الخاص بك وسترى تحليل البريد الإلكتروني في السجلات:
Received: Here is a test for the system. This is supposed to be a non-urgent request. It's very good! For the most part this is positive or neutral. Great things are happening! urgent = False Received: This is an urgent request. Everything is truly awful. This is a disaster. People hate this tasteless mail. urgent = True
إرسال تنبيه
نحن على وشك الانتهاء!
لقد أنشأنا روبوتًا للبريد الإلكتروني قادرًا على تلقي رسائل البريد الإلكتروني وإجراء تحليل للمشاعر وتحديد ما إذا كان البريد الإلكتروني يتطلب اهتمامًا فوريًا. الآن ، علينا فقط إرسال تنبيه نصي عندما يكون البريد الإلكتروني سلبيًا بشكل خاص.
سنستخدم Twilio لإرسال تنبيه نصي. واجهة برمجة تطبيقات Python الخاصة بهم ، والتي تم توثيقها هنا ، واضحة جدًا. دعنا نعدل مسار التحليل لإرسال طلب عندما يتلقى طلبًا عاجلاً.
def send_message(body): twilio_client.messages.create( to=on_call, from_=os.getenv('TWILIO_PHONE_NUMBER'), body=body ) app = Flask(__name__) @app.route('/analyze', methods=['POST']) def analyze(): text = str(request.form.get('text')) sentiment_client = client.SentimentClient() text.replace('\n', '') # remove all new lines sentences = text.rstrip('.').split('.') # remove the last period before splitting negative_sentences = [ sentence for sentence in sentences if sentiment_client.analyze(sentence).rstrip() in ['Negative', 'Very negative'] # remove newline char ] urgent = len(negative_sentences) / len(sentences) > 0.75 if urgent: send_message('Highly negative email received. Please take action') with open('logfile.txt', 'a') as fp_log: fp_log.write("Received: " % request.form.get('text')) fp_log.write("urgent = %s" % (str(urgent))) fp_log.write("\n") return "Got it"
ستحتاج إلى ضبط متغيرات البيئة الخاصة بك على بيانات اعتماد حساب Twilio الخاص بك وتعيين رقم الاتصال على هاتف يمكنك التحقق منه. بمجرد القيام بذلك ، أرسل بريدًا إلكترونيًا إلى نقطة نهاية التحليل وسترى نصًا يتم إرساله إلى رقم الهاتف المعني.
وانتهينا!
أصبحت معالجة اللغات الطبيعية سهلة مع Stanford NLP
في هذه المقالة ، تعلمت كيفية إنشاء روبوت لتحليل المشاعر عبر البريد الإلكتروني باستخدام مكتبة Stanford NLP. تساعد المكتبة في تجريد جميع التفاصيل الدقيقة لمعالجة اللغة الطبيعية وتسمح لك باستخدامها كحجر بناء لتطبيقات البرمجة اللغوية العصبية الخاصة بك.
آمل أن يكون هذا المنشور قد أظهر واحدًا من العديد من التطبيقات المحتملة المذهلة لتحليل المشاعر ، وأن يلهمك هذا لبناء تطبيق خاص بك في البرمجة اللغوية العصبية.
يمكنك العثور على الكود الخاص ببوت تحليل آراء البريد الإلكتروني من هذا البرنامج التعليمي للغة البرمجة اللغوية العصبية على GitHub.