SNA האקתון 2019

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

SNA האקתון 2019

האקתון SNA

זו הפעם השלישית שמתקיים האקתון בשם זה. זה מאורגן על ידי הרשת החברתית ok.ru, בהתאמה, המשימה והנתונים קשורים ישירות לרשת חברתית זו.
SNA (ניתוח רשת חברתית) במקרה זה מובן בצורה נכונה יותר לא כניתוח של גרף חברתי, אלא כניתוח של רשת חברתית.

  • בשנת 2014, המשימה הייתה לחזות את מספר הלייקים שפוסט יקבל.
  • בשנת 2016 - משימת VVZ (אולי אתם מכירים), קרובה יותר לניתוח הגרף החברתי.
  • בשנת 2019, דירוג הפיד של המשתמש על סמך הסבירות שהמשתמש יאהב את הפוסט.

אני לא יכול להגיד על 2014, אבל ב-2016 וב-2019, בנוסף ליכולות ניתוח נתונים, נדרשו גם מיומנויות בעבודה עם ביג דאטה. אני חושב שזה היה השילוב של למידת מכונה ובעיות עיבוד ביג דאטה שמשכו אותי לתחרויות האלה, והניסיון שלי בתחומים האלה עזר לי לנצח.

mlbootcamp

בשנת 2019, התחרות אורגנה על הפלטפורמה https://mlbootcamp.ru.

התחרות החלה באינטרנט ב-7 בפברואר וכללה 3 משימות. כל אחד יכול להירשם באתר, להוריד נקודת התחלה ולהעמיס את המכונית שלך לכמה שעות. בסוף השלב המקוון ב-15 במרץ, ה-15 המובילים של כל אירוע קפיצות ראווה הוזמנו למשרד Mail.ru לשלב הלא מקוון, שהתקיים בין ה-30 במרץ ל-1 באפריל.

משימה

נתוני המקור מספקים מזהי משתמש (userId) ומזהי פוסט (objectId). אם הוצג למשתמש פוסט, אז הנתונים מכילים שורה המכילה userId, objectId, תגובות המשתמשים לפוסט זה (משוב) וקבוצה של תכונות שונות או קישורים לתמונות וטקסטים.

תעודת זהות של המשתמש objectId זיהוי בעלים מָשׁוֹב תמונות
3555 22 5677 [אהבתי, לחצתי] [hash1]
12842 55 32144 [לא אהבתי] [hash2,hash3]
13145 35 5677 [לחץ, שיתף] [hash2]

מערך נתוני הבדיקה מכיל מבנה דומה, אך שדה המשוב חסר. המשימה היא לחזות את נוכחות תגובת 'אהבתי' בשדה המשוב.
לקובץ ההגשה יש את המבנה הבא:

תעודת זהות של המשתמש SortedList[objectId]
123 78,13,54,22
128 35,61,55
131 35,68,129,11

המדד הוא ה-ROC AUC הממוצע למשתמשים.

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

שלב מקוון

בשלב המקוון המשימה חולקה ל-3 חלקים

שלב לא מקוון

בשלב הלא מקוון, הנתונים כללו את כל התכונות, בעוד שהטקסטים והתמונות היו דלילים. היו פי 1,5 יותר שורות במערך הנתונים, שכבר היו הרבה מהן.

פתרון הבעיה

מכיוון שאני עושה קורות חיים בעבודה, התחלתי את דרכי בתחרות זו עם משימת "תמונות". הנתונים שסופקו היו userId, objectId, ownerId (הקבוצה בה פורסם הפוסט), חותמות זמן ליצירה והצגה של הפוסט וכמובן התמונה של פוסט זה.
לאחר יצירת מספר תכונות המבוססות על חותמות זמן, הרעיון הבא היה לקחת את השכבה הלפני אחרונה של הנוירון שהוכשר מראש ב-imagenet ולשלוח את ההטמעות הללו לחיזוק.

SNA האקתון 2019

התוצאות לא היו מרשימות. הטבעות מנוירון ה-imagenet אינן רלוונטיות, חשבתי, אני צריך ליצור מקודד אוטומטי משלי.

SNA האקתון 2019

זה לקח הרבה זמן והתוצאה לא השתפרה.

יצירת תכונות

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

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

