كيفية إنشاء منظمة العفو الدولية العنصرية دون الكثير من الجهد

درس تحذيري.

دعونا نجعل مصنف الدرجة اللونية!

يعد تحليل الشعور (تحليل الشعور) مهمة شائعة جدًا في معالجة اللغة الطبيعية (NLP) ، وهذا ليس مفاجئًا. من المهم لرجال الأعمال أن يفهموا ما يقوله الناس: إيجابي أو سلبي. يتم استخدام هذا التحليل لمراقبة الشبكات الاجتماعية ، وتعليقات العملاء ، وحتى في تداول الأسهم الخوارزمية (نتيجة لذلك ، تقوم برامج الروبوت بشراء أسهم Berkshire Hathaway بعد نشر مراجعات إيجابية حول دور آن هاثاواي في الفيلم الأخير ).

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

هذا هو ما سنفعله. سوف نتبع المسار الأقل مقاومة ونبسط المصنف ، والذي ربما يبدو مألوفًا للغاية لكل من يشارك في التطورات ذات الصلة في مجال البرمجة اللغوية العصبية. على سبيل المثال ، يمكن العثور على مثل هذا النموذج في مقالة Deep Averaging Networks (Iyyer et al.، 2015). نحن لا نحاول على الإطلاق تحدي نتائجهم أو نقد النموذج ؛ نحن ببساطة نعطي طريقة معروفة لتمثيل ناقلات الكلمات.

خطة العمل:

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

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

  • لتقييم المشكلة إحصائيا ، بحيث يصبح من الممكن قياس التقدم كما تم حلها.
  • قم بتحسين البيانات للحصول على نموذج دلالي أكثر دقة وأقل عنصرية.

تبعيات البرمجيات


تمت كتابة هذا البرنامج التعليمي في Python ويعتمد على حزمة نموذجية لتعلم آلة Python: numpy و scipy للحوسبة العددية ، و scikit-learn لإدارة البيانات ، و scikit-learn الآلي. في النهاية ، seaborn أيضًا matplotlib و seaborn لإنشاء المخططات.

من حيث المبدأ ، يمكن استبدال scikit-Learn بـ TensorFlow أو Keras ، أو شيء من هذا القبيل: يمكنهم أيضًا تدريب المصنف على النسب التدرجية. لكننا لسنا بحاجة إلى تجريداتهم ، لأنه هنا يتم التدريب في مرحلة واحدة.

 import numpy as np import pandas as pd import matplotlib import seaborn import re import statsmodels.formula.api from sklearn.linear_model import SGDClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score #     %matplotlib inline seaborn.set_context('notebook', rc={'figure.figsize': (10, 6)}, font_scale=1.5) 

الخطوة 1. ناقلات تمثيل الكلمات


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

يتطلب التعلم الناجح مئات غيغابايت من النص. لحسن الحظ ، قامت فرق البحث المختلفة بالفعل بهذا العمل وقدمت نماذج تم تدريبها مسبقًا لتمثيل المتجهات المتاحة للتنزيل.

أكثر مجموعتي البيانات شهرة للغة الإنجليزية هما word2vec (المدربين على نصوص أخبار Google) و GloVe (على صفحات الزحف الشائعة على الويب). سيعطي أي منهم نتيجة مماثلة ، لكننا سنأخذ نموذج GloVe لأنه يحتوي على مصدر بيانات أكثر شفافية.

يأتي GloVe بثلاثة أحجام: 6 مليارات و 42 مليار و 840 مليار ، أحدث طراز هو الأقوى ، لكنه يتطلب موارد معالجة كبيرة. الإصدار 42 مليار جيد جدًا ، ويتم قطع القاموس بدقة إلى مليون كلمة. نحن على طريق المقاومة الأقل ، لذلك خذ الإصدار 42 مليار.

- لماذا من المهم للغاية استخدام نموذج "معروف"؟

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

