שְׁאֵלָה:
כיצד לחשב שטח מתחת לעקומה (AUC), או נתון c, ביד
Matt Reichenbach
2015-04-09 22:53:46 UTC
view on stackexchange narkive permalink

אני מעוניין בחישוב שטח מתחת לעקומה (AUC), או בסטטיסטיקה c, ביד עבור מודל רגרסיה לוגיסטית בינארית.

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

המחשבות הראשוניות שלי היו לזהות את המספר "הנכון" של סיווגי המודל ופשוט לחלק את מספר התצפיות "הנכונות" במספר התצפיות הכוללות לחישוב סטטיסטיקה ג. על ידי "נכון", אם מצב השמירה האמיתי של תצפית = 1 ומצב השמירה החזוי הוא> 0.5 אז זה סיווג "נכון". בנוסף, אם מצב השמירה האמיתי של תצפית = 0 ומצב השמירה החזוי הוא < 0.5 אז זה גם סיווג "נכון". אני מניח ש"קשור "יתרחש כאשר הערך החזוי = 0.5, אך תופעה זו אינה מתרחשת במערך האימות שלי. מצד שני, סיווגים "לא נכונים" יהיו אם מצב השמירה האמיתי של תצפית = 1 ומצב השמירה החזוי הוא < 0.5 או אם מצב השמירה האמיתי לתוצאה = 0 ומצב השמירה החזוי הוא> 0.5. אני מודע ל- TP, FP, FN, TN, אך לא מודע כיצד לחשב את הסטטיסטיקה c בהתחשב במידע זה.

חָמֵשׁ תשובות:
Karl Ove Hufthammer
2015-04-13 23:40:48 UTC
view on stackexchange narkive permalink

אני ממליץ על מאמרו של הנלי, & McNeil, משנת 1982 ' המשמעות והשימוש באזור תחת עקומת הפעלת מקלט (ROC)'.

דוגמה

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

(1) נורמלי בהחלט: 33/3
(2) כנראה נורמלי: 6/2
(3) מוטל בספק: 6/2
(4) כנראה לא תקין: 11/11
(5) בהחלט לא תקין: 2/33

כך שיש בסך הכל 58 חולים 'רגילים' ו- '51' חריגים. אנו רואים שכאשר המנבא הוא 1, 'נורמלי בהחלט', המטופל בדרך כלל תקין (נכון עבור 33 מתוך 36 המטופלים), וכאשר הוא 5, 'בהחלט לא תקין' המטופלים בדרך כלל חריגים (נכון עבור 33 מתוך 35 חולים), כך שהמנבא הגיוני. אך כיצד עלינו לשפוט מטופל עם הציון 2, 3 או 4? מה שאנו קובעים לניתוק שלנו לשפוט חולים כלא תקין או תקין, קובע את הרגישות והספציפיות של הבדיקה שהתקבלה.

רגישות וספציפיות

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

אם אנו בוחרים בניתוק שלנו כך שנסווג הכל em> המטופלים כלא תקינים, לא משנה מה אומרות תוצאות הבדיקה שלהם (כלומר, אנו בוחרים את הקיצוץ 1+), נקבל רגישות של 51/51 = 1. הספציפיות תהיה 0/58 = 0. לא נשמע כל כך טוב.

בסדר, אז בוא נבחר לנתק פחות קפדני. אנו מסווגים מטופלים כלא תקינים אם יש להם תוצאת בדיקה של 2 ומעלה. לאחר מכן אנו מתגעגעים ל -3 חולים לא תקינים ויש לנו רגישות של 48/51 = 0.94. אך יש לנו ספציפיות מוגברת בהרבה, של 33/58 = 0.57.

כעת אנו יכולים להמשיך בכך, בבחירת ניתוקים שונים (3, 4, 5,> 5). (במקרה האחרון לא נסווג חולים כלשהם כלא תקינים, גם אם הם בעלי ציון הבדיקה הגבוה ביותר האפשרי של 5.)

