معالجة الكلمات لمعالجة اللغة الطبيعية في جوليا!

عقدة المصدر: 1172051

تم نشر هذه المقالة كجزء من مدونة علوم البيانات

نبذة

Julia هي لغة برمجة مشهورة ليس فقط بسبب بيئتها الودية ولكن أيضًا بسبب الحزم المدمجة ، والتي تجعل البرمجة اللغوية العصبية أمرًا سهلاً للغاية. قد تتذكرون جميعًا رموز Python الطويلة التي نستخدمها لتنظيف البيانات ، ومقارنات السلسلة ، واستخراج البيانات ، وحفلات الزفاف ، وما إلى ذلك. توفر لك هذه اللغة حزمًا مضمنة تستخدمها في ثوانٍ لهذه الأغراض. هل تريد أن ترى كيف؟ لنندفع!

جدول المحتويات

  1. المُقدّمة

  2. حزمة رموز الكلمات

  3. حزمة String Distance

  4. باقة الزفاف

  5. حزمة المحولات

  6. وفي الختام

المُقدّمة

في معالجة اللغة الطبيعية (NLP) ، نتعامل بشكل عام مع معالجة النصوص / الكلمات. يتضمن كل شيء مثل الترميز ، والتجزئة ، والتصنيف ، والتحليل ، ووضع العلامات ، وكذلك التفكير الدلالي. النص هو العنصر الأكثر أهمية في البرمجة اللغوية العصبية ، ويستغرق معظم الوقت لأن شفرة معالجة النص كبيرة جدًا. لأداء جميع عمليات معالجة الكلمات ، نحتاج إلى الكثير من الوقت والمساحة والوعي. توفر جوليا الحل لتلك الأكواد الطويلة المكونة من 2-3 صفحات والتي تستغرق ساعات في كتابتها باستخدام حزمها المضمنة. هنا ، سوف نتعرف على هذه الحزم المضمنة بمساعدة أكوادها القابلة للتنفيذ.

NLP

حزمة رموز الكلمات في جوليا

إحدى حزم معالجة النصوص الأساسية هي حزمة WordTokenizers.jl. تؤدي هذه الحزمة مهامًا مختلفة مثل استخراج الرموز المميزة من الجمل واستخراج الجمل من الفقرات واستخراج الجمل والرموز في وقت واحد من الفقرات. هنا نرى الاختلافات الثلاثة واحدة تلو الأخرى بمساعدة الأمثلة.

رابط الحزمة الرسمي: https://github.com/JuliaText/WordTokenizers.jl

أ). تثبيت

لتثبيت هذه الحزمة في Julia ، قم بتشغيل الأمر

pkg> إضافة WordTokenizers

ب). تقسيم الجملة إلى رموز

تحتوي حزمة WordTokenizers.jl على طريقة تسمى tokenize (نص)

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

جوليا> استخدام WordTokenizers julia> text = "أحلم أيضًا بإنشاء أدواتي الخاصة مثل أدوات الآخرين."؛ julia> tokenize (text) |> print # Default tokenizer SubString {String} ["I"، "also"، "have"، "dream"، "of"، "create"، "my"، "own"، " أدوات "،" مثل "،" الآخرين "،" لديك "،" ""]

ج). تقسيم الفقرة إلى جمل

تحتوي حزمة WordTokenizer.jl على طريقة تسمى split_sentences (النص). تبحث هذه الطريقة عن النقطة في الفقرة وتفصل الجمل بناءً على ذلك.

julia> text = "لدي حلم أيضًا في إنشاء أدواتي الخاصة مثل الآخرين. ولكن الشيء الذي وجدته مختلفًا في نفسي هو جنوني. كان لدي تلك السخرية التي جعلتني أفعل ذلك."؛ julia> split_sentences (text) 3-element Array {SubString {String}، 1}: "لدي حلم أيضًا في إنشاء أدواتي الخاصة مثل الأدوات الأخرى." ، "ولكن الشيء الذي وجدته مختلفًا في نفسي هو جنوني." ، "كان لدي تلك السخرية التي جعلتني أفعل ذلك."

د). تقسيم الفقرة إلى جملة + رموز

تُستخدم طريقة split_sentences (النص) أيضًا لتقسيم الفقرة إلى جمل بالإضافة إلى الرموز المميزة.

