R - Логистическая регрессия - Модель довольно плохо предсказывает и разбивает данные.Идеи? - PullRequest
0 голосов
/ 03 декабря 2018

Я не знаю, почему, но моя модель предсказывает все как ЛОЖЬ, что, очевидно, не является правильным способом прогнозирования тестовых данных.

Структура данных:

$ Anrede             : Factor w/ 4 levels "Familie","Firma",..: 3 4 4 4 4 3 3 3 4 3 ...
 $ KontaktPerTelefon  : num  1 0 1 1 1 1 1 1 1 0 ...
 $ KontaktPerEmail    : num  1 1 1 1 1 1 1 1 1 1 ...
 $ JahresbeitragBrutto: num  60 25 60 12 60 60 24 24 48 48 ...
 $ EMailBoolean       : logi  TRUE TRUE TRUE FALSE TRUE TRUE ...
 $ Jahreszeit         : Factor w/ 4 levels "Frühling","Herbst",..: 4 4 4 4 4 4 4 4 4 4 ...
 $ Tageszeit          : Factor w/ 4 levels "Abend","Mittag",..: 1 3 3 4 3 3 3 2 1 1 ...
 $ Organisation       : Factor w/ 3 levels "BRK","DRK","MHD": 1 1 1 1 1 1 1 1 1 1 ...
 $ Alter              : num  48.1 56.1 32.3 63.8 34.5 ...
 $ StornoBoolean      : logi  FALSE FALSE FALSE TRUE FALSE FALSE ...

R Код для моделирования

set.seed(101) 
sample <- sample.split(df_data_modeling$StornoBoolean, SplitRatio = 0.70) 
train = subset(df_data_modeling, sample == TRUE)
test = subset(df_data_modeling, sample == FALSE)
model = glm(StornoBoolean ~ ., family = binomial(logit), data = train)

Решения приведены здесь.Почти каждая переменная имеет значение!

   Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-6.5697  -0.6222  -0.5220  -0.4229   2.9912  

Coefficients:
                      Estimate Std. Error z value Pr(>|z|)    
(Intercept)         -0.7540186  0.0695698 -10.838  < 2e-16 ***
AnredeFirma         -0.1354145  0.1008984  -1.342  0.17957    
AnredeFrau           0.4519410  0.0517078   8.740  < 2e-16 ***
AnredeHerr           0.2772757  0.0519187   5.341 9.27e-08 ***
KontaktPerTelefon    0.1023211  0.0223885   4.570 4.87e-06 ***
KontaktPerEmail      0.1066560  0.0228986   4.658 3.20e-06 ***
JahresbeitragBrutto  0.0008593  0.0001412   6.088 1.15e-09 ***
EMailBooleanTRUE    -0.2772308  0.0226086 -12.262  < 2e-16 ***
JahreszeitHerbst    -0.4084937  0.0388069 -10.526  < 2e-16 ***
JahreszeitSommer    -0.1130239  0.0257069  -4.397 1.10e-05 ***
JahreszeitWinter    -0.0632982  0.0424629  -1.491  0.13605    
TageszeitMittag      0.1101916  0.0243596   4.524 6.08e-06 ***
TageszeitNachmittag  0.0801742  0.0244504   3.279  0.00104 ** 
TageszeitVormittag   0.0811602  0.0318205   2.551  0.01075 *  
OrganisationDRK     -0.2433693  0.0230773 -10.546  < 2e-16 ***
OrganisationMHD      0.1593983  0.0262643   6.069 1.29e-09 ***
Alter               -0.0231121  0.0005689 -40.627  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 80553  on 93752  degrees of freedom
Residual deviance: 78042  on 93736  degrees of freedom
AIC: 78076

Number of Fisher Scoring iterations: 4

Моя путаница и код:

test$predicted.Storno = predict(model, newdata=test, type="response")
table(test$StornoBoolean, test$predicted.Storno > 0.5)




    FALSE  TRUE
  FALSE 33982     8
  TRUE   6188     0

На самом деле я понятия не имею, почему мой прогноз настолько плох.Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Ваши данные несбалансированы.Вы можете попробовать некоторые методы передискретизации / недосэмплинга, такие как smote, но, вероятно, самая простая вещь, которую вы можете сделать, это изменить положительный порог с 0.5 на что-то меньшее.