עקומת ROC

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

  # Datanorm = rep (1: 5, times = c (33,6,6,11,2 )) abnorm = rep (1: 5, times = c (3,2,2,11,33)) testres = c (abnorm, norm) truestat = c (rep (1, אורך (abnorm)), rep (0 , אורך (נורמה))) # טבלת סיכום (טבלה I בעיתון) (tab = as.matrix (טבלה (truestat, testres)))  

הפלט הוא:

  testrestruestat 1 2 3 4 5 0 33 6 6 11 2 1 3 2 2 11 33  

אנחנו יכולים לחשב שונים סטטיסטיקה:

  (tot = colSums (tab)) # מספר חולים עם כל תוצאת בדיקה (truepos = unname (rev (cumsum (rev ()) לשונית [2,]))))) # מספר החיובי האמיתי (falsepos = unname (rev (cumsum (rev (tab [1,])))) # מספר החיובי השגוי (totpos = sum (tab [2, ])) # המספר הכולל של תוצאות חיוביות (מספר אחד) (totneg = סכום (כרטיסייה [1,])) # המספר הכולל שליליות (מספר אחד) (sens = truepos / totpos) # רגישות (חלק חיובי נכון) (omspec = falsepos / totneg) # 1 - ספציפיות (חיובי שווא) sens = c (sens, 0); omspec = c (omspec, 0) # מספרים כאשר אנו מסווגים הכל כרגיל  

ובאמצעות זה נוכל לשרטט את עקומת ה- ROC (המשוערת):

  עלילה (omspec, sens, type =" b ", xlim = c (0,1), ylim = c (0,1), lwd = 2, xlab =" 1 - ספציפיות ", ylab =" רגישות ") # אולי עם xaxs =" i "רשת () מוטה (0,1, col =" אדום ", lty = 2)  

AUC curve

חישוב ידני של ה- AUC

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

  height = (sens [ -1] + sens [-length (sens)]) / 2width = -diff (omspec) # = diff (rev (omspec)) סכום (גובה * רוחב)  

התוצאה היא 0.8931711.

מדד קונקורדנציה

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

  o = חיצוני (חריג, נורמה, "-") ממוצע ((o>0) + .5 * (o == 0))  

התשובה היא שוב 0.8931711, השטח מתחת לעיקול ROC. זה תמיד יהיה המקרה.

מבט גרפי על קונקורדנציה

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

  עלילה (ריצוד (truestat, .2), ריצוד (testres, .8), las = 1, xlab = "מצב מחלה אמיתי", ylab = "ציון מבחן")  

Scatter plot of risk score against true disease status.

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

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

d = cbind (x_norm = 0, x_abnorm = 1, expand.grid (y_norm = norm, y_abnorm = abnorm)) ספרייה (ggplot2) ggplot (d, aes (x = x_norm, xend = x_abnorm, y = y_norm, yend = y_abnorm)) + geom_segment (color = "# ff000006", position = position_jitter (רוחב = 0, גובה = .1)) + xlab ( "מצב מחלה אמיתי") + ylab ("בדוק \ nscore") + theme_light () + theme (axis.title.y = element_text (angle = 0))

Scatter plot of risk score against true disease status, with lines between all possible observation pairs.

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

  d = transform (d, slope = (y_norm-y_abnorm) / (x_norm-x_abnorm)) ממוצע ((d $ slope > 0) + .5 * (d $ slope == 0))  

התשובה היא שוב 0.8931711, כלומר AUC.

מבחן Wilcoxon – Mann – Whitney