julia> tokenize. (split_sentences (text)) 3-element Array {Array {SubString {String}، 1}، 1}: SubString {String} [“I”، “also”، “have”، “dream”، “ من "،" إنشاء "،" خاصتي "،" خاص "،" أدوات "،" مثل "،" الآخرين "،" لديك "،". "] SubString {String} [" لكن "،" the "،" شيء "،" التي "،" أنا "،" وجدت "،" مختلفة "،" في "،" أنا "،" هو "،" بلدي "،" جنون "،" الأرض "،". "] سلسلة فرعية {سلسلة} ["أنا" ، "كان" ، "ذلك" ، "السخرية" ، "التي" ، "صنعت" ، "أنا" ، "إلى" ، "تفعل" ، "هكذا" ، "."]

ه). توافر العديد من الخوارزميات المختلفة للتحليل:

  • الرمز المميز القابل للانعكاس هو رمز مميز يمكن عكس نتيجته لاستعادة النص الأصلي. يخصص في رموز منفصلة

  • TokTok Tokenizer هو رمز مميز قائم على التعبير العادي.

  • Tweet Tokenizer هو رمز مميز يركز على تقسيم التغريدات ، بما في ذلك الرموز التعبيرية وإدخالات HTML والمزيد.

  • NLTK Word tokenizer عبارة عن خوارزمية نموذجية تستخدمها مكتبة NLTK ، والتي تعتبر الأفضل مقارنة بالمكتبة السابقة من حيث التعامل مع أحرف UNICODE ، إلخ.

  • رمز بورمان المميز - أزل جميع علامات الترقيم وافصل بينها بمسافات. في بعض الأحيان يمكن أن يعمل بشكل أسوأ من مجرد الانقسام.

  • رموز مساحة علامات الترقيم - تحسين الخوارزمية السابقة عن طريق تتبع حدود الكلمات. على سبيل المثال ، يمنع الواصلة في الكلمات.

  • Penn Tokenizer هو تطبيق الرمز المميز المستخدم في مجموعة Penn Treebank.

  • يعد Penn Tokenizer المحسن تعديلًا يتم تنفيذه وفقًا لخوارزمية من مكتبة NLTK.

يتم تنفيذ الطريقة المستخدمة لاختيار خوارزمية الترميز عن طريق استدعاء set_tokenizer (nltk_word_tokenize)

حزمة سلسلة المسافة

توفر لك حزمة StringDistance.jl من Julia سهولة إجراء مقارنات بين السلاسل. ليس من الضروري دائمًا إجراء تحليل كامل للوثائق. في بعض الأحيان يكون من الضروري حل المشكلات المطبقة تمامًا لتحديد تشابه السلاسل ، على سبيل المثال ، تحديد الأخطاء المطبعية أو العناوين غير المكتملة. من المريح جدًا استخدام حزمة StringDistances.jl عندما تريد مقارنة السلاسل.

استخدام StringDistances Compar ("shikha"، "shikha"، Hamming ()) #> 1.0 قارن ("shikha"، "shihka"، Jaro ()) #> 0.9444444444444445 قارن ("shikha" ، "shihka" ، Winkler (Jaro () )) #> 0.9611111111111111 قارن ("شيخة" ، "شيخة" ، QGram (2)) #> 0.9230769230769231 قارن ("شيخة" ، "شيخة" ، وينكلر (QGram (2))) #> 0.9538461538461539

القيمة التي ترجعها طريقة المقارنة هي قرب السلاسل. عادة ، نعتبر أن الرقم 1 هو تطابق كامل والصفر غير مطابق.

غالبًا ما يتم استخدام Jaro-Winkler كمقاييس شائعة حاليًا. السبب هو سرعته العالية جدًا ، لكن دقة هذا المقياس ليست كبيرة بالمعايير الحديثة. يوفر مقياس RatcliffObershelp ، على سبيل المثال ، مزيدًا من الدقة في تحديد تشابه السلاسل الطويلة مع كلمات متعددة. بالإضافة إلى ذلك ، يمكن استخدامه مع المعالجة المسبقة. لنفترض أن لديك سلسلتين بنفس الكلمات ولكن ترتيب الكلمات مختلف ، فيمكنك استخدام رموز الفرز المميزة.

قارن ("shikha and shia" ، "shia and shikha" ، RatcliffObershelp ()) #> 0.44444 قارن ("shikha and shia" ، "shia and shikha" ، TokenSort (RatcliffObershelp ()) #> 1.0 قارن ("الشيخة والشيعة" "،" الشيخة تقاتل بجنون مع الشيعة "، TokenSet (Jaro ())) #> 0.944444 قارن (" الشيخة والشيعة "،" الشيخة تقاتل بجنون مع الشيعة "، TokenMax (RatcliffObershelp ())) #> 0.855

