Vered Shwartz

I am a Computer Science PhD student in the Natural Language Processing lab at Bar-Ilan University. My research focuses on recognizing lexical semantic relations between words and phrases. I work on ontological relationships e.g., cat is a type of animal, tail is a part of cat; interpreting noun-compounds, e.g. olive oil is oil made of olives while baby oil is oil for babies; and identifying predicate paraphrases, e.g. that X die at Y may have the same meaning as X live until Y in certain contexts.
I am a Computer Science PhD student in the Natural Language Processing lab at Bar-Ilan University. My research focuses on recognizing lexical semantic relations between words and phrases. I work on ontological relationships e.g., cat is a type of animal, tail is a part of cat; interpreting noun-compounds, e.g. olive oil is oil made of olives while baby oil is oil for babies; and identifying predicate paraphrases, e.g. that X die at Y may have the same meaning as X live until Y in certain contexts.

איך מחוללים טקסט ומי מפחד מפייק ניוז ?

מיועד ל- מתחילים (כתבה קצת טכנית)

נכתב על ידי Vered Shwartz

בתחילת השנה OpenAI הכריזה על GPT-2, מודל שפה שפיתחה שמסוגל לג׳נרט (לחולל) טקסט שנראה כאילו נכתב ע״י אנשים. בעוד שבדרך כלל הכרזות כאלה מלוות בשחרור של מודל מאומן, OpenAI בחרו שלא לפרסם את המודל שלהם בטענה שהמודל ״מסוכן מדי״ ועלול לשמש לייצור של פייק ניוז. המהלך גרר ביקורת בטענה שהמטרה הייתה יחצ״נות למודל (אכן, הרשת דיווחה על המודל בהגזמה, כפי שבדרך כלל קורה), אך גם עורר דיונים מעניינים באתיקה ובאחריות של המפתחים לשימוש לרעה במודל שפיתחו. המודל המלא שוחרר לבסוף רק לאחרונה, כחצי שנה לאחר הפרסום. ברשומה זו אדבר על ג׳נרוט אוטומטי (generation) של טקסטים באמצעות מודלי שפה – איך מודלים כאלה מאומנים, איך משתמשים בהם לג׳נרט טקסט, והאם הם באמת מסוכנים?

מה זה מודל שפה?

מודל שפה הוא פונקציה המקבלת כקלט טקסט ומחזירה את ההתפלגות למילה[1] הבאה עפ״י כל המילים במילון. השימוש הכי מוכר ואינטואיטיבי של מודל שפה הוא השלמה אוטומטית, שמציעה את המילה או המילים הכי סבירות בהינתן מה שהמשתמש הקליד עד כה. מודל שפה טוב יתן הסתברות גבוהה למשפטים תחביריים (״מה אתה _״ ייתן הסתברות גבוהה לפעלים) ולמשפטים יותר הגיוניים מבחינת משמעות (״אני עייפה, אני רוצה _״ ישלים ״לישון״ לעומת ״אני רעבה, אני רוצה _״ שישלים ״לאכול״).

למה כולם מדברים פתאום על מודלי שפה?

הסיבה שכולם מדברים בשנה האחרונה על מודלי שפה היא לאו דווקא בגלל השימוש בהם לייצור טקסט חדש, אלא בעיקר בגלל השימוש בהם לייצוג טקסט קיים. עד לא מזמן, היה מקובל להשתמש בווקטורי מילים מאומנים מראש כדי לייצג את המילים בטקסט, במקום ללמוד אותם מאפס רק מהדאטה (המועט יחסית) של המשימה הספציפית. בשנה האחרונה מספר קבוצות מחקר גדולות שחררו מודלי שפה שאומנו על הרבה מאוד טקסט והראו כי ניתן להשתמש בהם כדי לייצג טקסט בייצוג ווקטורי. בניגוד לווקטורי מילים סטטיים, מודלי שפה מחשבים ווקטור דינמי לכל מילה כפונקציה של ההקשר בו הוא מופיע, מה שמאפשר לתת ייצוג שונה למילים רבות משמעות בהקשרים שונים. שימוש במודלי השפה מאומנים מראש במקום בווקטורי מילים מאומנים מראש שיפר את הביצועים באופן דרמטי במשימות NLP רבות, ורוב מודלי ה-NLP (בעיקר לשפות עם הרבה דאטה, כמו אנגלית) מבוססים היום עליהם. ברשומה הזו אנחנו מתמקדים דווקא בג׳נרוט טקסט, וספציפית, ג׳נרוט טקסט פתוח שאינו ״תרגום״ של קלט כלשהו (כמו בתרגום בין שפות, תמצות אוטומטי, תמלול של אודיו, וכו׳). כדי להשפיע על הנושא של הטקסט שהמודל מייצר, בדרך כלל מתנים את הג׳נרוט במשפט או פסקה קצרה בנושא הזה.

איך מג׳נרטים טקסט?

בהנחה שיש ברשותנו מודל שפה מאומן, איך מג׳נרטים באמצעותו טקסט? נניח שנתון לנו טקסט התחלתי w1 … wn (הטקסט ההתחלתי לא הכרחי, לצורך העניין n יכול להיות אפס). תהליך הג׳נרוט מתבצע מילה-מילה: מייצרים את המילה ה-n+1 כתלות ב-n המילים הקודמות, ואז את המילה ה-n+2 כתלות ב-n+1 המילים הקודמות (הטקסט ההתחלתי והטקסט שהמודל ג׳נרט) וכן הלאה. איך ״מג׳נרטים״ מילה?