Причина в том, что данныесмещен в сторону 0, поэтому выходы тоже будут смещены, потому что это лучший способ оптимизировать функцию потерь.

Другими словами, алгоритм может многому научиться у отрицательного класса, но не так много у положительного, поэтому, когда он должен предсказать, он редко будет иметь более чем 1008 свидетельств положительности, поэтомубудь готов сказать "хорошо, мне не нужно 0.5 свидетельство положительного класса, мне просто нужно (скажем, скажем) 0.2" .Вы можете думать об этом с другой стороны: , так как алгоритм знает намного больше о отрицательном классе, вывод 0.2 является достаточным доказательством против отрицательного класса, поэтому я должен прогнозировать положительное вместо

0 голосов
/ 03 декабря 2018

Я не уверен, что на самом деле вы пытаетесь предсказать, так что может случиться так, что многие переменные значимы, так как 40000 - это довольно большой простейший.

Но главное -вопрос: почему он предсказывает все (кроме 8) как ЛОЖЬ?
Ответ: это не так, но вы тестируете это с test$predicted.Storno > 0.5.Это то же самое, что спросить: во скольких случаях вероятность возникновения заболевания превышает 50%.Как мы видим из вашей таблицы, только около 15% - ИСТИНА, поэтому вполне может быть, что даже случаи с самыми высокими коэффициентами остаются ниже 50%.Это звучит расплывчато, поэтому позвольте мне объяснить на примере:

Курение увеличивает ваши шансы заболеть раком легких.
Работа в шахтах увеличивает ваши шансы заболеть раком легких.
Семейная история ракаувеличивает ваши шансы заболеть раком.
Каковы шансы, что шахтер, который курит и имеет семейную историю рака, получит рак легкого до того, как ему исполнится 50?
Его шансы невелики, но все же этот шанс был быдо 50%, наверное, 10%?(в отличие от, возможно, 0,2% для широкой публики).
Так что, если вы сделаете модель, если это так, модель скажет что-то вроде предиката = 0,1, который вы переведете в ЛОЖЬ.И если вы запустите эту модель на 100 курящих горняках с семейным анамнезом, у каждого из них будет шансы <50% заболеть раком: 100 раз ЛОЖЬ.Хотя мы знаем статистически, вероятно, 10 из них заболеют раком легких.Просто индивидуально, каждый из 100 может ожидать здоровья. </p>

Так что в своем вопросе вы должны знать, о чем вы просите.Есть еще несколько статистических анализов о том, какую именно ценность использовать, о которой я не знаю достаточно, но сначала вам нужно точно знать, о чем вы спрашиваете.

РЕДАКТИРОВАТЬ:
Это не так многовопрос о том, как отредактировать / настроить вашу модель, но больше о том, как интерпретировать полученный результат.Некоторые примеры того, что вы можете спросить, и как получить ответы:

  • Какие члены, скорее всего, в среднем верны?Вы можете проверить это, проверив, какие прогнозные значения превышают средние, например: table(test$StornoBoolean, test$predicted.Storno > 6188/(33982+6188+8)
  • Какие члены, скорее всего, будут истинными?`test <- test [порядок (test $ предикат. Storno, убывающий = ИСТИНА),] упорядочит результаты вашего теста </li>
  • Проверка, является ли ваша модель (в целом) надежной: вы можете построить прогнозные коэффициенты относительно фактического отношения.
    library(ggplot2); print(ggplot(data=test)+geom_histogram(aes(x=predicted.Storno, fill=StornoBoolean), position='stack'))
    Если ваша модель была бы идеальной, при x = 0,10 10% от полного бара должно быть TRUE, 20% при 0,20 и т. Д. Обычно это не так, но вы должнывозможность видеть, что истинная доля увеличивается с увеличением х.Если вы хотите более четко увидеть, что такое фракция, вы можете использовать position = 'fill' в вызове, что означает, что все столбцы сжимаются / расширяются до одинаковой высоты, что делает фракцию более четкой для просмотра.Однако это может привести к вводящей в заблуждение картине для прогнозируемых значений, которые встречаются редко, поэтому следует смотреть только на значения x, которые достаточно часты.
...