Lojistik regresyon, y kategorik bir değişken olduğunda y = f (x) regresyon eğrisini yerleştirmek için bir yöntemdir . Bu modelin tipik kullanımı, bir grup yordayıcı x verildiğinde y‘yi tahmin etmektir. bağımsız değişkenler sürekli, kategorik veya her ikisinin bir karışımı olabilir.
Kategorik değişken y , genel olarak farklı değerler alabilir. En basit senaryoda y , ikili değerdir. Bu y’nin 1 veya 0 değerini alabileceği anlamına gelir. Makine öğreniminde kullanılan klasik bir örnek e-posta sınıflandırmasıdır: kelime, bağlantı ve resim sayısı gibi her e-posta için bir dizi özellik verildiğinde, algoritma, e-postanın spam olup (1) olmadığına (0) karar vermelidir. Bu yazıda modele, tahmin edilecek değişken ikili olduğu için “binom lojistik regresyon” diyoruz, ancak lojistik regresyon, 2’den fazla değer alabilen bağımlı bir değişkeni tahmin etmek için de kullanılabilir. Bu ikinci durumda, modele “çok terimli lojistik regresyon” diyoruz. Örneğin tipik bir örnek, filmleri “Eğlenceli”, “sınır çizgisi” veya “sıkıcı” arasında sınıflandırmak olabilir.
R, lojistik regresyon modelini uydurma işlemini çok kolaylaştırır. Çağrılacak fonksiyon glm() ve uydurma işlemi doğrusal regresyonda kullanılandan çok farklı değildir. Bu yazıda bir ikili lojistik regresyon modeli uyduracağım ve her adımı açıklayacağım.
Titanik veri seti üzerinde çalışacağız . Bu veri setlerinin çevrimiçi olarak farklı sürümleri mevcut, ancak Kaggle’da mevcut olanı kullanmanızı öneririm , çünkü neredeyse kullanıma hazır durumda (indirmek için Kaggle’a kaydolmanız gerekli).
Titanik veri seti (eğitim amaçlı), bazı yolcularla (tam olarak 889) ilgili bir veri kümesi ve yarışmanın amacı, veri kümesindeki bazı özelliklere (hizmetin sınıfına , cinsiyet , yaş vb.) dayanarak yolcuların hayatta kalıp kalmamış olduklarını tahmin etmek (yolcu hayatta kaldıysa 1 ya da yoksa 0 gibi). Sizin de farkedebileceğiniz gibi, hem kategorik hem de sürekli değişkenler kullanacağız.
Gerçek bir veri kümesiyle çalışırken, bazı verilerin eksik veya kullanışsız olabileceğini dikkate almamız, bu nedenle veri kümesini analizimiz için hazırlamamız gerekir. İlk adım olarak csv verilerini read.csv() fonksiyonunu kullanarak yüklüyoruz . na.strings parametresinin c(“”) olduğundan emin olun. Bu, tüm eksik verilerin NA olarak kodlanmasını sağlayarak sonraki adımlarda bize yardımcı olacak.
training.data.raw <- read.csv('train.csv',header=T,na.strings=c(""))
Şimdi, eksik değerleri kontrol etmeli ve veri çerçevesinin her sütununa bağımsız değişken olarak iletilen fonksiyonu uygulayan sapply() fonksiyonunu kullanarak her değişken için kaç tekil değer olduğunu görmeliyiz.
sapply(training.data.raw,function(x) sum(is.na(x)))
PassengerId Survived Pclass Name Sex
0 0 0 0 0
Age SibSp Parch Ticket Fare
177 0 0 0 0
Cabin Embarked
687 2
sapply(training.data.raw, function(x) length(unique(x)))
PassengerId Survived Pclass Name Sex
891 2 3 891 2
Age SibSp Parch Ticket Fare
89 7 7 681 248
Cabin Embarked
148 4
Eksik değerlerin görsel olarak incelenmesi yararlı olabilir: Amelia paketinde veri kümemizi çizecek ve eksik değerleri vurgulayacak missmap() şeklinde özel bir çizim işlevi mevcut.
library(Amelia)
missmap(training.data.raw, main = "Missing values vs observed")
Grafikten de gördüğümüz üzere “Cabin” değişkeninde çok fazla eksik değer var, bu yüzden onu kullanmayacağız. PassengerId’i de sadece bir dizin olduğu için bırakacağız. subset() fonksiyonunu kullanarak veri kümesinden yalnızca ilgileneceğimiz sütunları içeren bir alt küme oluşturuyoruz.
data <- subset(training.data.raw,select=c(2,3,5,6,7,8,10,12))
Şimdi diğer eksik değerleri hesaba katmamız gerekiyor. R, genelleştirilmiş bir doğrusal modeli uydururken, fonksiyonunun içindeki bir parametreyi ayarlayarak eksik değerlerle kolayca başa çıkabiliyor. Ancak, ben NA’ları mümkün olduğunca “elle” değiştirmeyi tercih ediyorum . Bunu yapmanın farklı yolları mevcut, örneğin bilindik bir uygulama eksik değerleri mevcut değerlerin ortalaması, medyanı veya mevcut mod ile değiştirmektir. Ben ortalamayı kullanacağım.
data$Age[is.na(data$Age)] <- mean(data$Age,na.rm=T)
Kategorik değişkenler söz konusu olduğunda, read.table() veya read.csv() fonksiyonları varsayılan olarak kullanılması kategorik değişkenleri faktörler olarak kodlayacaktır. Faktör, R’nin kategorik değişkenleri nasıl ele aldığıdır. Aşağıdaki kod satırlarını kullanarak kodlamayı kontrol edebiliriz:
is.factor(data$Sex)
TRUE
is.factor(data$Embarked)
TRUE
R’nin kategorik değişkenlerle nasıl başa çıkacağını daha iyi anlamak için contrasts() fonksiyonunu kullanabiliriz . Bu fonksiyon bize değişkenlerin R tarafından nasıl kuklalaştırıldığını ve bir modelde nasıl yorumlanacağını gösterecektir.
contrasts(data$Sex)
male
female 0
male 1
contrasts(data$Embarked)
Q S
C 0 0
Q 1 0
S 0 1
Örneğin, cinsiyet değişkeninde bayanın referans olarak kullanılacağını görebilirsiniz. Embarked’daki eksik değerlere gelince, sadece iki tane olduğundan, bu iki satırı atacağız (eksik değerleri en çok tekrarlanan değer ile değiştirebilir ve verileri öylece saklayabiliriz).
data <- data[!is.na(data$Embarked),]
rownames(data) <- NULL
Model uydurma işlemine geçmeden önce , verilerin temizlenmesi ve biçimlendirilmesinin ne kadar önemli olduğunu tekrar söylemek isterim. Bu önişleme adımı genellikle modelin iyi bir uyum ve daha iyi öngörme yeteneği elde etmesi için çok önemlidir.
Verileri iki parçaya ayırıyoruz: eğitim ve test seti. Eğitim seti, test seti üzerinde test edeceğimiz modelimizin elde edilmesinde kullanılacak.
train <- data[1:800,]
test <- data[801:889,]
Şimdi modeli yerleştirelim. glm() fonksiyonunda family = binomial parametresini belirttiğinizden emin olun.
model <- glm(Survived ~.,family=binomial(link='logit'),data=train)
summary() fonksiyonunu kullanarak modelimizin sonuçlarını görelim:
summary(model)
Call:
glm(formula = Survived ~ ., family = binomial(link = "logit"),
data = train)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.6064 -0.5954 -0.4254 0.6220 2.4165
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 5.137627 0.594998 8.635 < 2e-16 ***
Pclass -1.087156 0.151168 -7.192 6.40e-13 ***
Sexmale -2.756819 0.212026 -13.002 < 2e-16 ***
Age -0.037267 0.008195 -4.547 5.43e-06 ***
SibSp -0.292920 0.114642 -2.555 0.0106 *
Parch -0.116576 0.128127 -0.910 0.3629
Fare 0.001528 0.002353 0.649 0.5160
EmbarkedQ -0.002656 0.400882 -0.007 0.9947
EmbarkedS -0.318786 0.252960 -1.260 0.2076
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1065.39 on 799 degrees of freedom
Residual deviance: 709.39 on 791 degrees of freedom
AIC: 727.39
Number of Fisher Scoring iterations: 5
Şimdi uydurulan modeli analiz edebilir ve bize ne söylediğini yorumlayabiliriz. Her şeyden önce, SibSp , Fare ve Embarked’ın istatistiksel olarak anlamlı olmadığını görebiliriz. İstatistiksel olarak anlamlı değişkenlere gelince, cinsiyet, yolcunun cinsiyetinin hayatta kalma olasılığı ile güçlü bir ilişkisi olduğunu gösteren en düşük p değerine sahip. Bu bağımsız değişkenin negatif katsayısı, diğer tüm değişkenlerin eşit olduğu durumda, erkek yolcunun hayatta kalma olasılığının daha düşük olduğunu göstermektedir. Logit modelinde bağımlı değişkeninin log olasılıkları olduğunu unutmayın: ln (odds) = ln (p / (1-p)) = a * x1 + b * x2 +… + z * xn. Erkek kukla bir değişken olduğundan, erkek olmak log oranlarını 2.75 oranında azaltırken, yaşta birim artış log oranlarını 0.037 azaltır.
Şimdi sapma tablosunu analiz etmek için anova() fonksiyonunu çağırabiliriz.
anova(model, test="Chisq")
Analysis of Deviance Table
Model: binomial, link: logit
Response: Survived
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev Pr(>Chi)
NULL 799 1065.39
Pclass 1 83.607 798 981.79 < 2.2e-16 ***
Sex 1 240.014 797 741.77 < 2.2e-16 ***
Age 1 17.495 796 724.28 2.881e-05 ***
SibSp 1 10.842 795 713.43 0.000992 ***
Parch 1 0.863 794 712.57 0.352873
Fare 1 0.994 793 711.58 0.318717
Embarked 2 2.187 791 709.39 0.334990
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Null sapma ile rezidüel sapma arasındaki fark, modelimizin null modele (sadece sabit terim içeren model) karşı nasıl bir performans gösterdiğini gösterir. Bu fark ne kadar geniş olursa o kadar iyidir. Tabloyu incelerken, her bir değişkeni birer birer eklerken sapmadaki düşüşü görebiliriz. Yine Pclass , Sex ve Age eklemek rezidüel sapmayı önemli ölçüde azaltmakta. SibSp düşük bir p değerine sahip olsa da diğer değişkenler modeli daha az geliştiriyor gibi görünüyor. Buradaki büyük bir p değeri, bu değişkenin olmadığı modelin aşağı yukarı aynı miktarda değişimi açıkladığını gösterir. Nihayetinde görmek istediğiniz şey sapma ve AIC’de anlamlı düşüşlerdir.
Doğrusal regresyonun R2’sine tam bir eşdeğer olmamakla birlikte, model uyumunu değerlendirmek için McFadden R2 indeksi kullanılabilir.
library(pscl)
pR2(model)
llh llhNull G2 McFadden r2ML r2CU
-354.6950111 -532.6961008 356.0021794 0.3341513 0.3591775 0.4880244
Yukarıdaki adımlarda, modelin uyumunu kısaca değerlendirdik, şimdi yeni bir veri kümesinde y‘yi tahmin ederken modelin ne yaptığını görelim. Parameter type =”response” şeklinde ayarlandığında R, olasılıkları P(y=1|X) formunda verir. Karar sınırımız 0,5 olacak. P (y = 1 | X)> 0.5 ise y = 1 ise aksi halde y = 0 olur. Bazı uygulamalar için farklı eşiklerin daha iyi bir seçenek olabileceğini unutmayın.
fitted.results <- predict(model,newdata=subset(test,select=c(2,3,4,5,6,7,8)),type='response')
fitted.results <- ifelse(fitted.results > 0.5,1,0)
misClasificError <- mean(fitted.results != test$Survived)
print(paste('Accuracy',1-misClasificError))
"Accuracy 0.842696629213483"
Test setindeki 0.84 hassasiyeti oldukça iyi bir sonuçtur. Bununla birlikte, bu sonucun daha önce yaptığım verilerin manuel olarak bölünmesine bağlı olduğunu unutmayın, bu nedenle daha kesin bir puan istiyorsanız, K-katmanlı çapraz doğrulama (k-Fold Cross-Validation) gibi bir tür çapraz doğrulama yapmanız daha doğru olacaktır.
Son adım olarak, ROC eğrisini çizeceğiz ve bir ikili sınıflandırıcı için tipik performans ölçümleri olan AUC’yi (area under curve – eğrinin altındaki alan) hesaplayacağız. ROC, AUC ROC eğrisinin altındaki alan iken, çeşitli eşik ayarlarında gerçek pozitif oranın (TPR) yanlış pozitif orana (FPR) karşı çizilmesiyle oluşturulan bir eğridir. Temel kural olarak, iyi tahmin kabiliyetine sahip bir model, 0.5’e kıyasla 1’e (1 idealdir) yakın bir AUC’ye sahip olmalıdır.
library(ROCR)
p <- predict(model, newdata=subset(test,select=c(2,3,4,5,6,7,8)), type="response")
pr <- prediction(p, test$Survived)
prf <- performance(pr, measure = "tpr", x.measure = "fpr")
plot(prf)
auc <- performance(pr, measure = "auc")
auc <- [email protected][[1]]
auc
0.8647186
Umarım bu yazı faydalı olacaktır. Bu örneğin tam kodunu içeren bir özeti burada bulabilirsiniz .
Bu yayını okuduğunuz için teşekkür ederiz, herhangi bir sorunuz varsa aşağıya bir yorum bırakın.
Kaynak: https://www.r-bloggers.com/2015/09/how-to-perform-a-logistic-regression-in-r/