הדרך הכי פשוטה היא האלגוריתם החמדני שבוחר את המילה הכי סבירה בהינתן הטקסט שקדם לה, בדיוק כמו בהשלמה אוטומטית. הצרה היא שהטקסט שנוצר בשיטה הזו הוא משעמם ומכיל בעיקר מילים וביטויים נפוצים. בפרט, הוא שונה מטקסט שאנשים מייצרים: לפי עקרון שיתוף הפעולה של גרייס, אנשים דווקא נוטים לומר את הפחות מובן מאליו ואת מה שמוסיף אינפורמציה למאזין.

האלטרנטיבה היא לדגום את המילה הבאה באופן פרופורציונלי להתפלגות שמשרה הטקסט. בשיטה הזו הטקסט מגוון יותר, אבל נוטה לפעמים להיות ״מגוון מדי״ או במילים פחות עדינות לג׳נרט זבל. הסיבה שזה קורה היא שלכל מילה במילון, כולל המילים הנדירות ואלה שסתם לא מתאימות בהקשר, קיימת הסתברות כלשהי, לרוב גדולה מאפס (גם אם מאוד קטנה) להיבחר. ברגע שנבחרה מילה כזו, המילה הבאה תלויה בה וכך הטקסט מתדרדר.

הפתרון הפשוט הוא שילוב של שתי הגישות: ראשית בוחרים את k המילים הכי סבירות (עבור קבוע כלשהו k) ואז דוגמים מביניהן. k גדול יהיה דומה יותר לדגימה מכל ההתפלגות בעוד ש-k קטן יהיה קרוב יותר לאלגוריתם החמדני. לחילופין, אפשר לקחת את המילים הכי סבירות שמסת ההסתברות שלהם מסתכמת בלכל היותר p (עבור קבוע p בין 0 ל-1) ולדגום מהן. גם כאן p קטן דומה לאלגוריתם חמדני ו-p גדול לדגימה מכל ההתפלגות. השיטה הזו נותנת יותר גמישות בכך שמס׳ המילים מהן דוגמים משתנה לפי ההקשר. יש הקשרים שבהן מעט מאוד מילים מתאימות (״אני עייפה, אני רוצה _״) לעומת הקשרים הרבה יותר כלליים (״אני _״).

לקוראים הטכניים יותר, תוכלו להציץ על דוגמאות קוד של האלגוריתם החמדני, דגימה מכל ההתפלגות, ודגימה מk המילים הכי סבירות. תוכלו לנסות את הקוד בקלות עם דוגמת צעצוע למודל שפה.

איך מאמנים מודל שפה?

שימו לב שאנחנו מדברים ספציפית על מודל שפה מבוסס רשתות נוירונים. מודל שפה מאומן באופן עצמוני (״self-supervised״), והדאטה שהוא צריך עבור האימון הוא פשוט קורפוס טקסט (למשל, כל וויקיפדיה). בזמן האימון, עוברים על הקורפוס משפט-משפט. עבור משפט נתון w1 … wn, ועבור כל מילה במשפט wi, המודל מנסה לחזות את wi בהינתן ההקשר (במודל פשוט ההקשר יהיה התחילית w1 … wi-1) ומעדכנים את הפרמטרים של המודל בהתאם.[2]

לצורך החיזוי, התחילית מקודדת לייצוג ווקטורי. המקודד (encoder) מקבל כקלט ווקטורי מילים של רצף מילים ומחזיר ווקטור המייצג את הרצף. המקודד יכול להיות מבוסס רשתות נוירונים רקורסיביות (RNN), או Transformer שמתבסס רק על מנגנון ה-Attention. הווקטור המייצג את הרצף נכנס למסווג שמחזיר ווקטור באורך אוצר המילים (גודל המילון), המייצג את ההתפלגות על המילה הבאה. כך תיראה ארכיטקטורת רשת של מודל שפה מבוסס RNN:

ארכיטקטורות שונות

ישנן מודלי שפה שפונקציית העלות שלהם שונה. למשל, BERT של גוגל מאומן לחזות מילים רנדומליות מתוך המשפט שהוחלפו ב״מסכה״, והוא דו-כיווני, כלומר הוא מסתמך גם על מילים שהופיעו אחרי המסכה. עם זאת, בגלל הדרך שבה אומן, BERT לא מאפשר לג׳נרט טקסט אלא רק לייצג טקסט קיים. מאידך, קיימים מודלים אחרים לג׳נרוט טקסט שאינם מודלי שפה. דוגמה לכך היא מודלים מבוססי GAN, בהם ה-Generator מייצר טקסט ותפקידו של ה-Discriminator לזהות שמדובר בטקסט מיוצר ולא ״אמיתי״. על אף ההצלחה האדירה של GANים על תמונות ווידאו, ההצלחה שלו על טקסט נכון לעכשיו יחסית מוגבלת, כנראה בגלל שבניגוד לוידאו ותמונות, טקסט הוא בדיד. ספציפית, מודלים מבוססי GAN כרגע פחות מוצלחים בג׳נרוט טקסט מאשר מודלי שפה.

איך מודדים את האיכות של מודל לג׳נרוט טקסט?