קיים קשר הדוק בין מדד הקונקורדנציה לבין מבחן Wilcoxon – Mann – Whitney. למעשה, האחרון בודק אם ההסתברות לקונקורדנציה (כלומר, זה החולה הלא תקין בזוג אקראי נורמלי – לא תקין שתהיה לו תוצאת הבדיקה הכי "לא תקינה") היא בדיוק 0.5. ונתון הבדיקה שלה הוא רק שינוי פשוט של ההסתברות הקונקורדנטית המשוערת:

  > (wi = wilcox.test (abnorm, norm)) דרגת Wilcoxon מבחן סכום עם נתוני תיקון המשכיות: חריג ונורמה W = 2642, p-value = 1.944e-13 השערה אלטרנטיבית: שינוי מיקום אמיתי אינו שווה ל- 0  

נתון הבדיקה ( W = 2642 ) מונה את מספר הזוגות התואמים. אם נחלק אותו למספר הזוגות האפשריים, נקבל מספר מוכר:

  w = wi $ statisticw / (length (abnorm) * length (נורמה))  

כן, זה 0.8931711, השטח שמתחת לעיקול ה- ROC.

דרכים קלות יותר לחישוב ה- AUC (ב- R)

אבל בואו נעשה לנו חיים קלים יותר. ישנן חבילות שונות המחושבות עבורנו את ה- AUC באופן אוטומטי.

חבילת Epi

חבילת Epi יוצרת עקומת ROC יפה עם נתונים סטטיסטיים שונים (כולל AUC) מוטבע:

  ספרייה (Epi) ROC (testres, truestat) # נסה גם להוסיף plot = "sp"  

ROC curve from the Epi package

חבילת pROC

אני גם אוהב את החבילה pROC מכיוון שהיא יכולה להחליק את אומדן ה- ROC (ולחשב AUC הערכה על סמך ה- ROC המוחלק):

ROC curve (unsmoothed and smoothed) from the pROC package

(הקו האדום הוא ה- ROC המקורי, והקו השחור הוא ה- ROC המוחלק. שימו לב גם לברירת המחדל 1: 1 יחס הגובה-רוחב. זה הגיוני להשתמש בזה, מכיוון שגם לרגישות וגם לספציפיות יש טווח 0-1.)

ה- AUC המשוער מ- מוחלק ROC הוא 0.9107, בדומה ל , אך מעט גדול יותר מ- AUC מ- ROC הלא מוחלק (אם מסתכלים על הדמות, תוכלו לראות בקלות מדוע היא גדולה יותר). (אם כי באמת יש לנו מעט מדי ערכי תוצאות בדיקה אפשריים בכדי לחשב AUC חלק).

חבילת ה- rms

חבילת ה- rms של הראל יכולה לחשב קשורים שונים סטטיסטיקה של קונקורדנציה באמצעות הפונקציה rcorr.cens () . C אינדקס בפלט שלו הוא AUC:

  ספריית > (rms) > rcorr.cens (testres, truestat ] [1] אינדקס C 0.8931711  

חבילת caTools

לבסוף, יש לנו את החבילה caTools ואת colAUC () שלה פונקציה . יש לו כמה יתרונות על פני חבילות אחרות (בעיקר מהירות ויכולת לעבוד עם נתונים רב מימדיים - ראה ? ColAUC ) שיכולות לפעמים להועיל. אבל כמובן שזה נותן את אותה התשובה כמו שחישבנו שוב ושוב:

  ספרייה (caTools)
colAUC (testres, truestat, plotROC = TRUE) [, 1] 0 לעומת 1 0.8931711  

ROC curve from the caTools package

מילים אחרונות

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

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

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

אז אני חושב שלימוד ה עקומת ROC בפועל יהיה שימושי יותר מסתם להסתכל על מדד סיכום AUC. ואם אתה משתמש ב- ROC יחד עם (הערכות של) ה עלויות של תוצאות חיוביות שגויות ושליליות כוזבות, יחד עם שיעורי הבסיס של מה שאתה לומד, אתה יכול להגיע לאנשהו.

