בקבוצת Machine & Deep learning Israel בפייסבוק מישהו שאל את השאלה הבאה:
I have a feature matrix of about 4000 samples and 180,000 features. Naturally, I want to reduce its dimensions for applying a machine learning algorithm on the reduced matrix.
- How do I handle such a big matrix in python for calculations (pandas, other?)
- How can I apply feature selection on such a big matrix and what feature selection methods would you try first?
למעשה יש פה שתי שאלות, הראשונה טכנית במהותה (שימוש בשפת פייתון). אני רוצה להתייחס לשאלה השניה.
ראשית, בואו נבהיר אותה בעברית.
לשואל יש קובץ נתונים, עם 4000 תצפיות. בכל תצפית נתונים ערכים של 180,000 משתנים (features בשפת ה-machine learning). ברור לשואל שיש לו יותר מדי משתנים (חלק מהמשיבים לשאלה ציינו זאת במפורש, ויעצו לשואל לאסוף עוד תצפיות) , והוא שואל איך יוכל לבחור מתוכם קבוצה קטנה יותר של משתנים, כך שמימד הבעיה יקטן. כשכמובן הוא מעוניין לבחור את המשתנים המשמעותיים ביותר לבעיה שלו.
הוא קיבל כמה תשובות, חלקן מעניינות, אם כי לפחות אחת מהן (להפעיל PCA או פרוצדורה דומה) בעייתית בעיניי. אני רוצה להציע כאן היוריסטיקה משלי להתמודדות עם הבעיה.
ראשית, יש לסנן החוצה משתנים עם שונות נמוכה או ללא שונות כלל. לחשב את סטיית התקן של כל משתנה לחוד זה קל יחסית. איזה ערך של סטיית תקן ייחשב לנמוך? כאן יש להפעיל שיקול דעת (judgement). אפשר למשל לחשב את העשירונים או אפילו את המאונים של 180000 סטיות התקן, ולראות איך ההתפלגות מתנהגת. אפשר להחליט לקחת את העשירון העליון של סטיות התקן, או אולי אפילו את המאיון העליון. ייתכן גם ולא יהיה מזל, ותהיה קבוצה קטנה של משתנים עם סטיות תקן נמוכות, ולאחריהן קפיצת מדרגה, ואז לא יהיה ניתן לסנן הרבה משתנים.
מכאן נעבור לשלב השני בסינון. בואו נניח שאחרי הסינון הראשון נותרו 18000 משתנים. אני מניח כעת כי יש גם משתנה מוסבר כלשהו, Y, ושמעוניינים לבנות מודל פרדיקטיבי עבור Y. בשלב נבנה 18000 מודלים פרדיקטיביים עבור Y, כאשר בכל מודל יש רק משתנה מסביר אחד. מכאן נוכל לחשב את הערך הפרדיקטיבי האינדיבידואלי של כל אחד מ-18000 המשתנים שלנו. נפעיל שיקול דעת דומה לזה שהפעלנו בשלב הקודם, ונישאר עם המשתנים בעלי הערך הפרדיקטיבי האינדיבידואלי הגבוה ביותר. בואו נניח, לצורך העניין, שנשארנו עם 9000 משתנים מסבירים.
השלב הבא הוא לבנות מודל שיכיל כמה משתנים מסבירים. בהנחה שהשואל חילק את קובץ הנתונים שלו לשני חלקים (חלק אחד לצורך פיתוח, והאחר לצורך ולידציה), יש לו 2000 תצפיות, ולכן מספר המשתנים המסבירים צריך להיות נמוך מ-2000 באופן משמעותי, כדי שיהיו לו מספיק דרגות חופש לאמידת הפרמטרים של המודל. נניח שהולכים על מודל עם 500 משתנים מסבירים.
בשלב הראשון בונים מודל הכולל את 500 המשתנים בעלי הערך הפרדיקטיבי הגבוה ביותר. מחשבים את הערך הפרדיקטיבי של המודל.
ייתכן כעת, שעקב אינטראקציות בין משתנים, יהיה מצב בו הכנסת משתנה עם ערך פרדיקטיבי יותר נמוך למודל יעלה בכל זאת את הערך הפרדיקטיבי הכולל של המודל. כאן אני מציע להפעיל פרוצדורה רנדומלית:
1) בחר את אחד המשתנים שבתוך המודל באופן מקרי.
2) בחר אחד מהמשתנים שלא נכנסו למודל באופן מקרי.
3) הוצא מהמודל את המשתנה שבחרת בשלב (1) והכנס במקומו למודל את המשתנה שבחרת בשלב (2).
4) חשב את הערך הפרדיקטיבי של המודל החדש.
5) אם הערך הפרדיקטיבי של המודל החדש גבוה יותר מהערך הפרדיקטיבי של המודל הישן, השאר עם המודל החדש. אחרת חזור למודל הישן.
6) חזור לשלב (1).
את הפרוצדורה הזאת יש להריץ מספר גדול של פעמים. כמה פעמים בדיוק? זה שוב עניין של שיקול דעת.
לאחר שהתכנסנו למודל כלשהו עם 500 משתנים, נוכל להפעיל עליו את אחת השיטות המקובלות של variable/feature selection, למשל LASSO regression.
כעת, אם עדיין יש צורך, אפשר לקחת משתנים המתארים משתנים דומים או קרובים זה לזה (נניח הטמפרטורה בשעה 10 בבוקר והטמפרטורה בשעה 12 בצהריים), ולהחליף אותם במשתנה שירכז בתוכו את רובה של השונות במשתנים אלה, על ידי הפעלת PCA למשל.
תהליך ארוך אך אפשרי. חשוב לציין שזוהי היוריסטיקה בלבד, ואין לי הוכחה מתמטית לכך שההיוריסטיקה עובדת ומגיעה למודל סביר. כל מה שאני יכול לומר הוא שהתמודדתי בעזרתה עם בעיה הרבה יותר גדולה. התחלנו עם 1000000 משתנים מסבירים והגענו בסוף למודל עם 13 משתנים, בעל ערך פרדיקטיבי של 70%.
בהצלחה!
למה Pca לא יתן תשובה טובה?
מכיוון ש- PCA מדרג את הרכיבים (לאחר לכסון האוטו-קורלציה) לפי השונות וזורק רכיבים עם שונות נמוכה.
כמה שההיורסטיקה הזו נחמדה ונכונה לעתים, השונות היא לא בהכרח מדד נכון לחשיבות הרכיבים.
לדוגמה, נניח יש לך מדגם של וקטורים באורך 2 (וכ- 10000 דוגמאות או יותר, כמה שבא לך).
המדגם שלך מוגרל מ- x=(x1,x2), y=x1 כש- x1 מתפלג גאוסית עם ווריאנס קטן ו- x2 מתפלג גאוסית עם ווריאנס גדול. בנוסף x1 בלתי תלוי סטטיסטית ב- x2.
במדגם גדול, שמייצג נאמנה את המידע, נקבל מטריצת קווריאנס אלכסונית, ו- PCA ייקח את הקומפוננטה עם הווריאנס הגדול, כלומר x2. כמובן שזה מצב נורא כי לאחר הורדת המימד הדגימות שלך בלתי תלויות סטטיסטית ב- y.
אפשר לדרג את הקומפוננטות אחרת (נניח לפי קורלציה עם y).
ברור?
יוסי,
פוסט מרתק, תודה.
השיטה שאתה מציע הגיונית, ואני מניח שתניב תוצאות טובות.
חשוב להדגיש מה יקרה אם לא יבוצע feature selection לפי שפת ה machine learning או variable selection בשפתנו הסטטיסטיקאים. כניסה למודל עם יחס כזה של משתנים מול תצפיות היא מתכונת קלאסית ל – overfitting. במקרה כזה נקבל אופטימיות יתר.
לא שוברים את הראש.
ספארס מטריקס לתוך xgboost ושהוא יחליט לבד.
היי,
תוכל להרחיב מה זה ספארס מטריס ואיך XGBOOST מתמודד עם בעיית מס’ הפיצ’רים העצום?
לזרוק את הנתונים לתוך xgboost לא שונה במיוחד מלזרוק אותם לתוך PCA. תכניס משהו, ובטוח גם תקבל משהו. מה המשהו הזה שווה? Garbage in, garbage out. תכנה זה לא תחליף למחשבה.
xgboost באמת יכול לחסוך את השלבים לאחר שלב 6, לדוגמא צמצום משתנים עם קורלציה..