”מכיוון שראית את…”: כך עובד אלגוריתם המלצות הצפייה של נטפליקס
כיצד יודעים שירותי הסטרימינג כמו נטפליקס אילו סדרות וסרטים אנחנו אוהבים? הנה הסבר מקצועי על האלגוריתם בצירוף קטעי קוד רלוונטיים
מאת: איתי כנרות ועופר הלמן
בשנים האחרונות אנחנו רואים פריחה של עשרות שירותי סטרימינג שונים, כשכל אחד מהם מציג תכנים ייחודיים ובלעדיים לו. אבל שאלת מיליון הדולר, שמרבית השירותים הללו שואלים את עצמם היא מה הצופים מחפשים. או במילים אחרות, מעבר לתוכן, שהוכתר כבר למלך, מה גורם לצופים לאהוב שירות כזה או אחר ולהישאר נאמן לו לאורך זמן.
אחת מנקודות החוזקה הגדולות שהשירותים השונים יכולים להציע היא הכרה טובה יותר של המשתמש והמלצות צפייה שמותאמות לו אישית. היכולת הזו טובה לכולם. הן למשתמש, שמקבל תכנים שמותאמים על פי הטעם האישי וחוסך כך זמן יקר, והן לשירות הסטרימינג שרוצה שהמשתמשים ישהו אצלה כמה שיותר זמן.
ההיסטוריה
בשנת 2007 חברה קטנה שניסתה להתחרות בבלוקבאסטר (כן, כן, ניחשתם נכון, נטפילקס) הכריזה על תחרות לחיזוי דירוג סרטים על סמך מידע שהיא אספה מהמשתמשים שלה (משנת 1998 עד 2005). לזוכה בתחרות הובטח פרס מרשים של מיליון דולר, סכום שהיה כנראה מספיק גבוה כדי להניע קבוצות מחקר ופיתוח לפתח אלגוריתם, שיוכל לחזות את דירוגי הסרטים בצורה המיטבית. הקבוצה שזכתה השתמשה בעיקרון ה-Collaborative filtering (CF), שמקבל את העדפות הצפייה של משתמשי השירות, ויודע להמליץ לכל משתמש מהם התכנים הנוספים שאותו צופה עשוי לאהוב.
במאמר הזה נלמד קצת יותר על האלגוריתם הזה, איך הוא עובד ומה אפשר לעשות איתו, ואפילו נראה קצת דוגמאות קוד, שתוכלו להריץ אצלכם ולהשתמש בו לצרכים שלכם. אנחנו בחברה אגב משתמשים באלגוריתם דומה (אם כי קצת מורכב יותר), כדי לתת בדיוק את אותן המלצות צפייה לצופים של הלקוחות שלנו, ולהציג המלצות אישיות וגם המלצות שקשורות לתוכן שהם צפו.
מה חקרנו?
ישנם שני סוגים עיקריים של מנועי המלצות – מבוססי תוכן (Content Based) וסינון שיתופי (Collaborative Filtering), כאשר רוב מנועי ההמלצות המודרניים עושים שימוש בשני הסוגים ביחד. שיטות מבוססות תוכן לוקחות בחשבון דימיון בין מאפייני התכנים, ושיטות המבוססות סינון שיתופי מחשבות דמיון מתוך האינטראקציות של המשתמשים עם התוכן.
בשיטת סינון התוכן עושים שימוש במטריצת האינטראקציות, וישנם שני סוגי אינטראקציות: דירוג מפורש – מטריצה המכילה את דירוגי המשתמש שדרג את התוכן בצורה מודעת; דירוג משתמע – מטריצה המכילה מידע האם המשתמש צרך או לא צרך את התוכן. בדרך כלל מטריצת הדירוג היא דלילה מאוד ובעלת מימדים רבים (כמספר התכנים). בדוגמה הזו אנחנו עשינו שימוש במטריצת דירוג משתמע.
האלגוריתמים
ישנם מספר אלגוריתמים לסינון תוכן. הרעיון הוא למצוא תוכן שמתאים עבור משתמש מסויים, כשהמידע שיש לנו הוא מהם התכנים שבהם אותו משתמש צפה לאחרונה.
דמיון קוסיני הוא האלגוריתם הפשוט ביותר שניתן להשתמש בו. נחפש את n השכנים הדומים ביותר ונמליץ למשתמש תוכן שלא נצפה, בו צפו המשתמשים הדומים
פירוק לגורמים של מטריצה (Matrix Factorization) – אלגוריתמים המבוססים על Matrix Factorization שואפים לצמצם את מימדי מטריצת האינטראקציות על ידי פירוק המטריצה לשתי מטריצות בעלות מימדים קטנים יותר: מטריצת מאפייני המשתמשים ומטריצת מאפייני התכנים. פעולת הצמצום הופכת את הבעיה לפשוטה יותר לפיתרון מבחינת משאבי זיכרון. תוצאת המכפלה של שתי המטריצות קרובה למטריצה המקורית בעלת המימדים הרבים. פעולת הפירוק לגורמים נותנת לנו את היכולת להשוות משתמש לתוכן ולהפיך. על ידי מכפלה סקלרית של וקטור מאפייני משתמש מסויים בווקטור מאפייני מדיה מסויימת אנו יכולים לנחש את מידת ההתאמה של המדיה למשתמש.
יש הסבר אינטואיטיבי ל-Matrix Factorization, ולמה אנו צריכים מטריצות מסדר נמוך על מנת לייצג את המשתמשים והתכנים. נניח שמשתמש מסויים צפה או דירג את הסרטים אווטאר, מטריקס ואקס-מן. אנו רואים שהמשתמש אוהב סרטי מדע בדיוני, וכנראה שקיימים עוד תכנים שהמשתמש עשוי לאהוב. לקטגוריית סרטי המדע הבדיוני יהיה ייצוג חזק באחד מ-k המאפיינים. Matrix Factorization נותן לנו מדד עבור כל משתמש במרחב המאפיינים וכמו כן מדד עבור כל תוכן במרחב המאפיינים.
בחירת k נמצאת בשליטתינו, ככל שנרצה שאלגורתם “ימציא” יותר מאפייני משתמשים ותכנים כך נגדיל את k. כמובן שנשלם בזמן ריצה ארוך יותר ואם נגדיל מדי אז אולי גם בהתאמת יתר – זהו מצב בו המודל שיצרנו לא באמת למד אלא שינן את הנתונים. מצב של התאמת יתר גורם לכך שכאשר נבקש מהמודל לחזות התאמה של תוכן עבור משתמש שאין כדוגמתו בנתונים מהם הוא “למד”, המודל ייכשל.
פרדיקציה של התאמה (Rating) של תוכן j עבור משתמש i היא המכפלה של שורה i במטריצת מאפייני המשתמש, U, עם עמודה j במטריצת מאפייני התכנים, P.