שים לב גם ש- AUC מודד רק אפליה , ולא כיול. כלומר, זה מודד אם אתה יכול להבחין בין שני אנשים (אחד חולה ואחד בריא), על סמך ציון הסיכון. לשם כך, הוא מסתכל רק על ערכי סיכון יחסיים (או מדרגים, אם תרצו, עיין בפרשנות הבדיקה של Wilcoxon – Mann – Whitney), ולא על המוחלט ש אתה צריך למשל, אם אתה מחלק כל הערכת סיכונים מהמודל הלוגיסטי שלך ב -2, תקבל בדיוק אותו AUC (ו- ROC).

בעת הערכת מודל סיכון, כיול הוא גם מאוד חשוב. כדי לבחון זאת, תסתכל על כל החולים עם ציון הסיכון של סביב, למשל, 0.7, ותראה אם ​​כ- 70% מאלה אכן היו חולים. עשו זאת לכל ציון סיכון אפשרי (אולי באמצעות איזושהי החלקה / רגרסיה מקומית). התווה את התוצאות, ותקבל מדד גרפי של כיול .

אם יש לך מודל עם כיול טוב ואפליה טובה, אז אתה להתחיל להיות מודל טוב. :)

תודה לך, @Karl Ove Hufthammer, זו התשובה היסודית ביותר שקיבלתי.אני מעריך במיוחד את הקטע "מילים אחרונות".עבודה מצויינת!שוב תודה!
תודה רבה על התשובה המפורטת הזו.אני עובד עם מערך נתונים שבו Epi :: ROC () v2.2.6 משוכנע שה- AUC הוא 1.62 (לא זה לא מחקר מנטליסטי), אך על פי ה- ROC, אני מאמין הרבה יותר ב- 0.56 שהקוד הנ"ל מביאב.
אני חושב שיש שגיאה קטנה ב- `sens = c (sens, 0);omspec = c (omspec, 0) `, זה לא צריך להיות` sens = c (0, sens);omspec = c (0, omspec) `?זה מתכנן כראוי עם '0' המוביל אך לא כמו שהוא נמצא כרגע בתשובה.
לא, ההגדרה הנוכחית היא, AFAICS, נכון, @steveb, ומביא לעלילה נכונה.אני חושב שמה שאולי מבלבל הוא שעקומת ROC נמשכת מ- * ימין לשמאל * (כלומר מהפינה הימנית העליונה לפינה השמאלית התחתונה), ולא מ- * שמאל לימין *, כמו שרוב העלילות הן.זו רק התוצאה של איך שהגדרתי את המשתנים;באותה מידה אפשר היה לתכנן את זה משמאל לימין (על ידי היפוך הן של "sens" והן של "omspec" לפני זממה).
Alexey Grigorev
2015-04-14 13:23:24 UTC
view on stackexchange narkive permalink

הסתכל בשאלה זו: הבנת עקומת ROC

כך לבנות עקומת ROC (משאלה זו):

ציור עקומת ROC

בהתחשב בערכת נתונים שעובד על ידי מסווג הדירוג שלך

  • דוגמאות למבחני דירוג בציון יורד
  • התחל ב- $ (0, 0) $
  • לכל דוגמה $ x $ (בסדר היורד)
    • אם $ x $ חיובי, הזז $ 1 / \ text {pos} $ למעלה
    • אם $ x $ הוא שלילי, הזז $ 1 / \ text {neg} $ ימינה

איפה $ \ text {pos} $ ו- $ \ text {neg} $ את השברים של דוגמאות חיוביות ושליליות בהתאמה.

אתה יכול להשתמש ברעיון זה לחישוב ידני של AUC ROC באמצעות האלגוריתם הבא:

  auc = 0.0height = 0.0 לכל דוגמת אימון x_i, y_i אם y_i = 1.0: גובה = גובה + tpr אחר auc = auc + גובה * fprreturn auc  

התמונה הנפלאה הזו של אנימציית gif אמורה להמחיש את התהליך הזה ברור יותר

building the curve