قم بتنزيل glove.42B.300d.zip من موقع GloVe واستخلص data/glove.42B.300d.txt . بعد ذلك ، نحدد وظيفة لقراءة المتجهات بتنسيق بسيط.

 def load_embeddings(filename): """  DataFrame      ,   word2vec, GloVe, fastText  ConceptNet Numberbatch.            . """ labels = [] rows = [] with open(filename, encoding='utf-8') as infile: for i, line in enumerate(infile): items = line.rstrip().split(' ') if len(items) == 2: # This is a header row giving the shape of the matrix continue labels.append(items[0]) values = np.array([float(x) for x in items[1:]], 'f') rows.append(values) arr = np.vstack(rows) return pd.DataFrame(arr, index=labels, dtype='f') embeddings = load_embeddings('data/glove.42B.300d.txt') embeddings.shape 

(1917494, 300)

الخطوة 2. قاموس نغمة الذهب القياسية


الآن نحن بحاجة إلى معلومات عن الكلمات التي تعتبر إيجابية وأيها سلبية. توجد العديد من هذه القواميس ، لكننا سنأخذ قاموسًا بسيطًا جدًا (Hu و Liu ، 2004) ، والذي يتم استخدامه في المقال بواسطة Deep Averaging Networks .

قم بتنزيل القاموس من موقع Bing Liu واستخرج البيانات في data/positive-words.txt و data/negative-words.txt .

بعد ذلك ، نحدد كيفية قراءة هذه الملفات وتعيينها pos_words neg_words :

 def load_lexicon(filename): """       (https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html)      Latin-1.      ,    - .    ,    ';'   ,   . """ lexicon = [] with open(filename, encoding='latin-1') as infile: for line in infile: line = line.rstrip() if line and not line.startswith(';'): lexicon.append(line) return lexicon pos_words = load_lexicon('data/positive-words.txt') neg_words = load_lexicon('data/negative-words.txt') 

الخطوة 3. نقوم بتدريب النموذج على التنبؤ باللون


استنادًا إلى متجهات الكلمات الإيجابية والسلبية ، نستخدم الأمر Pandas .loc[] للبحث عن تمثيلات متجهة لكل الكلمات.

بعض الكلمات مفقودة في قاموس GloVe. غالبًا ما تكون هذه أخطاء مطبعية مثل "التخيل". نرى هنا مجموعة من NaN ، والتي تشير إلى عدم وجود ناقل ، وحذفها باستخدام الأمر .dropna() .

pos_vectors = embeddings.loc[pos_words].dropna()
neg_vectors = embeddings.loc[neg_words].dropna()


الآن نقوم بإنشاء صفائف من البيانات عند المدخلات (تمثيلات المتجهات) والإخراج (1 للكلمات الموجبة و -1 للسالب). نحن نتحقق أيضًا من أن المتجهات متصلة بكلمات حتى نتمكن من تفسير النتائج.

vectors = pd.concat([pos_vectors, neg_vectors])
targets = np.array([1 for entry in pos_vectors.index] + [-1 for entry in neg_vectors.index])
labels = list(pos_vectors.index) + list(neg_vectors.index)


- انتظر. بعض الكلمات ليست إيجابية ولا سلبية ، فهي محايدة. لا ينبغي إنشاء فئة ثالثة للكلمات محايدة؟

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

لذا جربت نسختي التي تحتوي على 800 مثال للكلمات وزادت وزني للتنبؤ بالكلمات المحايدة. لكن النتائج النهائية لم تكن مختلفة تمامًا عما ستراه الآن.

- كيف تميز هذه القائمة الكلمات الإيجابية والسلبية؟ لا يعتمد ذلك على السياق؟

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

يفهم الجميع أن الدرجة اللونية يتم تحديدها حسب السياق ، ولكن في نموذج بسيط عليك أن تتجاهل السياق وتأمل أن يكون متوسط ​​الدرجة اللونية خمّنًا بشكل صحيح.

باستخدام وظيفة train_test_split ، نقسم متجهات الإدخال وقيم المخرجات والعلامات في وقت واحد إلى بيانات تدريب واختبار ، مع ترك 10٪ للاختبار.

 train_vectors, test_vectors, train_targets, test_targets, train_labels, test_labels = \ train_test_split(vectors, targets, labels, test_size=0.1, random_state=0) 