במשימות סיווג ניתן להפיק מספר בודד שמודד את רמת ההצלחה של המודל (למשל הדיוק שלו על סט הבדיקה), ולהשוות בין המדדים של מודלים שונים. במקרה של ג׳נרוט טקסט אין לנו פלט צפוי, מה שהופך את האבלואציה של מודלים כאלה ליותר מורכבת. בעיקר כשמדובר על ג׳נרוט טקסט ״פתוח״ לעומת תרגום, סט הבדיקה הוא פשוט אוסף של טקסטים שהמודל לא התאמן עליהם. האינדיקציה היחידה שהמודל איכותי, חוץ מאבלואציה ידנית יקרה, היא שהוא מייצר טקסט דומה לטקסט בסט הבדיקה מבחינת הסגנון (בין היתר, שהוא למד את התחביר, ואולי גם את הנושא, אם קורפוס האימון בדומיין מסוים). המדד המקובל להערכת מודלים לג׳נרוט טקסט הוא perplexity, שמודד עד כמה סביר לג׳נרט את סט הבדיקה ע״י מודל השפה (ככל שהוא נמוך יותר, המודל טוב יותר). ההסתברות של סט הבדיקה מחושבת ע״י מעבר מילה-מילה וחישוב ההסתברות לג׳נרט כל מילה במודל השפה בהינתן המילים שקדמו לה. מודל שפה טוב יתן הסתברות גבוהה למילה ה״נכונה״ (המילה שהופיעה בפועל) והסתברות נמוכה למילים אחרות.

למרות השימוש הרווח ב-perplexity, המדד אינו חף מביקורת. בפועל, הוא לא מהווה אינדיקציה טובה להצלחה במשימות קצה. בנוסף, הוא מדד הסתברותי וככזה הוא יכול למדוד את האיכות רק של מודלים הסתברותיים (מודלים שהפלט שלהם הוא התפלגות).

אז… יש לנו ממה לחשוש?

בגדול, תמיד יש ממה לחשוש, אבל החשש שלי בדרך כלל מופנה לאנשים ולשימוש הרע שהם יכולים לעשות בכלים טכנולוגיים, ופחות להפחדות סטייל ״הרובוטים יפתחו מודעות ויהרסו את האנושות״. ספציפית בתחום ג׳נרוט טקסטים, החשש שהועלה בהכרזה של OpenAI בתחילת השנה היה מפני ייצור נרחב של פייק ניוז. אף על פי שזה לא לגמרי מופרך, כרגע ישנן מגבלות בג׳נרוט טקסט שמרחיקות את חלום הבלהות הזה.

למודלים אין אג׳נדה

כשאנשים מייצרים פייק ניוז, הם עושים את זה עם מטרה – בדר״כ לקדם תעמולה מסוימת או להכניס תעבורה לאתר שלהם כדי להרוויח מפרסום מקוון. בניגוד לאנשים, למודלי שפה אין אג׳נדה. רוב מודלי השפה היום נבנו כך שניתן לג׳נרט באמצעותם טקסט שנראה אמין ואנושי. מעט מאוד מודלים היום בכלל מסוגלים לג׳נרט טקסט מותנה בסגנון או שמצופה ממנו להגיע לאיזושהי פואנטה.

טקסט מג׳ונרט שונה מטקסט אנושי

אחד המודלים הבודדים שמסוגלים לג׳נרט טקסט מבוקר הוא גרובר, שנבנה לג׳נרוט של פייק ניוז מותנה בפרמטרים של תאריך, עיתון, עיתונאי, וכותרת. אמנם השימוש לרעה במודל די ברור מאליו, אך הג׳נרטור של גרובר פותח יחד עם מסווג שיודע להבדיל בדיוק של למעלה מ-90% בין חדשות אמיתיות למג׳ונרטות. הוא למד לזהות את ההבדלים הקטנים בסגנון שבין טקסט שנכתב ע״י אנשים וכזה שנכתב ע״י מכונה, והוא מצליח לזהות גם טקסט שג׳ונרט ע״י מודל גנרטיבי אחר (למשל GPT). וזוהי בדיוק החולשה השנייה של מודלי שפה כיום – הטקסט שהם מג׳נרטים הוא לא ממש אנושי, רק ליד.

נכון, טקסט מג׳ונרט היום הוא תחבירי ומצליח ברוב המקרים לא לסטות מהנושא, וזה כשלעצמו מרשים. אבל הוא לא מודע לעובדות (ראו מאמר עם השם המשעשע Baracks Wife Hillary), יש לו מעט מאוד הגיון וידע עולם, ולרוב נקרא קצת ״לא אנושי״ (גם אם אנחנו לא יודעים להסביר מה בדיוק הופך אותו לכזה). גם כשאנחנו נופלים בפח, ישנם מודלים שיכולים בדיוק גבוה מאוד לומר שהטקסט ג׳ונרט ולא נכתב ע״י אדם.

הפחד מדיסאינפורמציה הוא מוצדק, אבל לפחות כרגע, אני יותר מוטרדת מהאנשים המעורבים בדיסאינפורמציה: אלה שיוצרים אותה, אלה שמפיצים אותה בכוונה רעה, ובמיוחד אלה שמפיצים אותה מתוך בורות ונאיביות. אולי כדאי שבמקביל לפיתוח הטכנולוגיות בעלות המטרות המנוגדות של לייצר ולזהות דיסאינפורמציה, נתחיל גם ללמד אנשים לחשוב באופן יותר ביקורתי.

קריאה נוספת:

Text Generation (אותה הכתבה באנגלית, מהבלוג שלי)