אז איך מוצאים את מטריצות המאפיינים האופטימליות? כמו שעושים במשימות רבות בלמידת מכונה, מגדירים פונקציית הפסד (Loss Function). ב-Matrix Factorization אנו מעוניינים לשערך את מטריצת מאפייני המשתמשים (U) ואת מטריצת מאפייני התכנים (P) על ידי צימצום פונקציית ההפסד הבאה:
הדירוג האמיתי או האם משתמש צפה (או לא צפה) מיוצג על ידי rij. בתהליך האופטימיזציה אנו מחפשים את P האופטימלי שמיוצג על ידי הוקטור pj ואת U האופטימלי שמיוצג על ידי וקטור ui אשר מצמצם את את סכום השגיאה הריבועית בין הדירוג האמיתי rij והדירוג החזוי. חשוב להוסיף למשוואה רגולריזציה כדי להימנע מהתאמת יתר.
אופטימיזציה
ישנם מספר אלגוריתמי אופטימיזציה נפוצים כדי לצמצם את פונקציית ההפסד. אנחנו השתמשנו בשיטה שנקראת Alternating Least Square (ALS). בשיטה זו, אנו מתייחסים למטריצת מאפייני המשתמשים כקבועה ובזמן הזה מצמצמים את הפונקציה כך שמשנים כל פעם קצת את מטריצת מאפייני התכנים. לאחר מכן חוזרים על התהליך כך שהפעם אנו מתייחסים למטריצת מאפייני התכנים כקבועה, ומצמצמים את הפונקציה על ידי שינוי של מריצת מאפייני המשתמשים. על התהליך הזה אנחנו חוזרים שוב ושוב עד לקבלת שגיאה מינימאלית.
דוגמת קוד
בדוגמאות השתמשנו בספריה שנקראת implicit, ספריה שמממשת אלגוריתמי Collaborative filtering בדגש על מידע מסוג דירוג משתמע (בשונה מדירוג מפורש) עם מספר אופציות לאופטימיזציה.
תחילה, הדאטה שלנו נראה כך. בכל שורה יש דגימת זמן, מזהה משתמש ומזהה תוכן
בשלב הראשון נייבא ספריות ונטען את הדאטה
אנקדוטה על הדאטה שלנו: שימו לב שכמות האחדות במטריצה היא פחות מחצי אחוז ויותר מ-99.5% הם אפסים.
בשלב הבא נאמן את המודל. בדוגמא שלנו בחרנו מודל Matrix Factorization עם אופטימייזר ALS ובנוסף, החיפוש לוקטורים קרובים נעשה בעזרת Annoy, ספרייה לאחזור וקטורי. אנחנו הרצנו את האופטימייזר 10 איטרציות עם k=50
לבסוף נדפיס את ההמלצות עבור המשתמש הנבחר
דוגמת המלצה עבור המשתמש הנבחר
התכנים בהם צפה המשתמש
התכנים המומלצים עבור המשתמש הנבחר
מה עוד אנחנו רוצים לחקור?
האלגוריתם שהוצג כאן הוא אלגוריתם יחסית פשוט. הוא לא חף מבעיות, כגון cold start, הוא לא עובד כאשר אין דאטה, לדוגמא משתמש חדש או תוכן חדש. האלגוריתמים האופרטיביים שפיתחנו בחברה הם כמובן מורכבים יותר ועושים שימוש במגוון טכניקות שמתאימות יותר לעולם התוכן שלנו ולאתגרים שמאפיינים את התעשייה שלנו.
אתגר מרכזי שאנחנו צריכים לקחת בחשבון סובבת סביב נושא הפרטיות – בשנים האחרונות אנו עדים לשינויים רגולטוריים מרובים סביב פרטיות, והיום המשתמשים יכולים להחליט האם הם רוצים ששירותי הצפייה יעקבו אחריהם או יאספו מידע אישי במסד נתונים מרכזי או לא. כדי לממש את הפתרון שהצענו פה, כמובן שצריך מודל מרכזי שמכיר את כל המשתמשים, ואם המשתמש בחר שלא לשתף את המידע שלו – לא נוכל לספק המלצות.
מגמה נוספת שאנחנו רואים בעולם ה-ML היא ה-federated machine learning. בקצרה, מדובר על דרך שמאפשרת לעשות את רוב החישובים במכשיר הלקוח, ולעדכן את המודל המרכזי במידע אנונימי לגבי משקולות מכל לקוח. תניחו שפעם ביום כל לקוח מוריד את המודל המרכזי למכשיר שלו ומבצע את החישובים האישיים באופן לוקלי.
אז מה היה לנו?
מה שמדהים באלגוריתם שתואר בכתבה הוא שבעזרת מידע מינימלי (תזכרו שהאלגוריתם לא מכיר את סוג הסרט, שחקנים, דירוג ועוד) אנחנו מצליחים לתת המלצות טובות של תוכן שהמשתמשים שלנו מקבלים. כמו כן בשימוש באלגורתמים מסוג זה אנחנו רואים שהמשתמשים מבזבזים פחות זמן בחיפוש תוכן ועלייה של 70% בבחירת התוכן שמנוע ההמלצות מספק לעומת המלצות אחרות. צפייה נעימה.
איתי כנרות הוא סמנכ”ל מחקר ופיתוח ועופר הלמן הוא מפתח דאטה בכיר בחברת קלטורה




הגב
6 תגובות על "”מכיוון שראית את…”: כך עובד אלגוריתם המלצות הצפייה של נטפליקס"
* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.
אחלה תוכן
מעניין – תודה.
נחמד מאוד.
זה מה שאני מצאתי על זה באתר שלהם
https://help.netflix.com/he/node/100639/il
שטויות, זה שיטות של לפני 10 שנים שמלמדים אותן במבואות ללימודה חישובית כדי לתת קצת מוטיבציה לסטודנטים שחרמנים על משין לרנינג. בפועל, מדובר באלגוריתמים אחרים לגמרי
זה טוב ויפה רק שכל התוכן שמשודר היום הוא זבל טהור מהול בפרופוגנדה