معالجة اللغة العربية Arabic Natural Language Processing – تطبيق عملى بلغة البرمجه Python (الجزء الثاني)

1٬220

بعد ما شرحنا في المقال السابق خطوات الـ NLP سنستعرض كيف نستخدم هذه الخطوات بلغة Python.

ملحوظة: هناك مكتبة في Python أحدثت تطورا كبيرا في تسهيل استخدام ال NLP واستخراج معلومات مفيدة بخطوات بسيطة، هذه المكتبة هي spaCy. تدعم كل ما شرحناه وتطبقه بأسلوب سهل متناسق، بل وتستخدم deep learning models في بعض المهام مثل الـ NER لتحصل على أفضل النتائج.
لكن حاليا أكثر الدعم لـ
spaCy هو للغة الانجليزية، ولإضافة اللغة العربية نحتاج labeled data للعربية وهذا يتطلب وقت وجهد.
في هذا المقال سنستخدم مكتبات أقدم من
spaCy وبطرق أبسط. هي تؤدي الوظائف مع المزيد من الخطوات وقد لا تكون بنفس كفاءة الطرق الأحدث.

المكتبات المطلوبة

سوف نستخدم مكتبات NLP من جامعة ستانفورد، وهي مبنية بلغة الـ Java ولكن يمكننا استخدامها مع Python عن طريق مكتبة nltk

نحتاج الـ Java Development Kit (JDK) حتى نستطيع تشغيل مكتبات الـ Java

https://www.oracle.com/technetwork/java/javase/downloads/index.html

ونحتاج إلى الـ Stanford Parser والـ Stanford Tagger والـ Stanford Segmenter

https://nlp.stanford.edu/software/stanford-parser-full-2018-10-17.zip

https://nlp.stanford.edu/software/stanford-postagger-full-2018-10-16.zip

https://nlp.stanford.edu/software/stanford-segmenter-2018-10-16.zip

نتأكد من فك ضغط هذه الملفات ومعرفة مسارها، في هذا المثال ستكون في نفس الـ directory التي بها الكود.

وفي الـ Python سنحتاج مكتبة nltk ومكتبة polyglot ومكتبة rake-nltk

أنصح باستخدام Anaconda Python لسهولة التعامل معها وإضافة المكتبات

نستخدم pip لإضافة هذه المكتبات

pip install nltk
pip install rake-nltk
pip install polyglot
المكتبات المطلوبة

ملحوظة: قد يتعثر تنزيل مكتبة polyglot على Windows ولحل المشكلة نقوم بتحميل وإضافة هاتين المكتبتين أولا PyICU و pycld

https://www.lfd.uci.edu/~gohlke/pythonlibs/

حسب نسخة الـ Python، مثلا على المواصفات التالية:

Windows 64-bit, Python 3.6
pip install PyICU‑2.2‑cp36‑cp36m‑win_amd64.whl
pip install pycld2‑0.31‑cp36‑cp36m‑win_amd64.whl
لتشغيل polyglot على windows

ثم نحمل مكتبة polyglot من هنا

https://github.com/aboSamoor/polyglot/archive/master.zip

ونفك الضغط ونشغل هذا الأمر داخل الـ directory

cd polyglot-master
python setup.py install
لتثبيت polyglot

نحتاج إلى ملفين يحتويان على النصوص التي سنعالجها

ملف sample.txt يحتوي على الثلاث جمل من المقال السابق:

لندن هي عاصمة المملكة المتحدة وأكبر مدنها. تقع على نهر التيمز في جنوب بريطانيا وتعد من أهم المدن لأكثر من ألفي سنة. أسسها الرومان وسموها لندنيام.

وملف ar_london.txt وهو مستخرج النص من مقال ويكيبيديا عن لندن باللغة العربية.

sample.txt

ar_london.txt

تجهيز الكود

import os
from nltk.parse import stanford as SParse
from nltk.tag import stanford as STag
from nltk.tokenize import StanfordSegmenter

from polyglot.text import Text
from rake_nltk import Rake

import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords

os.environ['STANFORD_MODELS'] = 'stanford-segmenter-2018-10-16/data/;stanford-postagger-full-2018-10-16/models/'
os.environ['STANFORD_PARSER'] = 'stanford-parser-full-2018-10-17'
os.environ['CLASSPATH'] = 'stanford-parser-full-2018-10-17'
os.environ['JAVAHOME'] = 'C:/Program Files/Java/jdk-11.0.1'
ادراج المكتبات

نقوم بادراج المكتبات التي ذكرناها

نحتاج إلى الكلمات العربية الشائعة stopwords فنتاكد من تنزيلها بواسطة nltk

نضيف أماكن المكتبات المستخدمة Java وكذلك مكان الـ JDK نفسه

تقسيم الكلام Segmentation

segmenter = StanfordSegmenter('stanford-segmenter-2018-10-16/stanford-segmenter-3.9.2.jar')
segmenter.default_config('ar')
text = segmenter.segment_file('sample.txt')
print(text)
segmentation

لندن هي عاصمة المملكة المتحدة و اكبر مدن ها . تقع على نهر التيمز في جنوب بريطانيا و تعد من اهم المدن ل اكثر من الفي سنة . اسس ها الرومان و سمو ها ل ندنيام .

 

نلاحظ أن الـ Segmentation قام بفصل الضمائر والحروف مثل “و اكبر”، “مدنـ ها” وقام بفصل علامات الترقيم بمسافات ” . “