[1] רוב מודלי השפה היום לא מבוססי מילה אלא תו או רצפי תווים (חלקי מילה). לצורך פשטות, ברשומה זו נעסוק במודל שפה מבוסס מילה.

[2] חדי האבחנה מביניכם בוודאי ישימו לב שבניגוד להרבה משימות סיווג אחרות, בשפה בדר״כ אין תשובה אחת נכונה וניתן להשלים את המשפט ביותר מדרך אחרת. כלומר, באופן אופטימלי לא היינו רוצים להעניש את המודל על שחזה מילה לא נכונה אם היא מתאימה בהקשר. אכן, ישנה עבודה על חיזוי של ווקטורי מילים במקום התפלגות על המילון.

Posted by Vered Shwartz in deep

כשהאלגוריתם גזען או שוביניסט: על תחום ההוגנות בבינה מלאכותית

מיועד ל- כל אחד (כתבה לא טכנית)

נכתב על ידי Vered Shwartz

תהליכי קבלת החלטות רבים מסתמכים היום על אלגוריתמים מבוססי בינה מלאכותית, למשל סיווג של מועמדים למשרות, הערכת הסיכוי של עבריין מורשע לחזור לפשוע, אישור או דחייה של בקשת הלוואה, וכו’. ככל שתחום הסמכויות של האלגוריתמים גדל, עולה הצורך לוודא שהאלגוריתמים הוגנים ושהם לא מפלים לרעה קבוצות באוכלוסיה על סמך מאפיינים כמו גזע, מין ונטייה מינית. ברשומה הזו נדון בכמה מהבעיות בתחום ואף נדגים שתיים מהן.

בעיות בפונקצית המטרה ובחומר האימון

באימון של מודלי למידת מכונה אנחנו עושים אופטימיזציה למטריקות כמו דיוק שלוקחות בחשבון את המקרה הממוצע. מערכי נתונים נוטים להכיל מעט דוגמאות לאוכלוסיות קטנות, וכך קורה שהמודל לומד פחות טוב את האוכלוסיות הקטנות האלה, ואחוז הטעות עליהן גבוה יותר. לדוגמה, זיהוי פנים נחשב לבעיה פתורה, אבל מחקר שבחן מקרוב את המודלים גילה שהם אמנם עובדים טוב עבור פנים של גברים לבנים, אבל בעשרות אחוזים פחות טוב עבור נשים שחורות. זה תוצר ישיר של אחוז דוגמאות האימון של נשים שחורות במערך הנתונים, והמשמעות המעשית של מודל כזה שהותקן בשדה תעופה היה שנשים שחורות עוכבו בבדיקות ביטחוניות יותר מגברים לבנים.

כדי להמחיש, נסתכל על דוגמת צעצוע של מודל לזיהוי פנים שמאומן על מערך נתונים מאוד מוטה, עם הרבה תמונות של גברים ומעט תמונות של נשים. התוצאה היא שביצועי המודל כמעט מושלמים עבור גברים, אבל הרבה פחות טובים עבור נשים.

בעיה נוספת הקשורה למטריקה היא שהיא לרוב לא נותנת משקל שונה לטעויות שונות. לא בטוח שזה מצב רצוי, כלומר, היינו רוצים שתיוג אוטומטי של תמונה עם אדם שחור כגורילה ייחשב לטעות חמורה הרבה יותר מאשר לטעות בין צ’יוואווה למאפין.

זליגה של הטיות אנושיות (bias) לתוך האלגוריתמים

ניקח לדוגמה את המקרה שהופיע בחדשות לאחרונה, לפיו חברת אמזון השתמשה באלגוריתם בינה מלאכותית כדי לסנן קורות חיים של מועמדים לעבודה, והאלגוריתם התברר כמפלה לרעת נשים. גם מבלי לדעת כלום על המודל שאמזון פיתחו, אפשר לנחש היכן עלולות להתעורר בעיות. אחת הבעיות הנפוצות בסיווג מונחה, שנידונה בפירוט בספר Weapons of Math Destruction של קאת’י אוניל, היא בעיית הפרוקסי: הרבה פעמים אין לנו דרך למדל את מה שאנחנו רוצים למדל באמת, למשל, לחזות את רמת ההצלחה של מועמד לעבודה בתפקיד מסוים. במקום, אנחנו מתפשרים על פרוקסי, למשל, האם עובד כוח אדם שסינן קורות חיים של מועמדים עבור משרה אחרת בעבר החליט להעביר או לפסול קורות חיים מסוימים. כך אנחנו מכניסים הטיות אנושיות לתוך תהליך ההחלטה: אם העובד, בין אם באופן מודע ובין אם לאו, העדיף לסנן קורות חיים של נשים עבור תפקיד טכני כי בתפיסה שלו נשים הן פחות טכניות, כעת המודל שלנו ילמד לחקות את ההתנהגות הזו. כאשר משתמשים במודל בהיקף נרחב, הנזק מתעצם.

בעיה נוספת נובעת מהייצוגים שאנחנו משתמשים בהם עבור הנתונים. דיברנו באחת הרשומות הקודמות על ייצוגי מילים. ייצוגי מילים שנלמדים מטקסטים כוללים, באופן לא מפתיע, גם קורלציות סטטיסטיות פחות רצויות. כך יוצא שהוקטור של מתכנת קרוב יותר לוקטור של גבר מאשר לוקטור של אישה, שקרוב יותר למילה לוקטור של עקר/ת בית  (homemaker באנגלית, מילה נייטרלית מבחינה מגדרית). באופן אידיאלי היינו רוצים לתקן את החברה ולא את האלגוריתם, כלומר, לעודד שאנשים יעסקו במקצוע שמושך אותם ללא תלות במגדר שלהם. עד שזה יקרה, צריך לקחת בחשבון את ההטיות האלה, כיוון שהן יכולות לזלוג לתוך אלגוריתמים מקבלי החלטה ולהנציח את הבעיה – כלומר לגרום לכך שהאלגוריתם יעדיף גבר לתפקיד של מתכנת.