תודה @Alexey Grigorev, זה חזותי נהדר וזה כנראה יתגלה כשימוש בעתיד!+1
האם בבקשה תוכל להסביר קצת על "שברים של דוגמאות חיוביות ושליליות", האם אתה מתכוון לערך היחידה הקטן ביותר של שני צירים?
@Allan Ruin: `pos` פירושו כאן מספר הנתונים החיוביים.נניח שיש לך 20 נקודות נתונים, בהן 11 נקודות הן 1. לכן, בעת ציור התרשים, יש לנו מלבן 11x9 (גובה x רוחב). אלכסיי גריגורב אכן התרחש אבל פשוט נתן לזה כאילו אם תרצה.עכשיו פשוט העבר 1 בתרשים בכל שלב.
Frank Harrell
2015-04-14 17:41:41 UTC
view on stackexchange narkive permalink

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

בכל מה שקשור לחישוב ידני של אינדקס $ c $, צרו עלילה עם $ Y = 0,1 $ ב- $ x $ - ציר והמנבא הרציף או ההסתברות החזויה ש- $ Y = 1 $ על הציר $ y $. אם אתה מחבר כל נקודה עם $ Y = 0 $ עם כל נקודה עם $ Y = 1 $, שיעור הקווים שיש להם שיפוע חיובי הוא ההסתברות הקונקורדנטית.

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

לפונקציית R Hmisc rcorr.cens , הדפס את התוצאה כולה כדי לראות מידע נוסף , במיוחד שגיאה סטנדרטית.

תודה לך, @Frank הראל, אני מעריך את נקודת המבט שלך.אני פשוט משתמש בסטטיסטיקה c כהסתברות קונקורדנציה, מכיוון שאני לא אוהב קיצוצים.שוב תודה!
Jeff
2015-04-13 19:59:43 UTC
view on stackexchange narkive permalink

הנה אלטרנטיבה לדרך הטבעית של חישוב AUC פשוט על ידי שימוש בכלל הטרפז כדי לקבל את השטח מתחת לעיקול ROC.

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

  n <- 100Lx1 <- rnorm (n, 2.0, 0.5) x2 <- rnorm (n, -1.0, 2) y <- rbinom (n, 1L, plogis (-0.4 + 0.5 * x1 + 0.1 * x2)) mod <- glm (y ~ x1 + x2, "binomial") probs <- לחזות (mod, type = "תגובה") שילובים <- expand.grid (positiveProbs = בדיקות [y == 1L], negativeProbs = בדיקות [y == 0L]) ממוצע (שילובים $ positiveProbs > שילובים $ negativeProbs) [1] 0.628723  

אנו יכולים לאמת באמצעות pROC package:

  library (pROC) auc (y, probs) שטח מתחת לעקומה: 0.6287  

באמצעות דגימה אקראית:

  ממוצע (מדגם (בדיקות [y == 1L], 100000L, TRUE) מדגם > (probs [y == 0L], 100000L, TRUE)) [1] 0.62896  
user73455
2015-04-13 22:26:22 UTC
view on stackexchange narkive permalink
  1. יש לך ערך אמיתי לתצפיות.
  2. חישב הסתברות אחורית ואז דרג תצפיות על פי הסתברות זו.
  3. בהנחת הסתברות חתך של $ P $ ומספר תצפיות $ N $:
    $$ \ frac {\ text {סכום הדרגות האמיתיות} -0.5PN (PN + 1)} { PN (N-PN)} $$
@user73455 ... 1) כן, יש לי את הערך האמיתי לתצפיות.2) האם ההסתברות האחורית היא שם נרדף להסתברויות חזויות לכל אחת מהתצפיות?3) הובן;עם זאת, מהו "סכום הדרגות האמיתיות" וכיצד מחשבים ערך זה?אולי דוגמה תעזור לך להסביר תשובה זו בצורה יסודית יותר?תודה!


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 3.0 עליו הוא מופץ.
Loading...