الآن قم بإنشاء مصنف وتمرير المتجهات من خلال التكرار من خلالها. نحن نستخدم دالة الخسارة اللوجيستية حتى يتمكن المصنف النهائي من استنتاج احتمال أن تكون الكلمة إيجابية أو سلبية.

 model = SGDClassifier(loss='log', random_state=0, n_iter=100) model.fit(train_vectors, train_targets) SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1, eta0=0.0, fit_intercept=True, l1_ratio=0.15, learning_rate='optimal', loss='log', n_iter=100, n_jobs=1, penalty='l2', power_t=0.5, random_state=0, shuffle=True, verbose=0, warm_start=False) 

نحن تقييم المصنف على ناقلات الاختبار. هذا يظهر دقة 95 ٪. ليس سيئا

accuracy_score(model.predict(test_vectors), test_targets)
0.95022624434389136


نحدد وظيفة التنبؤ باللون لبعض الكلمات ، ثم نستخدمها لبعض الأمثلة من بيانات الاختبار.

 def vecs_to_sentiment(vecs): # predict_log_proba  log-    predictions = model.predict_log_proba(vecs) #        #  log-    . return predictions[:, 1] - predictions[:, 0] def words_to_sentiment(words): vecs = embeddings.loc[words].dropna() log_odds = vecs_to_sentiment(vecs) return pd.DataFrame({'sentiment': log_odds}, index=vecs.index) #  20      words_to_sentiment(test_labels).ix[:20] 

نغمة
تململ-9.931679
قاطع-9.634706
بثبات1.466919
وهمي-2.989215
الضرائب0.468522
العالم الشهير6.908561
غير مكلفة9.237223
خيبة أمل-8.737182
الشمولية-10.8151580
محارب-8.328674
يتجمد-8.456981
خطيئة-7.839670
هشة-4.018289
ينخدع-4.309344
بلا حل-2.816172
بذكاء2.339609
شيطاني-2.102152
الهم8.747150
لا يحظى بشعبية-7.887475
تعاطف1.790899

يتبين أن المصنف يعمل. لقد تعلم تعميم النغمة في الكلمات خارج بيانات التدريب.

الخطوة 4. الحصول على درجة اللونية للنص.


هناك العديد من الطرق لإضافة متجهات إلى التقدير الكلي. مرة أخرى ، نحن نتبع مسار أقل مقاومة ، لذلك فقط تأخذ متوسط ​​القيمة.

 import re TOKEN_RE = re.compile(r"\w.*?\b") # regex  ,     (\w)   #   (.+?)    (\b).   #       . def text_to_sentiment(text): tokens = [token.casefold() for token in TOKEN_RE.findall(text)] sentiments = words_to_sentiment(tokens) return sentiments['sentiment'].mean() 

هناك الكثير مما يجب طلبه للتحسين:

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

لكن كل شيء يتطلب رمزًا إضافيًا ولن يغير النتائج بشكل أساسي. على الأقل الآن يمكنك مقارنة العروض المختلفة تقريبًا:

 text_to_sentiment("this example is pretty cool") 3.889968926086298 

 text_to_sentiment("this example is okay") 2.7997773492425186 

 text_to_sentiment("meh, this example sucks") -1.1774475917460698 

الخطوة 5. ها الوحش أنشأنا


ليس كل جملة لها نغمة واضحة. دعونا نرى ما يحدث مع الجمل المحايدة:

 text_to_sentiment("Let's go get Italian food") 2.0429166109408983 

 text_to_sentiment("Let's go get Chinese food") 1.4094033658140972 

 text_to_sentiment("Let's go get Mexican food") 0.38801985560121732 

لقد واجهت بالفعل مثل هذه الظاهرة عند تحليل مراجعات المطاعم مع الأخذ في الاعتبار تمثيل ناقلات الكلمات. دون سبب واضح ، جميع المطاعم المكسيكية لديها درجة أقل عموما .

تمثيلات المتجهات التقاط الاختلافات الدلالي خفية في السياق. لذلك ، فهي تعكس تحيزات مجتمعنا.

فيما يلي بعض الاقتراحات المحايدة الأخرى:

 text_to_sentiment("My name is Emily") 2.2286179364745311 

 text_to_sentiment("My name is Heather") 1.3976291151079159 

 text_to_sentiment("My name is Yvette") 0.98463802132985556 

 text_to_sentiment("My name is Shaniqua") -0.47048131775890656 

