מערכת המלצות (recommendation system)
אתמול ישבתי עם חבר ודיברנו על מערכת המלצות ועל אלגוריתם מעניין שנקרא matrix factorization
אז היום אני הייתי רוצה להסביר על שני סוגי אלגוריתמים שיש במערכות של המלצות, ועל רעיון מעניין שעלה לי ואשמח לשמוע את דעתכם.
סינון מבוסס תוכן:
סינון מבוסס תוכן הוא הפשוט יותר מבין שני הסוגים שאני אדבר עליהם, סינון מבוסס תוכן בוחן את מה שאהבת בעבר וממליץ דברים דומים, אם ניקח לדוגמא היסטורית קניות של נעלי נייק עם פסים, נוכל להמליץ על עוד נעליים דומות.
הדרך שבה האלגוריתמים האלו עובדים היא לרוב ע"י לקיחת כל הפריטים והפיכה שלהם לווקטורים במרחב רב מימדי ככה שפריטים דומים יהיו קרובים, ואז המערכת פשוט מוצאת ווקטור ממוצע של הפריטים שהמשתמש אהב וממליצה על פריטים אחרים שקרובים (מכיוון שמשתמש יכול לקנות גם אופניים וגם נעליים אז לרוב עושים ממוצע על תת-קבוצה של פריטים שהוא אהב)
אז בעצם יש שני שלבים לאלגוריתם:
1. לקחת את כל הפריטים ולעשות להם embedding (להפוך אותם לווקטורים)
2. חיפוש על המרחב הווקטורי בשביל למצוא פריטים דומים.
בשלב של הembedding יש אפשרות לקבוע את הפיצרים ידנית או לתת למודל למצוא אותם לבד, במידה ועושים את זה ידנית זה לרוב ע"י מחיר, קטגוריה, מיקום בעולם, צבעים, תיאור המוצר, שם המוצר, גודל, וכו...
אם נותנים למודל להחליט על הפיצרים לרוב נמצאים קשרים שאנחנו כבני אדם לא היינו מוצאים כמו נעליים לאוזניות כי אנשים שקונים נעליים יוצאים לרוץ עם אוזניות ובעצם הקשר הוא פעילות.
סינון שיתופי:
סינון שיתופי הוא לדעתי קצת יותר מורכב כי הקטע שלו הוא להמליץ לי על דברים שאנשים שדומים לי אהבו.
אם לדוגמא אני קונה הרבה ציוד אלקטרוני ויש עוד אדם שקונה ציוד דומה והוא קנה רכיב שאני לא קניתי, המערכת תמליץ לי על הרכיב כי אולי אנחנו בונים את אותו פרויקט...
השאלה שיכולה לעלות היא האם אפשר פשוט לעשות embedding על המשתמשים במקום על הפריטים ואז למצוא משתמשים קרובים ולהמליץ להם על הקניות של הקרובים אליהם.
בגדול התשובה היא כן אבל העניין שמפריד את זה מסינון מבוסס תוכן הוא שאין אפשרות לעשות embedding כמו שעשינו על הפריטים פשוט כי אנשים דומים (אותו מין מיקום גיל וכו...) לא תמיד דומים בהרגלי צריכה.
אז בעצם אנחנו צריכים דרך לדעת איזה אנשים דומים אחד לשני ואז הembedding פתור ואיתו כל האלגוריתם.
אני מכיר שני דרכים לעשות את הembedding לדמיון בין שני צרכנים:
1. פקטוריזציה של מטריצה
2. הליכה ראנדומאלית על גרף ואז node to vec
פקטוריזציה של מטריצה:
אם ניקח מטריצה ובציר אחד נשים את כל הצרכנים ובציר השני את כל המוצרים נוכל לשים בכל תא 1 או 0 (או כל משקל אחר) לפי כמה אותו צרכן אוהב את המוצר.
עכשיו אנחנו ניקח את המטריצה ונמצא שני ווקטורים שהמכפלה שלהם היא כמה שיותר קרובה למטרציה המקורית.
ובשביל להמליץ לצרכן על מוצר חדש פשוט נחשב את המכפלה של הווקטורים עבור הצרכן ונמצא איזה פריטים הוא כנראה יאהב.
הליכה ראנדומאלית על גרף:
נבנה גרף שמכיל את צרכנים והפריטים וקשרים בניהם עם משקל של כמה הצרכן אוהב את המוצר.
בשביל להפוך את הגרף למרחב ווקטורי נוכל להשתמש בnode to vec שיעשה הליכה ראנדומאלית על הגרף ככה שבכל צומת הוא יקפוץ לnode ראנדומאלי אבל ישתמש בראנדום עם משקולות ככה שחיבור שחזק פי שניים יהיה לו סיכוי כפול לקפוץ דרכו.
האלגוריתם יתחיל מנקודה מסויימת ולפי מספר הפעמים שהוא נופל על נקודות אחרות במהלך ההליכה הוא ידע כמה הן צריכות להיות קרובות במרחב הווקטורי.
אחרי שיש לנו מרחב ווקטורי זה פשוט עניין של חיפוש פריטים קרובים למשתמש.
מקווה שהחכמתם. יויו. 🤩
עכשיו לרעיון:
מה אתם חושבים על בוט שמאזין על ערוצים בטלגרם עושה embedding לפוסטים שלהם ואז אתם יכולים לדפדף בבוט כמו טינדר לפוסטים (אהבתי \ לא אהבתי) וככה הבוט ילמד מה אתם אוהבים וימליץ עם פוסטים שכנראה תאהבו, זה בעצם פיד כמו בפייסבוק או טוויטר אבל בטלגרם ככה תוכלו למצוא ערוצים שאתם לא מכירים ויכולים לעניין אתכם.
אתמול ישבתי עם חבר ודיברנו על מערכת המלצות ועל אלגוריתם מעניין שנקרא matrix factorization
אז היום אני הייתי רוצה להסביר על שני סוגי אלגוריתמים שיש במערכות של המלצות, ועל רעיון מעניין שעלה לי ואשמח לשמוע את דעתכם.
סינון מבוסס תוכן:
סינון מבוסס תוכן הוא הפשוט יותר מבין שני הסוגים שאני אדבר עליהם, סינון מבוסס תוכן בוחן את מה שאהבת בעבר וממליץ דברים דומים, אם ניקח לדוגמא היסטורית קניות של נעלי נייק עם פסים, נוכל להמליץ על עוד נעליים דומות.
הדרך שבה האלגוריתמים האלו עובדים היא לרוב ע"י לקיחת כל הפריטים והפיכה שלהם לווקטורים במרחב רב מימדי ככה שפריטים דומים יהיו קרובים, ואז המערכת פשוט מוצאת ווקטור ממוצע של הפריטים שהמשתמש אהב וממליצה על פריטים אחרים שקרובים (מכיוון שמשתמש יכול לקנות גם אופניים וגם נעליים אז לרוב עושים ממוצע על תת-קבוצה של פריטים שהוא אהב)
אז בעצם יש שני שלבים לאלגוריתם:
1. לקחת את כל הפריטים ולעשות להם embedding (להפוך אותם לווקטורים)
2. חיפוש על המרחב הווקטורי בשביל למצוא פריטים דומים.
בשלב של הembedding יש אפשרות לקבוע את הפיצרים ידנית או לתת למודל למצוא אותם לבד, במידה ועושים את זה ידנית זה לרוב ע"י מחיר, קטגוריה, מיקום בעולם, צבעים, תיאור המוצר, שם המוצר, גודל, וכו...
אם נותנים למודל להחליט על הפיצרים לרוב נמצאים קשרים שאנחנו כבני אדם לא היינו מוצאים כמו נעליים לאוזניות כי אנשים שקונים נעליים יוצאים לרוץ עם אוזניות ובעצם הקשר הוא פעילות.
סינון שיתופי:
סינון שיתופי הוא לדעתי קצת יותר מורכב כי הקטע שלו הוא להמליץ לי על דברים שאנשים שדומים לי אהבו.
אם לדוגמא אני קונה הרבה ציוד אלקטרוני ויש עוד אדם שקונה ציוד דומה והוא קנה רכיב שאני לא קניתי, המערכת תמליץ לי על הרכיב כי אולי אנחנו בונים את אותו פרויקט...
השאלה שיכולה לעלות היא האם אפשר פשוט לעשות embedding על המשתמשים במקום על הפריטים ואז למצוא משתמשים קרובים ולהמליץ להם על הקניות של הקרובים אליהם.
בגדול התשובה היא כן אבל העניין שמפריד את זה מסינון מבוסס תוכן הוא שאין אפשרות לעשות embedding כמו שעשינו על הפריטים פשוט כי אנשים דומים (אותו מין מיקום גיל וכו...) לא תמיד דומים בהרגלי צריכה.
אז בעצם אנחנו צריכים דרך לדעת איזה אנשים דומים אחד לשני ואז הembedding פתור ואיתו כל האלגוריתם.
אני מכיר שני דרכים לעשות את הembedding לדמיון בין שני צרכנים:
1. פקטוריזציה של מטריצה
2. הליכה ראנדומאלית על גרף ואז node to vec
פקטוריזציה של מטריצה:
אם ניקח מטריצה ובציר אחד נשים את כל הצרכנים ובציר השני את כל המוצרים נוכל לשים בכל תא 1 או 0 (או כל משקל אחר) לפי כמה אותו צרכן אוהב את המוצר.
עכשיו אנחנו ניקח את המטריצה ונמצא שני ווקטורים שהמכפלה שלהם היא כמה שיותר קרובה למטרציה המקורית.
ובשביל להמליץ לצרכן על מוצר חדש פשוט נחשב את המכפלה של הווקטורים עבור הצרכן ונמצא איזה פריטים הוא כנראה יאהב.
הליכה ראנדומאלית על גרף:
נבנה גרף שמכיל את צרכנים והפריטים וקשרים בניהם עם משקל של כמה הצרכן אוהב את המוצר.
בשביל להפוך את הגרף למרחב ווקטורי נוכל להשתמש בnode to vec שיעשה הליכה ראנדומאלית על הגרף ככה שבכל צומת הוא יקפוץ לnode ראנדומאלי אבל ישתמש בראנדום עם משקולות ככה שחיבור שחזק פי שניים יהיה לו סיכוי כפול לקפוץ דרכו.
האלגוריתם יתחיל מנקודה מסויימת ולפי מספר הפעמים שהוא נופל על נקודות אחרות במהלך ההליכה הוא ידע כמה הן צריכות להיות קרובות במרחב הווקטורי.
אחרי שיש לנו מרחב ווקטורי זה פשוט עניין של חיפוש פריטים קרובים למשתמש.
מקווה שהחכמתם. יויו. 🤩
עכשיו לרעיון:
מה אתם חושבים על בוט שמאזין על ערוצים בטלגרם עושה embedding לפוסטים שלהם ואז אתם יכולים לדפדף בבוט כמו טינדר לפוסטים (אהבתי \ לא אהבתי) וככה הבוט ילמד מה אתם אוהבים וימליץ עם פוסטים שכנראה תאהבו, זה בעצם פיד כמו בפייסבוק או טוויטר אבל בטלגרם ככה תוכלו למצוא ערוצים שאתם לא מכירים ויכולים לעניין אתכם.