وأيضا قام بنوع من الـ normalization وهو يوحّد شكل الكلمات ليسهل التعامل معها فقام بإزالة جميعة الهمزات واستبدالها بألف الوصل: “أكبر” -> “اكبر”

لكن نلاحظ قصور في تقسيم كلمة “لنديام” لأنه لم يتعرف عليها وحسب أن اللام هي حرف متصل بكلمة “نديام”

تصنيف أقسام الكلام  Part-of-Speech (POS) tagging

tagger = STag.StanfordPOSTagger('arabic.tagger', 'stanford-postagger-full-2018-10-16/stanford-postagger.jar')
for tag in tagger.tag(text.split()):
	print(tag[1])

لندن/NNP
هي/PRP
عاصمة/NN
المملكة/DTNN
المتحدة/DTJJ
و/CC
...
Part of speech (POS) tagging

لتعرف على معاني الـ tags هنا:

https://www.ling.upenn.edu/courses/Fall_2003/ling001/penn_treebank_pos.html

الإعراب Parsing

parser = SParse.StanfordParser(model_path='edu/stanford/nlp/models/lexparser/arabicFactored.ser.gz')
sentences = parser.raw_parse_sents(text.split('.'))
for line in sentences:
	for sentence in line:
		print(sentence)
sentence.draw()
Parsing
(ROOT
  (FRAG
    (NP (NNP لندن))
    (NP (PRP هي))
    (NP
      (NN عاصمة)
      (NP
        (NP (DTNN المملكة) (DTJJ المتحدة))
        (CC و)
        (NP (ADJP (JJR اكبر) (NP (NN مدن) (NP (PRP$ ها)))))))))

يمكننا رسم الشجرة الغوية للجملة بواسطة sentence.draw

 

تحديد الأعلام Named Entity Recognition (NER)

هنا نستخدم مكتبة polyglot

from polyglot.text import Text
text = Text(text)
for sent in text.sentences:
    print(sent, "\n")
    for entity in sent.entities:
        print(entity.tag, entity)
Named Entity Recognition (NER)

لندن هي عاصمة المملكة المتحدة و اكبر مدن ها .
I-LOC ['لندن']
I-LOC ['المملكة', 'المتحدة']

تقع على نهر التيمز في جنوب بريطانيا و تعد من اهم المدن ل اكثر من الفي سنة .
I-LOC ['بريطانيا']

اسس ها الرومان و سمو ها ل ندنيام .
I-LOC ['الرومان']

نلاحظ أنه تعرف على “الرومان” ولكن كمكان بدلا من جنسية وهذا من حدود كفاءة بعض المكتبات المتوفرة، لكن يمكننا بناء models أفضل منها إذا حصلنا على labelled data وأحسنا تصميم الـ model

استخراج الحقائق  Fact Extraction

نراعي أن الـ POS والـ Parsing يستخدمان مكتبات Stanford فمن الأفضل استخدام الـ Stanford Segmenter قبلها

كذلك في حالة الـ NER فإن الـ Segmentation يساعد في التعرف على الأعلام

لكن في استخراج الحقائق فهالك عدة خورزميات والتي سنستخدمها RAKE تتعامل مع الجمل ككل بغض النظر عن محتواها لغويا، فهي تعد طريقة Unsupervised وبالتالي فاستخدام الـ Segmentation قد يغير من النتائج للأسوأ أو الأحسن فلنراعي ذلك.

بعض الخورزميات الأخرى تعتمد على الـ POS أو الـ NER أو الـ Parse وقد تجمع بينهم، ولكن هذه خارج إطار مقالنا هذا.

هنا نستخدم مقال ويكيبيديا عن لندن، نقوم بفتح الملف، بدون Segmentation، ونستعرض أوله

with open('ar_london.txt', encoding='utf-8') as f:
    london = f.read()
print(london[:100])
قراءة الملف
لندن
من ويكيبيديا، الموسوعة الحرة
اذهب إلى التنقل اذهب إلى البحث
   هذه المقالة عن لندن عاصمة الممل

نستخرج العبارات المهمة وبحد أقصى 15 كلمة، ونستعرض أهم 5 حقائق من نظر RAKE

rake = Rake(stopwords=stopwords.words('arabic'), punctuations=',./:،؛":.,’\''.split(), language='arabic', max_length=15)
rake.extract_keywords_from_text(london)
for phrase in rake.get_ranked_phrases()[:5]:
print(phrase)
استخراج الحقائق

سنة 1097 أمر وليام الثاني ملك إنجلترا ببناء قاعة ويستمنستر المتاخمة للدير والتي أصبحت جزء
أعاد تأسيس دير وستمنستر westminster abbey المتاخمة لقصر ويستمنستر westminster palce وقد أصبحت مدينة لندن
دير ويستمنستر وقد أعطى مواطني لندن امتيازات خاصة وأمر ببناء مايعرف الآن باسم برج لندن
2012 ، لتكون بذلك أكبر مدن أوروبا ، وأحد أهم مراكزها السياسية والاقتصادية والثقافية .
تقام مباريات الكريكت خلال فصلي الربيع والصيف ، وتعتبر ملاعب لورد للكريكيت ، الموجودة

قد تبدو هذه الحقائق مقصوصة لأننا حددنا 15 كلمة كحد أقصى، إلا أننا لو غيرنا هذا الحد سنحصل على حقائق مختلفة

يمكننا البحث عن العبارات وجلب الكلام المجاور لمعرفة أكثر ما تذكره

يمكنك تحميل ملف الكود كاملاً من ملف الكود كاملا

تعليقات