حسنا اللعنة ...

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

تم استخدام هذا الاختبار بواسطة Caliscan و Bryson و Narayanan في بحثهما المنشور في مجلة Science في أبريل 2017. إنه يثبت أن دلالات اللغة اللغوية تتضمن تحيزات المجتمع . سوف نستخدم هذه الطريقة.

الخطوة 6. تقييم المشكلة


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

لدينا هنا أربع قوائم بأسماء تعكس خلفيات إثنية مختلفة ، خاصة في الولايات المتحدة الأمريكية. الأولى والثانية هي قوائم بأسماء "بيضاء" و "سوداء" في الغالب ، مقتبسة على أساس مقال لكاليسكان وآخرون ، كما أضفت أسماء إسبانية ومسلمة من العربية والأردية.

يتم استخدام هذه البيانات للتحقق من تحيز الخوارزمية أثناء عملية بناء ConceptNet: يمكن العثور عليها في الوحدة النمطية conceptnet5.vectors.evaluation.bias . هناك فكرة لتوسيع القاموس ليشمل المجموعات العرقية الأخرى ، مع مراعاة ليس فقط الأسماء ، ولكن أيضًا الألقاب.

وهنا القوائم:

 NAMES_BY_ETHNICITY = { #           . 'White': [ 'Adam', 'Chip', 'Harry', 'Josh', 'Roger', 'Alan', 'Frank', 'Ian', 'Justin', 'Ryan', 'Andrew', 'Fred', 'Jack', 'Matthew', 'Stephen', 'Brad', 'Greg', 'Jed', 'Paul', 'Todd', 'Brandon', 'Hank', 'Jonathan', 'Peter', 'Wilbur', 'Amanda', 'Courtney', 'Heather', 'Melanie', 'Sara', 'Amber', 'Crystal', 'Katie', 'Meredith', 'Shannon', 'Betsy', 'Donna', 'Kristin', 'Nancy', 'Stephanie', 'Bobbie-Sue', 'Ellen', 'Lauren', 'Peggy', 'Sue-Ellen', 'Colleen', 'Emily', 'Megan', 'Rachel', 'Wendy' ], 'Black': [ 'Alonzo', 'Jamel', 'Lerone', 'Percell', 'Theo', 'Alphonse', 'Jerome', 'Leroy', 'Rasaan', 'Torrance', 'Darnell', 'Lamar', 'Lionel', 'Rashaun', 'Tyree', 'Deion', 'Lamont', 'Malik', 'Terrence', 'Tyrone', 'Everol', 'Lavon', 'Marcellus', 'Terryl', 'Wardell', 'Aiesha', 'Lashelle', 'Nichelle', 'Shereen', 'Temeka', 'Ebony', 'Latisha', 'Shaniqua', 'Tameisha', 'Teretha', 'Jasmine', 'Latonya', 'Shanise', 'Tanisha', 'Tia', 'Lakisha', 'Latoya', 'Sharise', 'Tashika', 'Yolanda', 'Lashandra', 'Malika', 'Shavonn', 'Tawanda', 'Yvette' ], #         . 'Hispanic': [ 'Juan', 'José', 'Miguel', 'Luís', 'Jorge', 'Santiago', 'Matías', 'Sebastián', 'Mateo', 'Nicolás', 'Alejandro', 'Samuel', 'Diego', 'Daniel', 'Tomás', 'Juana', 'Ana', 'Luisa', 'María', 'Elena', 'Sofía', 'Isabella', 'Valentina', 'Camila', 'Valeria', 'Ximena', 'Luciana', 'Mariana', 'Victoria', 'Martina' ], #       # ,   .     . # #          # -   .    #   ,    . # #       . 'Arab/Muslim': [ 'Mohammed', 'Omar', 'Ahmed', 'Ali', 'Youssef', 'Abdullah', 'Yasin', 'Hamza', 'Ayaan', 'Syed', 'Rishaan', 'Samar', 'Ahmad', 'Zikri', 'Rayyan', 'Mariam', 'Jana', 'Malak', 'Salma', 'Nour', 'Lian', 'Fatima', 'Ayesha', 'Zahra', 'Sana', 'Zara', 'Alya', 'Shaista', 'Zoya', 'Yasmin' ] } 

باستخدام Pandas ، سنقوم بتجميع جدول أسماء وأصلهم العرقي السائد وتقييمات الدرجة اللونية:

 def name_sentiment_table(): frames = [] for group, name_list in sorted(NAMES_BY_ETHNICITY.items()): lower_names = [name.lower() for name in name_list] sentiments = words_to_sentiment(lower_names) sentiments['group'] = group frames.append(sentiments) #           return pd.concat(frames) name_sentiments = name_sentiment_table() 

بيانات العينة:

name_sentiments.ix[::25]
نغمةالمجموعة
محمد0.834974عربي / مسلم
ايليا3.916803عربي / مسلم
تيريل-2.858010أسود
خوسيه0.432956من أصل اسباني
لوسيانا1.086073من أصل اسباني
هانك0.391858أبيض
ميغان2.158679أبيض

سنقوم بوضع رسم بياني لتوزيع الدرجة اللونية لكل اسم.

 plot = seaborn.swarmplot(x='group', y='sentiment', data=name_sentiments) plot.set_ylim([-10, 10]) 

(-10, 10)



أو رسم بياني مع فواصل الثقة لمعدل 95 ٪.

 plot = seaborn.barplot(x='group', y='sentiment', data=name_sentiments, capsize=.1) 



أخيرًا ، قم بتشغيل حزمة إحصائيات statsmodels الخطيرة. سيُظهر مدى انحياز الخوارزمية (مع مجموعة من الإحصاءات الأخرى).


نتائج الانحدار OLS
قسم متغير:الشعورR تربيع:0.208
موديل:OLSمساعد R تربيع:0.192
الطريقة:المربعات الصغرىإحصاء F:04/13
التاريخ:الخميس ، 13 يوليو 2017دقق (إحصاء F):1.31e-07
الوقت:11:31:17احتمال الدخول:-356.78
رقم الملاحظات:153AIC:721.6
مدافع المتبقية:149BIC:733.7
مدافع نموذج:3
نوع التباين:نونبروست

إحصاء F هو نسبة التباين بين المجموعات إلى التباين داخل المجموعات ، والتي يمكن اعتبارها بمثابة تقييم عام للتحيز.

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

نحن بحاجة إلى تحسين قيمة F. كلما كان ذلك أفضل.

ols_model.fvalue
13.041597745167659


الخطوة 7. محاولة البيانات الأخرى.


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

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

 def retrain_model(new_embs): """      . """ global model, embeddings, name_sentiments embeddings = new_embs pos_vectors = embeddings.loc[pos_words].dropna() neg_vectors = embeddings.loc[neg_words].dropna() vectors = pd.concat([pos_vectors, neg_vectors]) targets = np.array([1 for entry in pos_vectors.index] + [-1 for entry in neg_vectors.index]) labels = list(pos_vectors.index) + list(neg_vectors.index) train_vectors, test_vectors, train_targets, test_targets, train_labels, test_labels = \ train_test_split(vectors, targets, labels, test_size=0.1, random_state=0) model = SGDClassifier(loss='log', random_state=0, n_iter=100) model.fit(train_vectors, train_targets) accuracy = accuracy_score(model.predict(test_vectors), test_targets) print("Accuracy of sentiment: {:.2%}".format(accuracy)) name_sentiments = name_sentiment_table() ols_model = statsmodels.formula.api.ols('sentiment ~ group', data=name_sentiments).fit() print("F-value of bias: {:.3f}".format(ols_model.fvalue)) print("Probability given null hypothesis: {:.3}".format(ols_model.f_pvalue)) #        Y plot = seaborn.swarmplot(x='group', y='sentiment', data=name_sentiments) plot.set_ylim([-10, 10]) 

نحن نحاول word2vec


يمكن افتراض أن GloVe فقط لديه المشكلة. من المحتمل أن يكون هناك الكثير من المواقع المشكوك فيها في قاعدة بيانات الزحف الشائعة وما لا يقل عن 20 نسخة من القاموس الحضري للشارع العامية. ربما سيكون من الأفضل على قاعدة مختلفة: ماذا عن الكلمة القديمة الجيدة التي تم تدريبها على أخبار Google؟

يبدو أن هذا الملف على Google Drive هو المصدر الأكثر موثوقية لبيانات word2vec. قم data/word2vec-googlenews-300.bin.gz وحفظه كـ data/word2vec-googlenews-300.bin.gz .

 #   ConceptNet   word2vec   Pandas     from conceptnet5.vectors.formats import load_word2vec_bin w2v = load_word2vec_bin('data/word2vec-googlenews-300.bin.gz', nrows=2000000) #  word2vec    w2v.index = [label.casefold() for label in w2v.index] #  ,    w2v = w2v.reset_index().drop_duplicates(subset='index', keep='first').set_index('index') retrain_model(w2v) 

Accuracy of sentiment: 94.30%
F-value of bias: 15.573
Probability given null hypothesis: 7.43e-09


لذلك تبين أن كلمة word2vec كانت أسوأ مع قيمة F لأكثر من 15.

من حيث المبدأ ، كان من الغباء توقع حماية الأخبار بشكل أفضل من التحيز.

محاولة ConceptNet Numberbatch


أخيرًا ، يمكن أن أتحدث عن مشروعي الخاص حول التمثيل المتجه للكلمات.

ConceptNet مع ميزة عرض المتجهات هي الرسم البياني للمعرفة الذي أعمل عليه. يعمل على تطبيع تمثيل المتجهات في مرحلة التدريب ، وتحديد وإزالة بعض مصادر العنصرية الخوارزمية والتمييز الجنسي. تعتمد طريقة تصحيح الانحياز هذه على مقالة علمية كتبها Bulukbashi et al. "Debiasing Word Embeddings" وهي معممة للقضاء على عدة أنواع من التحيز في وقت واحد. بقدر ما أعرف ، هذا هو النظام الدلالي الوحيد الذي يوجد فيه شيء من هذا القبيل.

من وقت لآخر ، نقوم بتصدير متجهات محسوبة مسبقًا من ConceptNet - تسمى هذه الإصدارات ConceptNet Numberbatch . في أبريل 2017 ، تم إصدار الإصدار الأول مع تصحيح التحيز ، لذلك سنقوم بتحميل المتجهات باللغة الإنجليزية وإعادة تدريب نموذجنا.

numberbatch-en-17.04b.txt.gz ، numberbatch-en-17.04b.txt.gz في data/ الدليل numberbatch-en-17.04b.txt.gz تدريب النموذج:

 retrain_model(load_embeddings('data/numberbatch-en-17.04b.txt')) 

Accuracy of sentiment: 97.46%
F-value of bias: 3.805
Probability given null hypothesis: 0.0118




لذلك ، هل قام ConceptNet Numberbatch بحل المشكلة تمامًا؟ لا مزيد من العنصرية الخوارزمية؟ رقم

هل أصبحت العنصرية أقل بكثير؟ بالتأكيد

تتداخل النطاقات الرئيسية للمجموعات العرقية أكثر بكثير من متجهات GloVe أو word2vec. بالمقارنة مع GloVe ، انخفضت قيمة F بأكثر من ثلاث مرات ، ومقارنة بـ word2vec - بأكثر من أربع مرات. وبشكل عام ، نرى اختلافات أصغر بكثير في الدرجة اللونية عند مقارنة الأسماء المختلفة: هذا يجب أن يكون كذلك ، لأن الأسماء يجب ألا تؤثر حقًا على نتيجة التحليل.

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

لا المزالق


يرجى ملاحظة أنه مع التبديل إلى ConceptNet Numberbatch ، تحسنت دقة التنبؤ باللون.

ربما اقترح شخص ما أن تصحيح العنصرية الخوارزمية سيؤدي إلى تفاقم النتائج بطريقة أخرى. لكن لا. قد يكون لديك بيانات أفضل وأقل عنصرية.البيانات تتحسن حقا مع هذا التصحيح. لا علاقة للعنصرية word2vec و GloVe المكتسبة من الناس بدقة الخوارزمية.

طرق أخرى


بالطبع ، هذه طريقة واحدة فقط لتحليل اللونية. بعض التفاصيل يمكن تنفيذها بشكل مختلف.

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

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

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

Source: https://habr.com/ru/post/ar436506/


All Articles