כדי להמחיש, נטען וקטורי מילים מאומנים מראש (GloVe) ונתמקד במילים מתוך רשימת מקצועות. נטיל את הוקטורים למימד 2 ונראה שהכיוון של זוגות מילים כמו doctor/nurse דומה לכיוון של he/she.

מודלי “קופסה שחורה”

ההוגנות של אלגוריתם נפגעת כשלנו המשתמשים של האלגוריתם (או המושפעים מההחלטות שלו) אין דרך לדעת מה הוביל לקבלת החלטה מסוימת. דוגמה לכך יכולה להיות אדם המגיש מועמדות לעבודה בחברה גדולה והבקשה שלו נידחת ע”י סינון אוטומטי של קורות החיים שלו. במקרה הטוב הוא יקבל הודעת דחייה גנרית שלא מפרטת מדוע בקשתו לא התקבלה, ובמקרה הגרוע הוא פשוט לא יקבל תשובה. בהרבה מהמקרים האלה הרציונל שמאחורי ההחלטה שקיבל האלגוריתם לא נחשף כיוון שזהו סוד מסחרי של החברה שפיתחה ומשתמשת באלגוריתם. לאחרונה, עם השימוש בלמידה עמוקה, הדבר נובע מבעיה אינהרנטית יותר של חוסר היכולת של אלגוריתמים להסביר את ההחלטות שלהם (Explainability). מכיוון שהפיצ’רים חבויים, גם מפתחי האלגוריתם לא בהכרח יודעים להסביר מה עומד מאחורי ההחלטה של האלגוריתם.

ניקח לדוגמה מודל שהבנק מפתח על מנת להחליט האם לאשר לאדם כלשהו קבלת הלוואה. בתיאוריה, המודל יכול להיות הוגן יותר מבנקאי המקבל החלטה על סמך תחושת בטן, היכרות אישית עם מבקש ההלוואה, או הטיות בלתי מודעות. במודל כזה אין צורך בפרוקסי: ניתן ללמוד אותו מהלוואות עבר שאושרו, והאם הלווה החזיר את ההלוואה בזמן או לא. עם זאת, עדיין עומדים בפני האלגוריתם אתגרים הקשורים להוגנות: ישנן קורלציות סטטיסטיות שלא נרצה שהאלגוריתם יבסס עליהן את ההחלטה. למשל, בארה”ב אנשים שחורים עניים יותר בממוצע מלבנים. עוני יכול להעיד על יכולת החזרה הלוואה, אבל זה לא יהיה הוגן להשתמש בקורלציה הזו כדי לדחות בקשה להלוואה מאדם רק כי הוא שחור. אנחנו רוצים שהאלגוריתם יקבל החלטה על סמך הנתונים של מבקש ההלוואה, ולא על סמך אנשים דומים לו. לכן, כדי שהאלגוריתם יהיה הוגן ככל האפשר, המפתחים נמנעים מלכלול פיצ’רים רגישים כגון מין וגזע. לכאורה, האלגוריתם עיוור למאפיינים האלה ולכן לא יכול להפלות אנשים לפיהם.

בפועל, לאלגוריתם יש גישה למאפיינים האלה דרך קורלציה למאפיינים אחרים, כמו למשל מיקוד, שיש לו קורלציה גבוהה לגזע בארה”ב. בעוד שבמקרה הזה עדיין יחסית קל לאתר ולהסיר מאפיינים שיש להם קורלציה למאפיינים רגישים, העניינים מסתבכים כשעוברים להשתמש בלמידה עמוקה, והמאפיינים נלמדים גם הם. נניח שהמפתחים מחליטים לייצג את הטקסט הנלווה לבקשת ההלוואה באמצעות וקטור ולהשתמש בו לסיווג. הוקטור יכיל לא רק מאפיינים הקשורים לתוכן הבקשה אלא גם מאפיינים הקשורים בסגנון כתיבה או בחירת מילים, שגם הם יכולים לשמש את האלגוריתם כדי לשחזר את מאפיין הגזע שהמפתחים ניסו להסתיר.

אז מה עושים? אפשר להשתמש בשיטה שנקראת Adversarial Training שבה מנסים באופן אקטיבי להסיר מהייצוג החבוי מאפיינים רגישים. הרעיון הוא לאמן את המסווג הראשי f (האם לאשר הלוואה או לא) על ייצוג X, ובמקביל לאמן מסווג שני g המנסה לחזות את המאפיין הרגיש (מה הגזע של מבקש ההלוואה) מאותו הייצוג X. ע”י גרדיאנט הפוך גורמים ל-f “לשכוח” את מה ש-g למד וכך הייצוג הופך להיות עיוור למאפיין הרגיש. אך לאחרונה יצא מאמר שהראה שגם השיטה הזו לא מסירה באופן מושלם את המאפיינים הרגישים.