התכונות הפשוטות ביותר שהעניקו יותר צמיחה מהטבעות תמונה:

  • כמה פעמים הופיעו objectId, userId ו-ownerId בנתונים (צריכים להיות בקורלציה לפופולריות);
  • כמה פוסטים userId ראה מ-ownerId (צריך להתאים לעניין של המשתמש בקבוצה);
  • כמה UserIds ייחודיים צפו בפוסטים מ-ownerId (משקף את גודל הקהל של הקבוצה).

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

  • כמה פעמים userId נכנס בערב;
  • באיזו שעה הפוסט הזה מוצג לרוב (objectId) וכן הלאה.

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

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

SNA האקתון 2019

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

לפיכך, קיבלנו תכונות דומות:

  • כמה פעמים ראה userId פוסט ב- ownerId של הקבוצה;
  • כמה פעמים userId אהב את הפוסט בקבוצה ownerId;
  • אחוז הפוסטים ש-userId אהב מ-ownerId.

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

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

עד אז הייתי במקום הראשון בפער גדול. הדבר היחיד שהיה מבלבל הוא שהטבעות תמונה לא הראו כמעט צמיחה. הרעיון הגיע לתת הכל ל-catboost. אנו מקבצים תמונות של Kmeans ומקבלים תכונה קטגורית חדשה imageCat.

הנה כמה מחלקות לאחר סינון ידני ומיזוג של אשכולות שהתקבלו מ-KMeans.

SNA האקתון 2019

בהתבסס על imageCat אנו יוצרים:

  • תכונות קטגוריות חדשות:
    • איזה imageCat נצפה לרוב על ידי userId;
    • איזה imageCat מציג לרוב ownerId;
    • איזה imageCat אהב לרוב על ידי userId;
  • מונים שונים:
    • כמה imageCat ייחודי הסתכל על userId;
    • כ-15 תכונות דומות בתוספת קידוד יעד כמתואר לעיל.

טקסטים

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

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

מערכת שיתופית

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

צעדים ראשונים של אופטימיזציה של catboost

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

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

אני אתן דוגמה פשוטה:

תעודת זהות של המשתמש objectId נבואה אמת קרקעית
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 1
1 14 0.5 0
2 15 0.4 0
2 16 0.3 1

בואו נעשה סידור קטן מחדש

תעודת זהות של המשתמש objectId נבואה אמת קרקעית
1 10 0.9 1
1 11 0.8 1
1 12 0.7 1
1 13 0.6 0
2 16 0.5 1
2 15 0.4 0
1 14 0.3 1

אנו מקבלים את התוצאות הבאות:

דגם AUC User1 AUC User2 AUC מתכוון ל-AUC
אפשרות 1 0,8 1,0 0,0 0,5
אפשרות 2 0,7 0,75 1,0 0,875

כפי שאתה יכול לראות, שיפור מדד ה-AUC הכולל אינו אומר שיפור מדד ה-AUC הממוצע בתוך משתמש.

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

5 דקות לפני סגירת השלב המקוון של תחרות "מערכות שיתופיות", סרגיי שלנוב העביר אותי למקום השני. הלכנו יחד בשביל הנוסף.

מתכוננים לשלב האופליין

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

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

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

יצירת תכונות

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

  • auditweightsCtrGender
  • auditweightsCtrHigh
  • userOwnerCounterCreateLikes

למשל, הממוצע auditweightsCtrGender לפי userId זה התברר כתכונה חשובה, בדיוק כמו הערך הממוצע userOwnerCounterCreateLikes לפי userId+ownerId. זה כבר אמור לגרום לך לחשוב שאתה צריך להבין את משמעות השדות.

גם תכונות חשובות היו משקללי ביקורת ספור אוהב и AuditweightsShowsCount. מחלקים אחד בשני, התקבלה תכונה חשובה עוד יותר.

דליפות נתונים

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

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

הדליפה הראשונה שמצאנו היא משקולות ביקורת אוהבות ספירת מקסימום / משקלי ביקורת מציגים ספירת מקסימום.
אבל מה אם נסתכל על הנתונים יותר מקרוב? בואו נעשה סדר לפי תאריך המופע ונקבל:

objectId תעודת זהות של המשתמש AuditweightsShowsCount משקללי ביקורת ספור אוהב מטרה (אוהב)
1 1 12 3 כנראה שלא
1 2 15 3 אולי כן
1 3 16 4