يجب حفظ نتيجة المعالجة المسبقة أولاً حيث يكون من الضروري مقارنة عدد كبير من السلاسل. على سبيل المثال ، بدلاً من استدعاء TokenSort في كل مرة ، قم بذلك مرة واحدة وقم بتخزين النتائج الوسيطة المرتبة. تتمثل إحدى مزايا Julia ، في هذه الحالة ، في أن المكتبة تم تنفيذها بالكامل في Julia ، وبالتالي يمكن استخدام الكود بسهولة لتحسين أو استخدام أجزاء منه في التنفيذ.

باقة الزفاف في جوليا

عندما نريد تنفيذ خوارزميات لتحويل النصوص إلى بعض المساحات المتجهة ، فإننا نستخدم حزمة Embeddings.jl الخاصة بـ Julia. الميزة الرئيسية لهذه المساحات متعددة الأبعاد هي أن عمليات الجمع أو الطرح للمتجهات التي تمثل كلمات معينة تؤدي إلى حقيقة أن النتيجة تصبح قريبة من الكلمات الأخرى القريبة في السياق في مجموعة النص التي تم توفير البرنامج عليها. واحدة من أولى الخوارزميات المعروفة لمثل هذا الاتجاه كانت Word2Vec. مثال نموذجي للعمليات على المتجهات المرتبطة بالكلمات: ملك - رجل + امرأة = ملكة ... يمكن تعديل الأبعاد المختلفة لهذه المساحات اعتمادًا على مجموعة البيانات المستخدمة. على سبيل المثال ، هناك مجموعات بيانات مدربة على الأخبار ، أو مقالات ويكيبيديا ، بلغة واحدة فقط ، أو بعدة لغات في وقت واحد. نتيجة لذلك ، يمكن أن تختلف أبعاد الفضاء على مدى واسع من مئات إلى آلاف الأبعاد. بشكل عام ، تسمى هذه المسافات "الفضاء الدلالي" ، وغالبًا ما تسمى المسافة بين المتجهات "المسافة الدلالية".

رابط الحزمة الرسمي: - https://github.com/JuliaText/Embeddings.jl

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

تتضمن طرق التوجيه التي توفرها حزمة Embeddings.jl المفضلة لدينا Word2Vec و GloVe و FastText. تم تدريب الخيار الأخير مسبقًا لعدد كبير من المستندات. في الواقع ، لأي طريقة توجيهية ، يمكنك إعادة تدريب النموذج على مجموعة البيانات الخاصة بك ، ولكن يمكن أن يكون وقت إعادة التدريب طويلًا جدًا. أحد عيوب معظم طرق التحويل هذه هو وجود كمية كبيرة من البيانات ، بما في ذلك قاموس المصطلحات وتمثيل المتجهات لكل منها. لاستخدام ، على سبيل المثال ، word2vec ، تحتاج فقط إلى 8-16 جيجابايت من ذاكرة الوصول العشوائي. خلاف ذلك ، قد لا تناسب المصفوفة مع المتجهات ببساطة.

هناك حزمة أخرى تسمى حزمة DataDeps.jl ، والتي تُستخدم لأتمتة تحميل مجموعات البيانات الكبيرة في الوقت الذي تكون فيه هناك حاجة إليها ("التحميل البطيء"). إذا قمت بتشغيل برنامج باستخدام Embedding.jl لأول مرة ، فستطلب منك وحدة التحكم النصية ما إذا كنت تريد التحميل أم لا. نظرًا لأن هذا يمكن أن يحدث أيضًا على الخادم في عملية الخلفية ، فمن الممكن تحميل التبعيات تلقائيًا عن طريق تعيين متغير البيئة.

ENV ["DATADEPS_ALWAYS_ACCEPT"] = صحيح

الشرط الوحيد هو وجود مساحة قرص كافية لتخزين الملفات التي تم تنزيلها. يتم وضع التبعيات التي تم تنزيلها في دليل ~ / .julia / datadeps حسب أسماء مجموعة البيانات.

المرحلة الأولى هي تحميل البيانات لطريقة التوجيه المطلوبة:

استخدام التضمينات
وظيفة get_embedding (word) ind = get_word_index [word] emb = embtable.embeddings [:، ind]
عائد أعلى الإدارة الانتخابية
النهاية

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

julia> get_embedding ("blue") 300-element Array {Float32,1،0.01540828}: 0.03409082 0.0882124 0.04680265 0.03409082 -XNUMX ...

يمكن استرجاع الكلمات بواسطة WordTokenizers أو عن طريق TextAnalysis. يمكنك إضافة متجهات باستخدام العمليات القياسية المضمنة بالفعل في Julia:

julia> a = rand (5) 5-element Array {Float64,1،0.012300397820243392}: 0.13543646950484067 0.9780602985106086 0.24647179461578816 0.18672770774122105 5 جوليا> b = واحد (5) مصفوفة 64,1 عناصر {Float1.0 1.0،1.0}: b 1.0-element Array {Float1.0،5}: 64,1 1.0123003978202434 1.1354364695048407 1.9780602985106086 1.2464717946157882

يتم توفير خوارزميات التجميع بواسطة حزمة Clustering.jl. طرق التعلم الآلي بما في ذلك طرق التصنيف - راجع حزمة MLJ.jl. إذا كنت ترغب في تنفيذ خوارزميات التجميع بشكل مستقل ، فإنني أوصيك بالاهتمام بالحزمة https://github.com/JuliaStats/Distances.jl، والذي يوفر مجموعة ضخمة من الخوارزميات لحساب مسافة المتجه:

  • يعني الانحراف التربيعي

  • الجذر يعني الانحراف التربيعي

  • يعني الجذر الطبيعي الانحراف التربيعي

  • المسافة الإقليدية المربعة

  • المسافة الإقليدية الدورية

  • مسافة التباين الإجمالية

  • المسافة الإقليدية

  • مسافة الجاكارد

  • مسافة هامينج

  • مسافة جيب التمام

  • مسافة الارتباط

  • المسافة Bhattacharyya

  • يعني الانحراف المطلق

يمكن استخدام مقاييس المسافة هذه عند إجراء التجميع أو التصنيف.

حزمة المحولات في جوليا

Transformers.jl هو تطبيق جوليا الخالص لبنية Transformers التي تعتمد عليها شبكة BERT العصبية من Google. تجدر الإشارة إلى أن هذه الشبكة العصبية وتعديلاتها هي التي أصبحت الآن شائعة جدًا لحل مشكلة NER - ترميز الكيانات المسماة ، وكذلك لتوجيه الكلمات.

يستخدم Transformers.jl الامتداد الجريان.jl الحزمة ، والتي بدورها ليست فقط مكتبة جوليا الخالصة لتنفيذ الشبكات العصبية ولكنها أيضًا واحدة من أسرع التطبيقات لتنفيذ مثل هذه العمليات. يتحول Flux.jl بسهولة من وحدة المعالجة المركزية إلى وحدة معالجة الرسومات ، ولكن هذا مطلب عام للمكتبات التي تنفذ وظائف الشبكة العصبية.

في هذه المقالة ، لن ندخل في تفاصيل BERT أو الشبكات العصبية على هذا النحو. دعنا نلتزم بمثال من التعليمات البرمجية لتوجيه النصوص:

استخدام ترانسفورمرس
استخدام المحولات
استخدام المحولات
استخدام المحولات
استخدام محولات
استخدام تدفق
استخدام الجريان: onehotbatch ، الانحدار
استيراد الجريان. الأمثل: التحديث!
استخدام WordTokenizers ENV ["DATADEPS_ALWAYS_ACCEPT"] = صحيح
CONST FromScratch = false #use wordpiece و tokenizer من الاختبار المسبق
CONST قطعة الكلمات = التحضير المسبق "bert-uncased_L-12_H-768_A-12: wordpiece"
CONST tokenizer = prerain "bert-uncased_L-12_H-768_A-12: tokenizer"
CONST المفردات = المفردات (قطعة الكلمات)
CONST bert_model = gpu (FromScratch؟ create_bert (): اختبار مسبق "bert-uncased_L-12_H-768_A-12: bert_model") Flux.testmode! (bert_model) وظيفة vectorize (str :: String) tokens = str |> tokenizer |> wordpiece text = ["[CLS]"؛ الرموز. "[SEP]"] t_indices = vocab (نص) seg_indices = [fill (1، length (tokens) + 2)؛] sample = (tok = t_indices، seg = seg_indices) bert_embedding = sample |> bert_model.embed collection (مجموع (bert_embedding ، يعتم = 2) [:])
النهاية

الطريقة المحددة هنا vectorize ستستخدم لتوجيه النصوص. حسنًا ، يتم استخدامه على النحو التالي:

استخدام المسافات x1 = vectorize ("البعض يستحق الحب") x2 = vectorize ("البعض يستحق الكراهية") cosine_dist (x1، x2)

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

وفي الختام

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

الوسائط الموضحة في هذه المقالة ليست مملوكة لشركة Analytics Vidhya ويتم استخدامها وفقًا لتقدير المؤلف.

المصدر: https://www.analyticsvidhya.com/blog/2021/10/word-processing-for-natural-language-processing-in-julia/

الطابع الزمني:

اكثر من تحليلات Vidhya