ניסיון לפתור את חוסר ההוגנות כרוך הרבה פעמים בטרייד-אוף בין הדיוק של המודל על המקרה הממוצע לבין הוגנות. ירידה בדיוק של מודל של חברה מסחרית עשויה להיתרגם ישירות לאובדן כספי. לכן, מעבר לבעיה הטכנית של כיצד לזהות ולהתגבר על חוסר הוגנות באלגוריתמים, ישנה בעיה גם ברמת התמריץ של החברות המפתחות את האלגוריתמים. עם זאת, החברות הגדולות היום מודעות לנושא ומשקיעות בו משאבים: לגוגל למשל יש צוות שלם המוקדש לנושא.

קריאה נוספת:

אתיקה בלמידת מכונה, מהבלוג שלי (אנגלית)

פרק על הוגנות בפודקאסט “Unsupervised”

Posted by Vered Shwartz in deep

כיצד לייצג מילים כמספרים בעלי משמעות? על הבסיס לאלגוריתמי NLP

מיועד ל- כל אחד (כתבה לא טכנית)

נכתב על ידי Vered Shwartz

בכתבה זו נעסוק בייצוג וקטורי של מילים עבור אלגוריתמים לניתוח שפה טבעית (NLP).

מספרים במקום מילים

בשביל מה צריך וקטורים? הייצוג הוא רק אמצעי כאשר המטרה היא משימת קצה כלשהי בעיבוד שפות טבעיות. כיום רוב האלגוריתמים מבוססי למידה עמוקה והם מסתמכים על קלט וקטורי. מילה נחשבת ליחידה הבסיסית של משמעות בשפה, וייצוג “טוב” שלה הוא קריטי עבור האיכות של אלגוריתמים שונים להבנת שפה. בנוסף, ייצוג מילים מהווה גם בסיס לייצוג של רצפים ארוכים יותר (משפט, פסקה, מסמך, וכו’).

לצורך ההדגמה, לאורך הרשומה נתרכז במשימת קצה אחת מיני רבות שיכולה להדגים את השימוש בווקטורי מילים: סיווג טקסטים. במשימה הזו, האלגוריתם מקבל אוסף של מסמכים וצריך לסווג אותם לפי הנושא בו הם עוסקים, מתוך רשימה מוגדרת מראש של נושאים (לדוגמה: ספורט, חדשות, מוזיקה וכו’).

ייצוג לפי אינדקס (One-hot Vector)

הייצוג הווקטורי הבסיסי ביותר. נניח שקיים אוצר מילים (vocabulary) שמכיל את כל סוגי המילים בשפה (word types), נסמנו V. אם אין לנו כזה אוצר מילים, אפשר לבנות אותו מקורפוס (אוסף גדול של טקסטים) ע”י כך ששומרים מופע אחד (word token) של כל מילה. נהוג גם לוותר על ה”זנב הארוך” של המילים המאוד נדירות ולהתייחס רק למילים שהופיעו מספיק פעמים בקורפוס. 

כל מילה יושבת באינדקס נומרי מסוים ב-V, למשל יכול להיות ש”חתול” יהיה באינדקס 1242 ו”מחשב” באינדקס 1587. בניגוד למילון שבו כל מילה מופיעה בצורתה הבסיסית ובלי הטיות, באוצר המילים שלנו מופיעה כל צורה כמילה נפרדת. למשל, יכול להיות ש”חתולים” יהיה באינדקס 454. 

בייצוג one-hot-vector אנחנו מייצגים כל מילה באמצעות האינדקס שלה ב-V. מילה w באינדקס i מיוצגת ע”י וקטור שאורכו כגודל אוצר המילים – |V|, וכל ערכיו 0 פרט לאינדקס i שערכו 1. ככה ייראו וקטורים של כמה מילים לדוגמה:

nlp

הבעיה העיקרית בייצוג הזה היא שאין שום קשר בין המשמעות של המילה לבין האינדקס שלה. בפרט, מדדי דמיון וקטוריים כמו מדד קוסינוס לא מעידים על דמיון סמנטי בין מילים (ולמעשה, המדד ייתן 0 עבור כל זוג מילים, בין אם “חתול” ו”חתולים” או “חתול” ו”מחשב”).

בהקשר של משימת הקצה של סיווג טקסטים, מקובל לייצג מסמך ע”י קבוצת כל המילים שהופיעו בו (שאמורות להעיד על הנושא שלו). כלומר, מרחב הפיצ’רים הוא כל המילים הקיימות בשפה, וערך הפיצ’ר של מילה מסוימת w במסמך d יהיה פרופורציונלי למס’ ההופעות של המילה w במסמך d. ייצוג של מסמך ע”י סכימה של כל ווקטורי ה-one-hot של המילים המופיעות בו ייתן לנו בדיוק את זה. עכשיו נניח שבזמן האימון המסווג שלנו ראה הרבה מסמכים מתויגים לנושא “טכנולוגיה” שהכילו את המילה “מחשב”. הוא לומד שהמילה “מחשב” היא פיצ’ר חזק עבור הנושא “טכנולוגיה”. כעת נראה למסווג מסמך שמדבר על מחשבים ניידים והוא יכיל הופעות רבות של המילה “לפטופ”. אם המסווג לא נתקל בזמן האימון (מספיק פעמים) במילה “לפטופ” במסמכים בנושא טכנולוגיה, הוא לא ידע להשלים את המידע החסר הזה מהדמיון למילה “מחשב”. שתי המילים האלה הן פיצ’רים נפרדים לחלוטין עבור המסווג. זה לא מצב טוב.