זה היה מפתיע כשמצאתי את הדוגמה הראשונה כזו והתברר שהתחזית שלי לא התממשה. אבל, בהתחשב בעובדה שהערכים המקסימליים של מאפיינים אלה בתוך האובייקט נתנו עלייה, לא התעצלנו והחלטנו למצוא משקלי ביקורתShowsCountהבא и משקלי ביקורת לייקיםספירההבאכלומר, הערכים ברגע הבא בזמן. על ידי הוספת תכונה
(auditweightsShowsCountNext-auditweightsShowsCount)/(auditweightsLikesCount-auditweightsLikesCountNext) עשינו קפיצה חדה במהירות.
ניתן להשתמש בדליפות דומות על ידי מציאת הערכים הבאים עבור userOwnerCounterCreateLikes בתוך userId+ownerId ו, למשל, auditweightsCtrGender בתוך objectId+userGender. מצאנו 6 שדות דומים עם דליפות והפקנו מהם מידע רב ככל האפשר.

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

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

החלטה בקרוב
מקסימום עם תמונות 0.6411
מקסימום אין תמונות 0.6297
תוצאת מקום שני 0.6295

החלטה בקרוב
מקסימום עם טקסטים 0.666
מקסימום ללא טקסטים 0.660
תוצאת מקום שני 0.656

החלטה בקרוב
מקסימום בשיתוף פעולה 0.745
תוצאת מקום שני 0.723

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

גידול נוסף של תכונות במערכות שיתופיות לא נתן עלייה, והתחלנו לדרג. בשלב המקוון, הרכב המיון והדירוג העניק לי עלייה קטנה, כפי שהתברר כי אימנתי את המיון. אף אחת מפונקציות השגיאה, כולל YetiRanlPairwise, לא הניבה בשום מקום את התוצאה ש-LogLoss עשתה (0,745 לעומת 0,725). עדיין הייתה תקווה ל-QueryCrossEntropy, שלא ניתן היה להפעיל.

שלב לא מקוון

בשלב הלא מקוון, מבנה הנתונים נשאר זהה, אך היו שינויים קלים:

  • מזהים userId, objectId, ownerId חולקו מחדש באקראי;
  • מספר שלטים הוסרו ושמות אחדים שונה;
  • הנתונים גדלו בערך פי 1,5.

בנוסף לקשיים המפורטים, היה יתרון אחד גדול: לצוות הוקצה שרת גדול עם RTX 2080TI. נהניתי מ-htop כבר הרבה זמן.
SNA האקתון 2019

היה רק ​​רעיון אחד - פשוט לשחזר את מה שכבר קיים. לאחר שבילינו כמה שעות בהגדרת הסביבה בשרת, התחלנו בהדרגה לוודא שהתוצאות ניתנות לשחזור. הבעיה העיקרית איתה אנו מתמודדים היא הגידול בנפח הנתונים. החלטנו להפחית מעט את העומס ולהגדיר את פרמטר ה-catboost ctr_complexity=1. זה מוריד מעט את המהירות, אבל הדגם שלי התחיל לעבוד, התוצאה הייתה טובה - 0,733. סרגיי, בניגוד אלי, לא חילק את הנתונים ל-2 חלקים והתאמן על כל הנתונים, למרות שזה נתן את התוצאות הטובות ביותר בשלב האונליין, בשלב האופליין היו הרבה קשיים. אם ניקח את כל התכונות שיצרנו וננסה לדחוף אותן ל-catboost, אז שום דבר לא יעבוד בשלב המקוון. סרגיי עשה אופטימיזציה של סוגים, למשל, המרת סוגי float64 ל-float32. במאמר זה, אתה יכול למצוא מידע על אופטימיזציה של זיכרון בפנדות. כתוצאה מכך, סרגיי התאמן על המעבד תוך שימוש בכל הנתונים וקיבל בערך 0,735.

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

להילחם עד הסוף

