מבוא
לפעמים מבולבל עם רגרסיה לינארית על ידי טירונים - עקב שיתוף המונח נסיגה - - רגרסיה לוגיסטית שונה בהרבה מ רגרסיה לינארית. בעוד רגרסיה ליניארית מנבאת ערכים כמו 2, 2.45, 6.77 או ערכים מתמשכים, מה שהופך אותו ל נסיגה אַלגוֹרִיתְם, - רגרסיה לוגיסטית מנבא ערכים כגון 0 או 1, 1 או 2 או 3, שהם ערכים בדידים, מה שהופך אותו ל מיון אַלגוֹרִיתְם. כן, זה נקרא נסיגה אך הוא א מיון אַלגוֹרִיתְם. עוד על זה עוד רגע.
לכן, אם בעיית מדעי הנתונים שלך כוללת ערכים מתמשכים, אתה יכול ליישם א נסיגה אלגוריתם (רגרסיה ליניארית היא אחד מהם). אחרת, אם זה כרוך בסיווג תשומות, ערכים בדידים או מחלקות, אתה יכול להחיל א מיון אלגוריתם (רגרסיה לוגיסטית היא אחד מהם).
במדריך זה, נבצע רגרסיה לוגיסטית ב-Python עם ספריית Scikit-Learn. נסביר גם מדוע המילה "נְסִיגָה" קיים בשם וכיצד פועלת רגרסיה לוגיסטית.
לשם כך, קודם נטען נתונים שיסווגו, יוצגו ויעובדו מראש. לאחר מכן, נבנה מודל רגרסיה לוגיסטי שיבין את הנתונים הללו. לאחר מכן, מודל זה יוערך, ויופעל כדי לחזות ערכים על סמך קלט חדש.
מוטיבציה
החברה בה אתה עובד עשתה שותפות עם חווה חקלאית טורקית. שותפות זו כוללת מכירת גרעיני דלעת. זרעי דלעת חשובים מאוד לתזונת האדם. הם מכילים חלק ניכר של פחמימות, שומן, חלבון, סידן, אשלגן, זרחן, מגנזיום, ברזל ואבץ.
בצוות מדעי הנתונים, המשימה שלך היא להבחין בהבדל בין סוגי זרעי הדלעת רק על ידי שימוש בנתונים - או סיווג הנתונים לפי סוג הזרע.
החווה הטורקית עובדת עם שני סוגי זרעי דלעת, האחד נקרא Çerçevelik והאחר Ürgüp Sivrisi.
כדי לסווג את זרעי הדלעת, הצוות שלך עקב אחר המאמר של 2021 "השימוש בשיטות למידת מכונה בסיווג זרעי דלעת (Cucurbita pepo L.). משאבים גנטיים ואבולוציית היבול" מקוקלו, סאריגיל ואוזבק - במאמר זה קיימת מתודולוגיה לצילום והפקת מידות הזרעים מהתמונות.
לאחר השלמת התהליך המתואר במאמר, הוצאו המדידות הבאות:
- אזור - מספר הפיקסלים בגבולות של זרע דלעת
- היקפי – ההיקף בפיקסלים של גרעיני דלעת
- אורך ציר ראשי – גם ההיקף בפיקסלים של גרעיני דלעת
- אורך ציר קטן – מרחק הציר הקטן של גרעיני דלעת
- תִמהוֹנִיוּת – האקסצנטריות של זרע דלעת
- אזור קמור - מספר הפיקסלים של הקליפה הקמורה הקטנה ביותר באזור שנוצר על ידי זרעי הדלעת
- היקף - היחס בין שטח זרעי דלעת לפיקסלים של התיבה התוחמת
- קוטר שווה ערך – השורש הריבועי של כפל שטח גרעיני הדלעת בארבע חלקי פי
- קומפקטיות – הפרופורציה של שטח זרעי הדלעת ביחס לשטח העיגול בעל אותו היקף
- מוצקות – המצב הקמור והקמור של גרעיני הדלעת
- סיבוב - הסגלגלות של גרעיני דלעת מבלי להתחשב בעיוותים בקצוות שלה
- יחס היבט – יחס הממדים של גרעיני הדלעת
אלו המידות שאתה צריך לעבוד איתן. מלבד המידות, יש גם את כיתה תווית עבור שני סוגי זרעי הדלעת.
כדי להתחיל לסווג את הזרעים, בואו לייבא את הנתונים ונתחיל להסתכל עליהם.
הבנת מערך הנתונים
הערה: אתה יכול להוריד את מערך הנתונים של דלעת כאן.
לאחר הורדת מערך הנתונים, נוכל לטעון אותו למבנה מסגרת נתונים באמצעות ה pandas
סִפְרִיָה. מכיוון שמדובר בקובץ אקסל, נשתמש ב- read_excel()
שיטה:
import pandas as pd
fpath = 'dataset/pumpkin_seeds_dataset.xlsx'
df = pd.read_excel(fpath)
לאחר טעינת הנתונים, נוכל להציץ במהירות ב-5 השורות הראשונות באמצעות ה- head()
שיטה:
df.head()
זו התוצאה:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness Class
0 56276 888.242 326.1485 220.2388 56831 267.6805 0.7376 0.9902 0.7453 0.8963 1.4809 0.8207 Çerçevelik
1 76631 1068.146 417.1932 234.2289 77280 312.3614 0.8275 0.9916 0.7151 0.8440 1.7811 0.7487 Çerçevelik
2 71623 1082.987 435.8328 211.0457 72663 301.9822 0.8749 0.9857 0.7400 0.7674 2.0651 0.6929 Çerçevelik
3 66458 992.051 381.5638 222.5322 67118 290.8899 0.8123 0.9902 0.7396 0.8486 1.7146 0.7624 Çerçevelik
4 66107 998.146 383.8883 220.4545 67117 290.1207 0.8187 0.9850 0.6752 0.8338 1.7413 0.7557 Çerçevelik
הנה, יש לנו את כל המידות בעמודות שלהם, שלנו מאפיינים, וגם כיתה טור, שלנו יעד, שהוא האחרון ב-dataframe. אנו יכולים לראות כמה מדידות יש לנו באמצעות ה shape
תְכוּנָה:
df.shape
הפלט הוא:
(2500, 13)
תוצאת הצורה אומרת לנו שיש 2500 ערכים (או שורות) במערך הנתונים ו-13 עמודות. מכיוון שאנו יודעים שיש עמודת יעד אחת - זה אומר שיש לנו 12 עמודות תכונה.
כעת נוכל לחקור את משתנה היעד, זרעי הדלעת Class
. מכיוון שנחזה את המשתנה הזה, מעניין לראות כמה דגימות יש לנו מכל גרעיני דלעת. בדרך כלל, ככל שההפרש בין מספר המקרים בשיעורים שלנו קטן יותר, כך המדגם שלנו מאוזן יותר ותחזיותינו טובות יותר.
בדיקה זו יכולה להיעשות על ידי ספירת כל דגימת זרע עם value_counts()
שיטה:
df['Class'].value_counts()
הקוד לעיל מציג:
Çerçevelik 1300
Ürgüp Sivrisi 1200
Name: Class, dtype: int64
אנו יכולים לראות שיש 1300 דוגמאות של Çerçevelik זרעים ו-1200 דגימות של Ürgüp Sivrisi זֶרַע. שימו לב שההבדל ביניהם הוא 100 דגימות, הבדל קטן מאוד, מה שטוב לנו ומעיד שאין צורך לאזן מחדש את מספר הדגימות.
בואו נסתכל גם על הסטטיסטיקה התיאורית של התכונות שלנו עם ה describe()
שיטה לראות עד כמה הנתונים מפוזרים היטב. אנו גם נעביר את הטבלה המתקבלת עם T
כדי להקל על ההשוואה בין הנתונים הסטטיסטיים:
df.describe().T
הטבלה המתקבלת היא:
count mean std min 25% 50% 75% max
Area 2500.0 80658.220800 13664.510228 47939.0000 70765.000000 79076.00000 89757.500000 136574.0000
Perimeter 2500.0 1130.279015 109.256418 868.4850 1048.829750 1123.67200 1203.340500 1559.4500
Major_Axis_Length 2500.0 456.601840 56.235704 320.8446 414.957850 449.49660 492.737650 661.9113
Minor_Axis_Length 2500.0 225.794921 23.297245 152.1718 211.245925 224.70310 240.672875 305.8180
Convex_Area 2500.0 81508.084400 13764.092788 48366.0000 71512.000000 79872.00000 90797.750000 138384.0000
Equiv_Diameter 2500.0 319.334230 26.891920 247.0584 300.167975 317.30535 338.057375 417.0029
Eccentricity 2500.0 0.860879 0.045167 0.4921 0.831700 0.86370 0.897025 0.9481
Solidity 2500.0 0.989492 0.003494 0.9186 0.988300 0.99030 0.991500 0.9944
Extent 2500.0 0.693205 0.060914 0.4680 0.658900 0.71305 0.740225 0.8296
Roundness 2500.0 0.791533 0.055924 0.5546 0.751900 0.79775 0.834325 0.9396
Aspect_Ration 2500.0 2.041702 0.315997 1.1487 1.801050 1.98420 2.262075 3.1444
Compactness 2500.0 0.704121 0.053067 0.5608 0.663475 0.70770 0.743500 0.9049
על ידי התבוננות בטבלה, כאשר משווים את אומר ו סטיית תקן (std
) עמודות, ניתן לראות שלרוב התכונות יש ממוצע שרחוק מסטיית התקן. זה מצביע על כך שערכי הנתונים אינם מרוכזים סביב הערך הממוצע, אלא מפוזרים יותר סביבו - במילים אחרות, יש להם שונות גבוהה.
כמו כן, כאשר מסתכלים על מינימום (min
) ו מקסימום (max
) עמודות, תכונות מסוימות, כגון Area
, ו Convex_Area
, יש הבדלים גדולים בין ערכי מינימום למקסימום. זה אומר שלעמודות האלה יש נתונים קטנים מאוד וגם ערכי נתונים גדולים מאוד, או משרעת גבוהה יותר בין ערכי נתונים.
עם שונות גבוהה, משרעת גבוהה ותכונות עם יחידות מדידה שונות, רוב הנתונים שלנו יפיקו תועלת מקנה מידה זהה עבור כל התכונות או ההוויה סולם. קנה המידה של הנתונים ירכז נתונים סביב הממוצע ויפחית את השונות שלו.
תרחיש זה מעיד כנראה גם על קיימות חריגים וערכים קיצוניים בנתונים. אז עדיף כמה טיפול חריג מלבד קנה המידה של הנתונים.
ישנם כמה אלגוריתמים של למידת מכונה, למשל, אלגוריתמים מבוססי עצים כגון סיווג יער אקראי, שאינם מושפעים משונות נתונים גבוהים, חריגים וערכים קיצוניים. רגרסיה לוגיסטית שונה, היא מבוססת על פונקציה שמסווגת את הערכים שלנו, והפרמטרים של פונקציה זו יכולים להיות מושפעים מערכים שהם מחוץ למגמת הנתונים הכללית ובעלי שונות גבוהה.
עוד מעט נבין יותר על רגרסיה לוגיסטית כשנגיע ליישם אותה. לעת עתה, אנו יכולים להמשיך ולחקור את הנתונים שלנו.
הערה: יש פתגם פופולרי במדעי המחשב: "זבל פנימה, זבל החוצה" (GIGO), שמתאים היטב ללמידת מכונה. המשמעות היא שכאשר יש לנו נתוני זבל - מדידות שאינן מתארות את התופעות בפני עצמן, נתונים שלא הובנו והוכנו היטב לפי סוג האלגוריתם או המודל, סביר להניח שיניבו פלט שגוי שלא יעבוד עליו על בסיס יומיומי.
זו אחת הסיבות לכך שחקר, הבנת נתונים וכיצד פועל המודל הנבחר כל כך חשובים. על ידי כך, נוכל להימנע מהכנסת זבל במודל שלנו - לשים בו ערך במקום, ולהוציא ערך.
הדמיה של הנתונים
עד עכשיו, עם הסטטיסטיקה התיאורית, יש לנו תמונת מצב מעט מופשטת של כמה איכויות של הנתונים. צעד חשוב נוסף הוא לדמיין אותו ולאשר את ההשערה שלנו לגבי שונות, משרעת וחריגים גבוהים. כדי לראות אם מה שצפינו עד כה מופיע בנתונים, נוכל לשרטט כמה גרפים.
מעניין גם לראות כיצד התכונות קשורות לשני המחלקות שיחזו. כדי לעשות זאת, בואו לייבא את seaborn
לארוז ולהשתמש ב pairplot
גרף כדי להסתכל על כל התפלגות תכונה, וכל הפרדת מחלקה לכל תכונה:
import seaborn as sns
sns.pairplot(data=df, hue='Class')
הערה: הקוד שלמעלה עשוי להימשך זמן מה לרוץ, מכיוון שה-pairplot משלב תרשימי פיזור של כל התכונות (הוא יכול), וגם מציג את הפצות התכונות.
בהסתכלות על העלילה הזוגית, אנו יכולים לראות שברוב המקרים הנקודות של ה- Çerçevelik
הכיתה מופרדות בבירור מנקודות ה- Ürgüp Sivrisi
מעמד. או שהנקודות של מחלקה אחת הן ימינה כאשר האחרות משמאל, או שחלקן למעלה בעוד האחרות למטה. אם היינו משתמשים בסוג כלשהו של עקומה או קו כדי להפריד בין מחלקות, זה מראה שקל יותר להפריד ביניהן, אם הן היו מעורבות, הסיווג יהיה משימה קשה יותר.
ב Eccentricity
, Compactness
ו Aspect_Ration
עמודות, כמה נקודות "מבודדות" או חורגות ממגמת הנתונים הכללית - חריגים - גם מזוהות בקלות.
כאשר מסתכלים על האלכסון מהצד השמאלי העליון לחלק הימני התחתון של התרשים, שימו לב שגם התפלגויות הנתונים מקודדות בצבע בהתאם לשיעורים שלנו. צורות ההתפלגות והמרחק בין שתי העקומות הם אינדיקטורים נוספים למידת ההפרדה שלהם - ככל שהן רחוקות יותר זו מזו, כך ייטב. ברוב המקרים, הם אינם מונחים על גבי, מה שמרמז על כך שקל יותר להפריד אותם, וזה גם תורם למשימה שלנו.
ברצף, נוכל גם לשרטט את התרשים של כל המשתנים עם ה- sns.boxplot()
שיטה. ברוב הפעמים, זה מועיל לכוון את עלילות הקופסאות בצורה אופקית, כך שהצורות של עלילות הקופסאות זהות לצורות ההפצה, אנחנו יכולים לעשות את זה עם orient
טענה:
sns.boxplot(data=df, orient='h')
בעלילה למעלה, שימו לב לזה Area
ו Convex_Area
יש להם גודל כל כך גבוה בהשוואה לגדלים של העמודות האחרות, עד שהם מעוכים את עלילות הקופסה האחרות. כדי שנוכל להסתכל על כל עלילות הקופסה, נוכל לשנות את קנה המידה של התכונות ולתכנן אותן שוב.
לפני שנעשה את זה, בואו נבין שאם יש ערכים של תכונות הקשורות באופן אינטימי לערכים אחרים, למשל - אם יש ערכים שגדלים גם כאשר ערכי תכונה אחרים גדלים, מתאם חיובי; או אם יש ערכים שעושים את ההיפך, הולכים וקטנים בעוד שערכים אחרים הולכים וקטנים, עם א מתאם שלילי.
חשוב להסתכל על זה מכיוון שיש קשרים חזקים בנתונים עשויים לגרום לכך שעמודות מסוימות נגזרו מעמודות אחרות או בעלות משמעות דומה למודל שלנו. כאשר זה קורה, תוצאות המודל עשויות להיות מוערכות יתר על המידה ואנו רוצים תוצאות קרובות יותר למציאות. אם יש מתאמים חזקים, זה גם אומר שאנחנו יכולים להפחית את מספר התכונות, ולהשתמש בפחות עמודות מה שהופך את המודל ליותר קַמצָנִי.
הערה: מתאם ברירת המחדל מחושב עם corr()
השיטה היא מקדם מתאם פירסון. מקדם זה מצוין כאשר הנתונים הם כמותיים, מחולקים בצורה נורמלית, אין להם חריגים ויש להם קשר ליניארי.
אפשרות אחרת תהיה לחשב מקדם המתאם של ספירמן. מקדם ספירמן משמש כאשר הנתונים הם אורדינליים, לא לינאריים, בעלי התפלגות כלשהי ויש להם חריגים. שימו לב שהנתונים שלנו לא לגמרי מתאימים להנחותיהם של פירסון או ספירמן (יש גם שיטות מתאם נוספות, כמו זו של קנדל). מכיוון שהנתונים שלנו הם כמותיים וחשוב לנו למדוד את הקשר הליניארי שלהם, נשתמש במקדם של פירסון.
בואו נסתכל על המתאמים בין משתנים ואז נוכל לעבור לעיבוד מקדים של הנתונים. נחשב את המתאמים עם ה corr()
השיטה ודמיינו אותם עם Seaborn's heatmap()
. הגודל הסטנדרטי של מפת החום נוטה להיות קטן, אז אנחנו נייבא matplotlib
(מנוע ויזואליזציה כללי/ספרייה ש-Seaborn בנוי עליו) ולשנות את הגודל איתו figsize
:
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))
correlations = df.corr()
sns.heatmap(correlations, annot=True)
במפת חום זו, הערכים הקרובים יותר ל-1 או -1 הם הערכים שאנו צריכים לשים לב אליהם. המקרה הראשון, מציין מתאם חיובי גבוה והשני, מתאם שלילי גבוה. שני הערכים, אם לא מעל 0.8 או -0.8 יהיו מועילים למודל הרגרסיה הלוגיסטית שלנו.
כאשר יש מתאמים גבוהים כמו זה של 0.99
בֵּין Aspec_Ration
ו Compactness
, זה אומר שאנחנו יכולים לבחור להשתמש בלבד Aspec_Ration
או רק Compactness
, במקום שניהם (מכיוון שהם היו כמעט שווים מנבאים אחד של השני). כך גם לגבי Eccentricity
ו Compactness
עם -0.98
מתאם, עבור Area
ו Perimeter
עם 0.94
מתאם, ועוד כמה עמודות.
עיבוד מוקדם של הנתונים
מכיוון שכבר חקרנו את הנתונים במשך זמן מה, נוכל להתחיל לעבד אותם מראש. לעת עתה, בואו נשתמש בכל התכונות עבור חיזוי הכיתה. לאחר השגת מודל ראשון, קו בסיס, נוכל להסיר כמה מהעמודות בקורלציה גבוהה ולהשוות אותה לקו הבסיס.
עמודות התכונה יהיו שלנו X
נתונים ועמודת הכיתה, שלנו y
נתוני יעד:
y = df['Class']
X = df.drop(columns=['Class'], axis=1)
הפיכת תכונות קטגוריות לתכונות מספריות
לגבי שלנו Class
עמודה - הערכים שלה אינם מספרים, זה אומר שאנחנו צריכים גם לשנות אותם. ישנן דרכים רבות לעשות את השינוי הזה; כאן, נשתמש ב- replace()
שיטה והחלפה Çerçevelik
ל 0
ו Ürgüp Sivrisi
ל 1
.
y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)
זכור את המיפוי! בעת קריאת תוצאות מהמודל שלך, תרצה להמיר אותן בחזרה לפחות בראש שלך, או בחזרה לשם הכיתה עבור משתמשים אחרים.
חלוקת נתונים למערכות רכבת ובדיקות
בחקירה שלנו, ציינו שהתכונות זקוקות לשינוי קנה מידה. אם עשינו את קנה המידה עכשיו, או באופן אוטומטי, היינו מדרגים את הערכים עם כל X
ו y
. במקרה כזה, היינו מציגים דליפת מידע, מכיוון שהערכים של ערכת הבדיקה שעתידה להיות בקרוב היו משפיעים על קנה המידה. דליפת נתונים היא סיבה שכיחה לתוצאות בלתי ניתנות לשחזור וביצועים גבוהים הזויים של דגמי ML.
מחשבה על קנה המידה מראה שאנחנו צריכים קודם כל להתפצל X
ו y
מידע נוסף לתוך הרכבות ומערכות הבדיקה ולאחר מכן אל מתאים scaler על ערכת האימונים, וכן ל לשנות גם הרכבת וגם מערכי הבדיקה (מבלי שמערכת הבדיקה תשפיע על הסקלר שעושה זאת). לשם כך, נשתמש ב-Skikit-Learn's train_test_split()
שיטה:
from sklearn.model_selection import train_test_split
SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=.25,
random_state=SEED)
הגדרת test_size=.25
הוא מבטיח שאנו משתמשים ב-25% מהנתונים לבדיקות ו-75% לאימון. ניתן להשמיט זאת, ברגע שזה פיצול ברירת המחדל, אבל ה פיתונית הדרך לכתיבת קוד מייעצת שלהיות "מפורש עדיף על מרומז".
הערה: המשפט "עדיף מפורש מאשר מרומז" הוא התייחסות אליו הזן של פיתון, או PEP20. הוא מציג כמה הצעות לכתיבת קוד Python. אם עוקבים אחר ההצעות הללו, הקוד ייחשב פיתונית. אתה יכול לדעת יותר על זה כאן.
לאחר פיצול הנתונים לקבוצות רכבת ובדיקות, מומלץ לבדוק כמה רשומות יש בכל סט. זה יכול להיעשות עם shape
תְכוּנָה:
X_train.shape, X_test.shape, y_train.shape, y_test.shape
זה מציג:
((1875, 12), (625, 12), (1875,), (625,))
אנו יכולים לראות שאחרי הפיצול, יש לנו 1875 רשומות לאימונים ו-625 לבדיקות.
קנה מידה של נתונים
ברגע שנכין את הרכבת וערכות הבדיקה שלנו, נוכל להמשיך להרחיב את הנתונים עם Scikit-Learn StandardScaler
אובייקט (או סקולרים אחרים שסופקו על ידי הספרייה). כדי למנוע דליפה, ה-scaler מותקן על X_train
הנתונים וערכי הרכבת משמשים לאחר מכן לשינוי קנה מידה - או שינוי - הן של הרכבת והן של נתוני הבדיקה:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
מכיוון שבדרך כלל אתה מתקשר:
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
ניתן לכווץ את שתי השורות הראשונות ביחיד fit_transform()
call, שמתאים ל-scaler על הסט, והופך אותו במכה אחת. כעת נוכל לשחזר את גרפי התרשים כדי לראות את ההבדל לאחר שינוי קנה המידה של הנתונים.
בהתחשב בשינוי קנה המידה מסיר שמות עמודות, לפני התכנון, אנו יכולים לארגן נתוני רכבת לתוך מסגרת נתונים עם שמות עמודות שוב כדי להקל על ההדמיה:
column_names = df.columns[:12]
X_train = pd.DataFrame(X_train, columns=column_names)
sns.boxplot(data=X_train, orient='h')
סוף סוף נוכל לראות את כל ה-boxplots שלנו! שימו לב שלכולם יש חריגים, ולתכונות שמציגות התפלגות רחוקה מהרגיל (שיש להם עקומות מוטות לשמאל או לימין), כמו למשל Solidity
, Extent
, Aspect_Ration
, ו Compactedness
, הם זהים שהיו להם מתאמים גבוהים יותר.
הסרת חריגים בשיטת IQR
אנחנו כבר יודעים שרגרסיה לוגיסטית יכולה להיות מושפעת מחריגים. אחת הדרכים לטפל בהן היא להשתמש בשיטה הנקראת טווח בין רבעוני or מנת משכל. השלב הראשוני של שיטת IQR הוא לחלק את נתוני הרכבת שלנו לארבעה חלקים, הנקראים רבעונים. הרבעון הראשון, Q1, מסתכם ב-25% מהנתונים, השני, Q2, עד 50%, השלישי, Q3, ל-75%, והאחרון, Q4, עד 100%. התיבות ב-boxplot מוגדרות בשיטת IQR ומהוות ייצוג ויזואלי שלה.
בהתחשב בתרשים אופקי, הקו האנכי משמאל מסמן 25% מהנתונים, הקו האנכי באמצע, 50% מהנתונים (או החציון), והקו האנכי האחרון מימין, 75% מהנתונים . ככל ששני הריבועים המוגדרים על ידי הקווים האנכיים אחידים יותר - או שהקו האנכי החציוני יותר באמצע - פירושו שהנתונים שלנו קרובים יותר להתפלגות הנורמלית או פחות מוטים, מה שמועיל לניתוח שלנו.
מלבד תיבת IQR, ישנם גם קווים אופקיים משני הצדדים שלה. שורות אלה מסמנות את ערכי ההפצה המינימליים והמקסימליים שהוגדרו על ידי
$$
מינימום = Q1 – 1.5*IQR
$$
ו
$$
מקסימום = Q3 + 1.5*IQR
$$
IQR הוא בדיוק ההבדל בין Q3 ל- Q1 (או Q3 - Q1) והיא הנקודה המרכזית ביותר של הנתונים. לכן כשמוצאים את ה-IQR, אנחנו בסופו של דבר מסננים את החריגים בקצוות הנתונים, או בנקודות המינימום והמקסימום. עלילות קופסאות נותנות לנו הצצה קטנה למה תהיה התוצאה של שיטת IQR.
אנחנו יכולים להשתמש בפנדות quantile()
שיטה למצוא את הקוונטילים שלנו, ו iqr
מ scipy.stats
חבילה לקבלת טווח הנתונים הבין-רבעוני עבור כל עמודה:
from scipy.stats import iqr
Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)
IQR = X_train.apply(iqr)
עכשיו יש לנו Q1, Q3 ו-IQR, אנחנו יכולים לסנן את הערכים הקרובים יותר לחציון:
minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)
filter = ~(minimum | maximum).any(axis=1)
X_train = X_train[filter]
לאחר סינון שורות האימונים שלנו, נוכל לראות כמה מהן עדיין נמצאות בנתונים shape
:
X_train.shape
זו התוצאה:
(1714, 12)
אנו יכולים לראות שמספר השורות ירד מ-1875 ל-1714 לאחר סינון. המשמעות היא ש-161 שורות הכילו חריגים או 8.5% מהנתונים.
הערה: מומלץ שסינון חריגים, הסרת ערכי NaN ופעולות אחרות הכוללות סינון וניקוי נתונים יישארו מתחת ל-10% מהנתונים או עד עד 10%. נסה לחשוב על פתרונות אחרים אם הסינון או ההסרה שלך עולים על XNUMX% מהנתונים שלך.
לאחר הסרת חריגים, אנחנו כמעט מוכנים לכלול נתונים במודל. עבור התאמת הדגם, נשתמש בנתוני רכבת. X_train
מסונן, אבל מה לגבי y_train
?
y_train.shape
תפוקות אלה:
(1875,)
שים לב ש y_train
עדיין יש 1875 שורות. אנחנו צריכים להתאים את המספר של y_train
שורות למספר של X_train
שורות ולא רק באופן שרירותי. עלינו להסיר את ערכי ה-y של המקרים של גרעיני דלעת שהסרנו, אשר כנראה מפוזרים דרך y_train
מַעֲרֶכֶת. המסונן X_train
עדיין יש את המדדים המקוריים שלו ולמדד יש פערים שבהם הסרנו חריגים! לאחר מכן נוכל להשתמש באינדקס של ה X_train
DataFrame כדי לחפש את הערכים המתאימים y_train
:
y_train = y_train.iloc[X_train.index]
לאחר שנעשה זאת, נוכל להסתכל על y_train
צורה שוב:
y_train.shape
אילו תפוקות:
(1714,)
עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!
עכשיו, y_train
יש גם 1714 שורות והן זהות ל- X_train
שורות. סוף סוף אנחנו מוכנים ליצור את מודל הרגרסיה הלוגיסטית שלנו!
יישום מודל הרגרסיה הלוגיסטית
החלק הקשה הסתיים! עיבוד מקדים הוא בדרך כלל קשה יותר מפיתוח מודלים, כשמדובר בשימוש בספריות כמו Scikit-Learn, אשר ייעלו את היישום של מודלים של ML לכמה שורות בלבד.
ראשית, אנו מייבאים את LogisticRegression
מחלקה ולייצר אותו, יצירת א LogisticRegression
אובייקט:
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)
שנית, אנו מתאימים את נתוני הרכבת שלנו ל- logreg
דגם עם ה fit()
שיטה, ולחזות את נתוני הבדיקה שלנו עם ה predict()
שיטה, אחסון התוצאות כ y_pred
:
logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)
כבר עשינו תחזיות עם המודל שלנו! בואו נסתכל על 3 השורות הראשונות בפנים X_train
כדי לראות באילו נתונים השתמשנו:
X_train[:3]
הקוד שלמעלה מוציא:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness
0 -1.098308 -0.936518 -0.607941 -1.132551 -1.082768 -1.122359 0.458911 -1.078259 0.562847 -0.176041 0.236617 -0.360134
1 -0.501526 -0.468936 -0.387303 -0.376176 -0.507652 -0.475015 0.125764 0.258195 0.211703 0.094213 -0.122270 0.019480
2 0.012372 -0.209168 -0.354107 0.465095 0.003871 0.054384 -0.453911 0.432515 0.794735 0.647084 -0.617427 0.571137
וב-3 התחזיות הראשונות ב y_pred
כדי לראות את התוצאות:
y_pred[:3]
זו התוצאה:
array([0, 0, 0])
עבור שלוש השורות הללו, התחזיות שלנו היו שהם זרעים מהמחלקה הראשונה, Çerçevelik
.
עם - רגרסיה לוגיסטית, במקום לחזות את המעמד הסופי, כגון 0
, נוכל גם לחזות את ההסתברות שיש לשורה להתייחס ל- 0
מעמד. זה מה שקורה בפועל כאשר רגרסיה לוגיסטית מסווגת נתונים, ואת predict()
לאחר מכן, השיטה מעבירה חיזוי זה דרך סף כדי להחזיר מחלקה "קשה". כדי לחזות את ההסתברות להתייחס לכיתה, predict_proba()
משמש:
y_pred_proba = logreg.predict_proba(X_test)
בואו נסתכל גם על 3 הערכים הראשונים של תחזיות ההסתברויות y:
y_pred_proba[:3]
אילו תפוקות:
# class 0 class 1
array([[0.54726628, 0.45273372],
[0.56324527, 0.43675473],
[0.86233349, 0.13766651]])
כעת, במקום שלושה אפסים, יש לנו עמודה אחת לכל מחלקה. בעמודה משמאל, החל מ- 0.54726628
, הן ההסתברויות של הנתונים הנוגעים למחלקה 0
; ובעמודה הימנית, החל מ 0.45273372
, האם ההסתברות שזה קשור למחלקה 1
.
הערה: הבדל זה בסיווג ידוע גם בשם קָשֶׁה ו רך נְבוּאָה. חיזוי קשיח תופס את החיזוי למחלקה, בעוד שחיזויים רכים מוציאים את הסתברות של המקרה השייך לכיתה.
יש מידע נוסף על אופן יצירת הפלט החזוי. זה לא היה בעצם 0
, אבל סיכוי של 55% לכיתה 0
, וסיכוי של 45% לשיעור 1
. זה משטח איך שלושת הראשונים X_test
נקודות נתונים, הנוגעות לכיתה 0
, באמת ברורים רק לגבי נקודת הנתונים השלישית, עם הסתברות של 86% - ולא כל כך לגבי שתי נקודות הנתונים הראשונות.
כאשר מתקשרים ממצאים באמצעות שיטות ML - בדרך כלל עדיף להחזיר מחלקה רכה, ואת ההסתברות הקשורה כ- "אֵמוּן" של הסיווג הזה.
נדבר יותר על איך זה מחושב כשנעמיק במודל. בשלב זה, נוכל להמשיך לשלב הבא.
הערכת המודל עם דוחות סיווג
השלב השלישי הוא לראות כיצד המודל מתפקד על נתוני בדיקה. אנחנו יכולים לייבא את Scikit-Learn classification_report()
ולהעביר את שלנו y_test
ו y_pred
כטיעונים. לאחר מכן, נוכל להדפיס את תגובתו.
דוח הסיווג מכיל את מדדי הסיווג הנפוצים ביותר, כגון דיוק, זוכר, ציון f1, ו דיוק.
- דיוק: להבין אילו ערכי חיזוי נכונים נחשבו נכונים על ידי המסווג שלנו. הדיוק יחלק את הערכים החיוביים האמיתיים האלה בכל מה שנחזה כחיובי:
$$
דיוק = frac{text{true positive}}{text{true positive} + text{false positive}}
$$
- להיזכר: כדי להבין כמה מהנקודות החיוביות האמיתיות זוהו על ידי המסווג שלנו. ההחזרה מחושבת על ידי חלוקת התוצאות החיוביות האמיתיות בכל מה שהיה צריך לחזות כחיובי:
$$
recall = frac{text{true positive}}{text{true positive} + text{false negative}}
$$
- ציון F1: האם המאוזן או ממוצע הרמוני של דיוק וזכירה. הערך הנמוך ביותר הוא 0 והגבוה ביותר הוא 1. מתי
f1-score
שווה ל-1, זה אומר שכל המחלקות חזו נכון - זה ציון קשה מאוד להשגה עם נתונים אמיתיים:
$$
text{f1-score} = 2* frac{text{precision} * text{recall}}{text{precision} + text{recall}}
$$
- דיוק: מתאר כמה תחזיות המסווג שלנו צדק. ערך הדיוק הנמוך ביותר הוא 0 והגבוה ביותר הוא 1. ערך זה מוכפל בדרך כלל ב-100 כדי לקבל אחוז:
$$
דיוק = frac{טקסט{מספר תחזיות נכונות}}{טקסט{מספר כולל של התחזיות}}
$$
הערה: קשה מאוד להשיג דיוק של 100% על נתונים אמיתיים כלשהם, אם זה קורה, היו מודעים לכך שאולי מתרחשת דליפה כלשהי או משהו שגוי - אין הסכמה לגבי ערך דיוק אידיאלי והוא גם תלוי הקשר. ערך של 70%, כלומר המסווג יעשה טעויות ב-30% מהנתונים, או מעל 70% נוטה להספיק לרוב הדגמים.
from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)
לאחר מכן נוכל להסתכל על פלט דוח הסיווג:
precision recall f1-score support
0 0.83 0.91 0.87 316
1 0.90 0.81 0.85 309
accuracy 0.86 625
macro avg 0.86 0.86 0.86 625
weighted avg 0.86 0.86 0.86 625
זו התוצאה שלנו. שים לב ש precision
, recall
, f1-score
, ו accuracy
המדדים כולם גבוהים מאוד, מעל 80%, וזה אידיאלי - אבל התוצאות האלה כנראה הושפעו מתאמים גבוהים, ולא יישמרו בטווח הארוך.
הדיוק של הדגם הוא 86%, כלומר הוא טועה בסיווג 14% מהמקרים. יש לנו את המידע הכולל הזה, אבל זה יהיה מעניין לדעת אם 14% הטעויות קורות לגבי סיווג הכיתה 0
או כיתה 1
. כדי לזהות אילו מחלקות מזוהות בטעות כאיזה, ובאיזה תדירות - נוכל לחשב ולתכנן את א מטריצת בלבול מהתחזיות של המודל שלנו.
הערכת המודל באמצעות מטריצת בלבול
בוא נחשב ואז נתווה את מטריצת הבלבול. לאחר שנעשה זאת, נוכל להבין כל חלק ממנו. כדי לשרטט את מטריצת הבלבול, נשתמש ב-Skikit-Learn confusion_matrix()
, שנייבא מה- metrics
מודול.
קל יותר לדמיין את מטריצת הבלבול באמצעות Seaborn heatmap()
. אז, לאחר יצירתו, נעביר את מטריצת הבלבול שלנו כטיעון עבור מפת החום:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')
- מטריקס בלבול: המטריצה מראה כמה דוגמאות המודל טעה או טעה עבור כל מחלקה. הערכים שהיו נכונים וחזויים כהלכה נקראים חיובי אמיתי, ואלה שנחזו כחיוביים אך לא היו חיוביים נקראים תוצאות חיוביות שגויות. אותה המינוח של שליליים אמיתיים ו שלילי שווא משמש לערכים שליליים;
על ידי התבוננות בעלילת מטריצת הבלבול, אנו יכולים לראות שיש לנו 287
ערכים שהיו 0
ונחזה כ 0
- או חיובי אמיתי לשיעור 0
(זרעי Çerçevelik). יש לנו גם 250
חיובי אמיתי לכיתה 1
(זרעי Ürgüp Sivrisi). הנקודות החיוביות האמיתיות ממוקמות תמיד באלכסון המטריצה העובר משמאל למעלה לימין תחתון.
יש לנו גם 29
ערכים שהיו אמורים להיות 0
, אבל חזוי כ 1
(תוצאות חיוביות שגויות) ו 59
ערכים שהיו 1
ונחזה כ 0
(שלילי שווא). עם המספרים האלה, אנחנו יכולים להבין שהשגיאה שהמודל עושה הכי הרבה היא שהוא מנבא שליליות שגויות. אז, זה יכול בעיקר בסופו של דבר לסווג זרע של Ürgüp Sivrisi כזרע של Çerçevelik.
סוג זה של שגיאה מוסבר גם על ידי ריקול של 81% מהכיתה 1
. שימו לב שהמדדים מחוברים. וההבדל בריקול נובע מכך שיש 100 דגימות פחות ממחלקת Ürgüp Sivrisi. זו אחת ההשלכות של קיום רק כמה דגימות פחות מהכיתה האחרת. כדי לשפר עוד יותר את הזכירה, אתה יכול להתנסות עם משקלי כיתות או להשתמש בדוגמאות נוספות של Ürgüp Sivrisi.
עד כה, ביצענו את רוב הצעדים המסורתיים של מדעי הנתונים והשתמשנו במודל הרגרסיה הלוגיסטית כקופסה שחורה.
הערה: אם אתה רוצה ללכת רחוק יותר, השתמש אימות צולב (CV) וחיפוש רשת לחפש, בהתאמה, את המודל שמכליל הכי הרבה לגבי נתונים, ואת פרמטרי המודל הטובים ביותר שנבחרים לפני האימון, או יתר פרמטרים.
באופן אידיאלי, עם חיפוש קורות חיים ורשת, תוכל גם ליישם דרך משורשרת לבצע שלבי עיבוד מקדים של נתונים, פיצול נתונים, מודלים והערכה - מה שמקל עם Scikit-Learn צינורות.
עכשיו זה הזמן לפתוח את הקופסה השחורה ולהסתכל בתוכה, להעמיק ולהבין איך עובדת רגרסיה לוגיסטית.
להעמיק כיצד רגרסיה לוגיסטית באמת עובדת
השמיים נסיגה המילה אינה שם במקרה, כדי להבין מה עושה רגרסיה לוגיסטית, אנו יכולים לזכור מה אחיה, הרגרסיה הליניארית עושה לנתונים. נוסחת הרגרסיה הליניארית הייתה כזו:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
שבו ב0 היה יירוט הרגרסיה, ב1 המקדם ו-x1 הנתונים.
המשוואה הזו הביאה לקו ישר ששימש לניבוי ערכים חדשים. אם נזכור את ההקדמה, ההבדל כעת הוא שלא נחזה ערכים חדשים, אלא מחלקה. אז הקו הישר הזה צריך להשתנות. עם רגרסיה לוגיסטית, אנו מציגים אי-לינאריות והניבוי נעשה כעת באמצעות עקומה במקום קו:
שימו לב שבעוד שקו הרגרסיה הליניארי ממשיך ועשוי מערכים אינסופיים מתמשכים, ניתן לחלק את עקומת הרגרסיה הלוגיסטית באמצע ויש לה קצוות בערכי 0 ו-1. צורת "S" זו הסיבה שהיא מסווגת נתונים - הנקודות הקרובות יותר או נופלות על הקצוות הגבוהה ביותר שייכות לכיתה 1, בעוד שהנקודות שנמצאות ברביע התחתון או קרוב יותר ל-0, שייכות לכיתה 0. האמצע של ה-"S" הוא האמצע בין 0 ל-1, 0.5 - הוא הסף לנקודות הרגרסיה הלוגיסטיות.
אנחנו כבר מבינים את ההבדל החזותי בין רגרסיה לוגיסטית ללינארית, אבל מה לגבי הנוסחה? הנוסחה לרגרסיה לוגיסטית היא הבאה:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
זה יכול להיכתב גם כך:
$$
y_{prob} = frac{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
או אפילו להיכתב כך:
$$
y_{prob} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
במשוואה למעלה, יש לנו את ההסתברות לקלט, במקום את הערך שלו. יש לו 1 כמונה, כך שהוא יכול להביא לערך בין 0 ל-1, ו-1 פלוס ערך במכנה שלו, כך שהערך שלו הוא 1 ומשהו - זה אומר שכל תוצאת השבר לא יכולה להיות גדולה מ-1 .
ומה הערך שיש במכנה? זה e, הבסיס של הלוגריתם הטבעי (בערך 2.718282), מורם לחזקת רגרסיה ליניארית:
$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
דרך אחרת לכתוב את זה תהיה:
$$
ln left( frac{p}{1-p} right) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
במשוואה האחרונה, ln הוא הלוגריתם הטבעי (בסיס e) ו p היא ההסתברות, כך שהלוגריתם של ההסתברות לתוצאה זהה לתוצאת הרגרסיה הליניארית.
במילים אחרות, עם תוצאת הרגרסיה הליניארית והלוגריתם הטבעי, נוכל להגיע להסתברות של קלט שייך או לא מחלקה מתוכננת.
כל תהליך גזירת הרגרסיה הלוגיסטית הוא כדלקמן:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
p + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
p
=
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
-
p
*
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
ln left( frac{p}{1-p} right) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$
המשמעות היא שלמודל הרגרסיה הלוגיסטית יש גם מקדמים וערך יירוט. מכיוון שהוא משתמש ברגרסיה ליניארית ומוסיף לה רכיב לא ליניארי עם הלוגריתם הטבעי (e
).
אנו יכולים לראות את ערכי המקדמים והיירוט של המודל שלנו, באותה דרך שראינו עבור רגרסיה ליניארית, באמצעות coef_
ו intercept_
נכסים:
logreg.coef_
המציג את המקדמים של כל אחת מ-12 התכונות:
array([[ 1.43726172, -1.03136968, 0.24099522, -0.61180768, 1.36538261,
-1.45321951, -1.22826034, 0.98766966, 0.0438686 , -0.78687889,
1.9601197 , -1.77226097]])
logreg.intercept_
זה מביא ל:
array([0.08735782])
בעזרת המקדמים וערכי היירוט, נוכל לחשב את ההסתברויות החזויות של הנתונים שלנו. בואו ניקח את הראשון X_test
שוב ערכים, כדוגמה:
X_test[:1]
זה מחזיר את השורה הראשונה של X_test
כמערך NumPy:
array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
-1.12235877, 0.45891056, -1.07825898, 0.56284738, -0.17604099,
0.23661678, -0.36013424]])
בעקבות המשוואה הראשונית:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
בפיתון יש לנו:
import math
lin_reg = logreg.intercept_[0] +
((logreg.coef_[0][0]* X_test[:1][0][0])+
(logreg.coef_[0][1]* X_test[:1][0][1])+
(logreg.coef_[0][2]* X_test[:1][0][2])+
(logreg.coef_[0][3]* X_test[:1][0][3])+
(logreg.coef_[0][4]* X_test[:1][0][4])+
(logreg.coef_[0][5]* X_test[:1][0][5])+
(logreg.coef_[0][6]* X_test[:1][0][6])+
(logreg.coef_[0][7]* X_test[:1][0][7])+
(logreg.coef_[0][8]* X_test[:1][0][8])+
(logreg.coef_[0][9]* X_test[:1][0][9])+
(logreg.coef_[0][10]* X_test[:1][0][10])+
(logreg.coef_[0][11]* X_test[:1][0][11]))
px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px
זו התוצאה:
0.45273372469369133
אם נסתכל שוב על predict_proba
תוצאה של הראשון X_test
שורה, יש לנו:
logreg.predict_proba(X_test[:1])
המשמעות היא שמשוואת הרגרסיה הלוגיסטית המקורית נותנת לנו את ההסתברות לקלט לגבי מחלקה 1
, כדי לברר איזו הסתברות היא לכיתה 0
, אנחנו יכולים פשוט:
1 - px
שימו לב ששניהם px
ו 1-px
זהים ל- predict_proba
תוצאות. כך מחושבת רגרסיה לוגיסטית ולמה נסיגה הוא חלק מהשם שלו. אבל מה עם המונח לוגיסטי?
המונח לוגיסטי בא מ לוגית, שזו פונקציה שכבר ראינו:
$$
בשמאל (frac{p}{1-p} ימין)
$$
זה עתה חישבנו את זה עם px
ו 1-px
. זהו הלוגיט, הנקרא גם יומן סיכויים מכיוון שהוא שווה ללוגריתם של הסיכויים היכן p
הוא הסתברות.
סיכום
במדריך זה, למדנו את אחד מאלגוריתמים הבסיסיים ביותר לסיווג למידת מכונה, כלומר - רגרסיה לוגיסטית.
בתחילה, יישמנו רגרסיה לוגיסטית כקופסה שחורה עם ספריית למידת המכונה של Scikit-Learn, ובהמשך הבנו אותה צעד אחר צעד כדי שיהיה ברור מדוע ומאיפה מגיעים המונחים רגרסיה ולוגיסטיקה.
כמו כן, חקרנו ולמדנו את הנתונים, מתוך הבנה שזהו אחד החלקים החשובים ביותר של ניתוח מדעי הנתונים.
מכאן, הייתי ממליץ לך לשחק עם רגרסיה לוגיסטית רב-מעמדית, רגרסיה לוגיסטית עבור יותר משתי מחלקות - אתה יכול ליישם את אותו אלגוריתם רגרסיה לוגיסטית עבור מערכי נתונים אחרים שיש להם מחלקות מרובות, ולפרש את התוצאות.
הערה: אוסף טוב של מערכי נתונים זמין כאן כדי שתוכל לשחק איתו.
אני גם ממליץ לך ללמוד את L1 ו-L2 הסדרות, הם דרך "להעניש" את הנתונים הגבוהים יותר כדי שהם יתקרבו לנורמליים, תוך שמירה על מורכבות המודל, כך שהאלגוריתם יכול להגיע לתוצאה טובה יותר. היישום של Scikit-Learn בו השתמשנו, כבר כולל רגולציה L2 כברירת מחדל. דבר נוסף שצריך להסתכל עליו הוא השונה פותרים, כמו lbgs
, אשר מייעלים את ביצועי אלגוריתם הרגרסיה הלוגיסטית.
חשוב גם להסתכל על סטטיסטי גישה לרגרסיה לוגיסטית. יש לזה הנחות על התנהגות הנתונים ועל נתונים סטטיסטיים אחרים שחייבים להתקיים כדי להבטיח תוצאות משביעות רצון, כגון:
- התצפיות עצמאיות;
- אין מולטי-קולינאריות בין משתנים מסבירים;
- אין חריגים קיצוניים;
- קיים קשר ליניארי בין משתנים מסבירים והלוגיט של משתנה התגובה;
- גודל המדגם גדול מספיק.
שימו לב כמה מהנחות אלו כבר כוסו בניתוח ובטיפול שלנו בנתונים.
אני מקווה שתמשיך לחקור מה יש לרגרסיה לוגיסטית להציע בכל הגישות השונות שלה!