ייצוג מבוסס שכנים (Distributional Vectors)

כל הפתרונות הבאים שנראה מבוססים על הנחה בלשנית (Distributional Hypothesis) שבבסיסה עומד ההיגיון הפשוט “תגיד לי מי השכנים שלך ואומר לך מי אתה”. מילים הנוטות להופיע באותן ההקשרים (לצד אותן מילים “שכנות”), הן בדר”כ דומות במשמעות שלהן. למשל, מילים נרדפות כמו “אווירון” ו”מטוס” יופיעו ליד מילים כמו “נחיתה”, “המראה”, “טיסה” וכו’. דמיון סמנטי לא מוגבל רק למילים בעלות אותה המשמעות. גם למילים הקשורות אחת לשנייה מבחינה תחבירית (חתול/חתולים), נושאית (מטוס/דיילת), בקשר של הכלה (לפטופ/מחשב) ואפילו בקשר של דבר והיפוכו (חם/קר) יהיו ווקטורים דומים.

הרעיון הוא שווקטור של מילה w יהיה כעת עדיין באורך |V|, אבל המשמעות של כל כניסה בווקטור תהיה שונה. הערך של כניסה u בווקטור של w יהיה פרופורציונלי למס’ הפעמים ש-w ו-u הופיעו ביחד בקורפוס האימון. ההגדרה של “הופיעו יחד” גמישה, אבל באופן הפשוט נניח הופעה של u בחלון של k מילים (למשל k=5) סביב w. הערך עצמו יכול להיות מספר ההופעות המשותפות, מספר מנורמל (הסתברות), או מדד כמו PMI, המפחית את ההשפעה של השכיחות של כל מילה בפני עצמה.

שיטות ספירה (Count-based Vectors)

הדבר הפשוט ביותר לעשות יהיה לעבור על קורפוס האימון, ולבנות את מטריצת ההופעות המשותפות (בגודל |V|x|V|) של כל מילה w עם מילה u בחלון בגודל k. השורות של המטריצה משמשות בתור ווקטורי מילים, ואותן אפשר לנרמל (למשל באמצעות PMI). ככה יראו עכשיו הווקטורים של המילים לדוגמה. נראה יותר טוב, לא?

nlp

היתרון של השיטה הזו על פני one-hot הוא בכך שלמילים בעלות משמעות דומה (למשל “מחשב” ו”לפטופ”) יהיו ווקטורים דומים מכיוון שהן מופיעות לצד אותן מילים שכנות (“עכבר”, “חומרה”, “מסך” וכו’), כפי שניתן לראות באיור. הדמיון יכול בקלות להימדד ע”י שימוש במדדי דמיון של ווקטורים כמו קוסינוס. בהקשר של משימת הקצה שלנו, אם נייצג מסמכים שוב כסכום/ממוצע של ווקטורי המילים המופיעות במסמך, נוכל להרוויח מהדמיון הזה. אם האלגוריתם שלנו למד לסווג מסמך המכיל את המילה “מחשב” ועכשיו ניתן לו מסמך דומה מאוד אבל שמדבר על “לפטופ” במקום, הייצוג הווקטורי של המסמכים יהיה דומה בזכות הדמיון הווקטורי בין “מחשב” ל”לפטופ”. האלגוריתם מצליח להכליל את החוקים שהוא למד בזכות דמיון מילים.

החיסרון של הווקטורים האלה הוא שהם כבדים מבחינה חישובית. מדובר על ווקטורים דלילים ממימד מאוד גבוה – גודל אוצר המילים בדר”כ נע בין כמה עשרות אלפים לכמה מיליונים.

שיכוני מילים (Word Embeddings)

אז איך אפשר להשיג ווקטורים דחוסים ממימד נמוך ששומרים על התכונה הטובה של הייצוג מבוסס השכנים? נקפוץ כמה שנים קדימה (ונדלג על פתרון הביניים – הפעלת אלגוריתם להורדת מימדים כגון SVD על מטריצת ההופעות המשותפות). במקום לספור הופעות משותפות, אפשר להחליט מראש על מימד קטן כלשהו D (בדר”כ 50-1000, הכי נפוץ 300) ולחזות ווקטורים באורך D שישמרו על התכונה הזו – כלומר, שלמילים שמופיעות באותם ההקשרים יהיו ווקטורים דומים. למרות שהרעיון הזה כבר הוצע ב-2003 עי בנגיו וקולגות, הוא זכה לפופולריות רק ב-2013 כשמיקולוב וקולגות פרסמו את word2vec (שהמימוש שלו היה יעיל, והתוצאות מרשימות). ככה ייראו הווקטורים, קטני מימדים ודחוסים, ועדיין שומרים על תכונת הדמיון:

nlp

הרעיון של word2vec הוא ללמוד מטריצה בגודל |V| על D, שכל שורה בה מייצגת מילה. זאת המטריצה של מילות היעד (target). כעזר, מחזיקים מטריצה נוספת באותם המימדים שמייצגת מילה כמילת הקשר (context). שתי המטריצות מאותחלות אקראית. בזמן האימון, האלגוריתם עובר על כל הקורפוס, מילה-מילה, כאשר בכל פעם מילה אחת נחשבת ליעד והמילים המקיפות אותה בחלון נחשבות למילות ההקשר. יש שתי גרסאות לאלגוריתם: באחת (CBOW = continuous bag of words), מנסים לחזות את מילת היעד ממילות ההקשר, ובשנייה (skip-gram), מנסים באמצעות מילת היעד לחזות את מילות ההקשר. כפועל יוצא של החיזוי הזה, הווקטור של מילת היעד (ממטריצת היעד) מתקרב לווקטורים של מילות ההקשר (ממטריצת ההקשר). נוסף על כך, ווקטור היעד צריך להתרחק מווקטורי ההקשר של המילים שלא הופיעו בחלון. בגרסה היעילה יותר (negative sampling), דוגמים k מילים אקראיות כלשהן (שכנראה לא הופיעו בחלון) ומוסיפים לפונקציית המטרה גורם דומה לחיזוי של מילות ההקשר אבל עם המילים האקראיות ומוכפל במינוס 1.