כוונון Catboost

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

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

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

  • שיעור_למידה - ערך ברירת המחדל מחושב על סמך גודל מערך הנתונים. הגדלת קצב הלמידה דורשת הגדלת מספר האיטרציות.
  • l2_leaf_reg — מקדם רגוליזציה, ערך ברירת מחדל 3, רצוי לבחור בין 2 ל-30. הפחתת הערך מובילה לעלייה בכושר יתר.
  • bagging_temperatur - מוסיף אקראי למשקלים של עצמים במדגם. ערך ברירת המחדל הוא 1, כאשר המשקולות נמשכות מהתפלגות אקספוננציאלית. ירידה בערך מובילה לעלייה בכושר יתר.
  • רנדומלי_כוח - משפיע על בחירת הפיצולים באיטרציה ספציפית. ככל שהעוצמה האקראית גבוהה יותר, כך הסיכוי שייבחר פיצול חשיבות נמוך גבוה יותר. בכל איטרציה שלאחר מכן, האקראיות פוחתת. ירידה בערך מובילה לעלייה בכושר יתר.

לפרמטרים אחרים יש השפעה קטנה בהרבה על התוצאה הסופית, אז לא ניסיתי לבחור אותם. איטרציה אחת של אימון במערך הנתונים של ה-GPU שלי עם ctr_complexity=1 ארכה 20 דקות, והפרמטרים שנבחרו במערך הנתונים המופחת היו מעט שונים מאלה האופטימליים במערך הנתונים המלא. בסופו של דבר, עשיתי כ-30 איטרציות על 10% מהנתונים, ואחר כך עוד כ-10 איטרציות על כל הנתונים. יצא משהו כזה:

  • שיעור_למידה עליתי ב-40% מברירת המחדל;
  • l2_leaf_reg השאיר את זה אותו הדבר;
  • bagging_temperatur и רנדומלי_כוח מופחת ל-0,8.

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

הופתעתי מאוד כשראיתי את התוצאה בטבלה:

דגם מודל 1 מודל 2 מודל 3 מִכלוֹל
בלי כוונון 0.7403 0.7404 0.7404 0.7407
עם כוונון 0.7406 0.7405 0.7406 0.7408

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

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

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

ובסופו של דבר, צור אנסמבל מכל האפשרויות.

האנסמבל האחרון

בשעות הערב המאוחרות של היום האחרון, הנחתנו מכלול הדגמים שלנו שהניב 0,742. בן לילה השקתי את הדגם שלי עם ctr_complexity=2 ובמקום 30 דקות הוא התאמן במשך 5 שעות. רק ב-4 לפנות בוקר זה נספר, והכנתי את האנסמבל האחרון, שנתן 0,7433 ב-Leaderboard הציבורי.

בשל גישות שונות לפתרון הבעיה, התחזיות שלנו לא היו מתואמות חזק, מה שהביא לעלייה טובה בהרכב. כדי להשיג אנסמבל טוב, עדיף להשתמש בחיזוי המודל הגולמי predict(prediction_type='RawFormulaVal') ולהגדיר scale_pos_weight=neg_count/pos_count.

SNA האקתון 2019

באתר תוכלו לראות תוצאות סופיות בטבלת ההישגים הפרטית.

פתרונות אחרים

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

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

מסקנה

מה שהכי תקוע בזכרוני:

  • אם יש מאפיינים קטגוריים בנתונים, ואתה יודע לעשות קידוד יעד נכון, עדיין עדיף לנסות catboost.
  • אם אתה משתתף בתחרות, אל תבזבז זמן בבחירת פרמטרים מלבד קצב למידה ואיטרציות. פתרון מהיר יותר הוא ליצור אנסמבל של מספר דגמים.
  • ניתן ללמוד חיזוקים על ה-GPU. Catboost יכול ללמוד מהר מאוד ב-GPU, אבל הוא אוכל הרבה זיכרון.
  • במהלך הפיתוח והבדיקה של רעיונות, עדיף להגדיר rsm קטן~=0.2 (CPU בלבד) ו-ctr_complexity=1.
  • בניגוד לקבוצות אחרות, הרכב הדגמים שלנו נתן עלייה גדולה. רק החלפנו רעיונות וכתבנו בשפות שונות. הייתה לנו גישה שונה לפיצול הנתונים, ולדעתי, לכל אחד היו באגים משלו.
  • לא ברור מדוע אופטימיזציית הדירוג התפקדה גרועה יותר מאופטימיזציית הסיווג.
  • צברתי קצת ניסיון בעבודה עם טקסטים והבנה כיצד נוצרות מערכות ממליצים.

SNA האקתון 2019

תודה למארגנים על הרגשות, הידע והפרסים שהתקבלו.

מקור: www.habr.com

הוספת תגובה