חוץ מ-word2vec יש עוד לא מעט אלגוריתמים שונים ללמידה של word embeddings ע”י חיזוי, הנפוצים מביניהם GloVe של סטנפורד ו-FastText של פייסבוק. בשנים האחרונות הם משמשים כקלט לכל אלגוריתם למידה בתחום עיבוד שפה, בין אם בשימוש בווקטורים המאומנים שפורסמו עם השיטות האלה או באימון מחדש על קורפוס אחר. בהקשר של משימת סיווג הטקסטים שלנו, נוכל עדיין לייצג מסמך ע”י סכום או ממוצע וקטורי המילים. וקטור מסמך יהיה כעת באורך D והפיצ’רים שלו יהיו חבויים, אבל מסמכים עם מילים דומות עדיין יקבלו ייצוג דומה ויסווגו לאותו הנושא, ובמחיר חישובי נמוך יותר. המטרה הושגה!

בעיניי ההצלחה של הווקטורים נמדדת בעיקר בכמה שהם משפרים ביצועים של משימות קצה וכמה קל השימוש בהם. במאמרים המתארים את האלגוריתמים ליצירת הווקטורים, נהוג לדווח על תוצאות על שתי משימות מלאכותיות שבוחנות את איכות הווקטורים: (1) מודל רגרסיה שחוזה דמיון בין מילים בהסתמך על הווקטורים (ומושווה לציוני הדמיון שאנשים נתנו לזוגות מילים), ו-(2) פתרון של בעיות אנלוגיה מהסוג “גבר:מלך ::אישה:?”. הנה דוגמה לאיך שהאנלוגיות האלה נראות במרחב הווקטורי, מתוך המאמר של word2vec:

nlp

תודה ל https://www.kdnuggets.com/2016/05/amazing-power-word-vectors.html

בתור מדד איכותי, נהוג לחשב הטלה של הווקטורים למימד 2 ע”י t-SNE או PCA ולצייר גרף מילים שממנו ניתן לראות שמילים דומות סמנטית ממוקמות זו לצד זו ב(הטלה למימד 2 של ה)מרחב הווקטורי. הנה דוגמת קוד לחישוב הזה, וכך למשל נראה חלק קטן מהגרף המתקבל כשמפעילים t-SNE על GloVe (מאומן מראש, בגודל 50):

nlp

העתיד של ייצוגי מילים

כיום יש הרבה אלגוריתמים שעובדים ברמת התו (char-based) ולא ברמת המילים. זה מועיל עבור מילים שאינן מאוד נפוצות בקורפוס, אבל דומות בתווים למילים אחרות במשמעות דומה. זה קורה במיוחד בשפות בהן המורפולוגיה עשירה – כמו עברית. בשפות כאלה, מילים מורכבות מ”שורש” כלשהו, תחיליות וסופיות, והטיות שונות של אותו השורש יהיו דומות גם מבחינת משמעות וגם מבחינת הרכב התווים. בנוסף, אם מפעילים שיטה כזו על קורפוס של טקסטים ממדיה חברתית, עבודה ברמת התווים יכולה לעזור במקרה של שגיאות כתיב וקיצורים. החיסרון היחסי לעומת חישוב ווקטורים ברמת המילים היא שנדרש יותר חומר אימון כדי לקבל ווקטורים איכותיים.

ההתפתחות האחרונה בייצוגי מילים היא ההכרה שמשמעות של מילה נגזרת לא רק מהמשמעות הכללית שלה אלא גם במשמעות שלה בהקשר נתון, וזה נכון בעיקר (אבל לא רק) עבור מילים רבות משמעות. למשל, המילה “עכבר” במשפט “קניתי מקלדת ועכבר אלחוטיים” שונה במשמעותה מאשר במשפט “החתול רדף אחרי העכבר”. במקום לייצג את המילה “עכבר” בווקטור יחיד שמאגד את כל ההופעות שלה בקורפוס (בשתי המשמעויות), אפשר לחשב את הווקטור הזה בכל פעם מחדש עבור השימוש הספציפי, ושיהיה תלוי-הקשר. זה מה שעושים בשיטת ELMo שלאחרונה זכתה בפרס המאמר הטוב ביותר בכנס NAACL 2018. לא מעט מאמרים יצאו לאחרונה שהראו ששימוש ב-ELMo משפר ביצועים של משימות קצה על-פני שימוש בווקטורים סטטיים. ההקשר חשוב. החיסרון הברור הוא כמובן שהשימוש בווקטורים דינאמיים הרבה יותר כבד מבחינה חישובית: במקום לשלוף ווקטור מוכן צריך לחשב אותו בכל פעם מחדש ע”י מעבר על כל המשפט… אין מתנות חינם.

Posted by Vered Shwartz in deep