Analiz için gerekli olan kütüphaneler yükleniyor.
library(tidyverse)
# tidyverse paketi veri manipülasyonu ve okuma işlemleri için yükleniyor. Python'daki pandas kütüphanesine karşılık gelir.
library(ggplot2)
# ggplot2 paketi görselleştirme işlemleri için yükleniyor. Python'daki matplotlib ve seaborn kütüphanelerine benzer işlevler sunar.
library(corrplot)
# corrplot paketi korelasyon matrislerini görselleştirmek için kullanılır.
library(caTools)
# caTools paketi veri setini train ve test olarak bölmek için kullanılır.
library(car)
# car paketi VIF (Variance Inflation Factor) testini hesaplamak için gereklidir. Çoklu bağıntı problemini tespit etmeye yarar.
library(lmtest)
# lmtest paketi Breusch-Pagan ve Durbin-Watson gibi istatistiksel testleri yapmak için kullanılır.
# install.packages("fastDummies")
# Not: Paket zaten yüklüyse install satırını yorum satırı yapabilirsiniz.
# fastDummies paketi kategorik değişkenleri dummy değişkenlere dönüştürmek için yükleniyor.
library(fastDummies)
# fastDummies paketi one-hot encoding işlemi için aktif hale getiriliyor.
df <- read.csv("insurance.csv")
# Kullanıcıdan bir CSV dosyası seçmesi isteniyor ve bu dosya df isimli bir veri çerçevesine yükleniyor.
cat("Veri Seti Boyutu:", dim(df), "\n")
## Veri Seti Boyutu: 1338 7
# Veri setinin boyutu yani satır ve sütun sayısı ekrana yazdırılıyor.
print(head(df))
## age sex bmi children smoker region charges
## 1 19 female 27.900 0 yes southwest 16884.924
## 2 18 male 33.770 1 no southeast 1725.552
## 3 28 male 33.000 3 no southeast 4449.462
## 4 33 male 22.705 0 no northwest 21984.471
## 5 32 male 28.880 0 no northwest 3866.855
## 6 31 female 25.740 0 no southeast 3756.622
# Veri setinin ilk 6 satırı ekrana yazdırılarak veriye genel bir bakış sağlanıyor.
cat("\n--- Eksik Veri Sayıları ---\n")
##
## --- Eksik Veri Sayıları ---
# Eksik veri kontrolü için bir başlık yazdırılıyor.
print(colSums(is.na(df)))
## age sex bmi children smoker region charges
## 0 0 0 0 0 0 0
# Her sütundaki eksik veri sayısı hesaplanıp ekrana yazdırılıyor.
numeric_cols <- c("age", "bmi", "children", "charges")
# Sayısal değişkenlerin isimleri bir vektörde toplanıyor. Bu değişkenler üzerinde aykırı değer analizi yapılacak.
cat("\n--- Aykırı Değer Analizi (IQR) ---\n")
##
## --- Aykırı Değer Analizi (IQR) ---
# Aykırı değer analizi için başlık yazdırılıyor.
for(col in numeric_cols) {
# Sayısal her sütun için döngü başlatılıyor.
Q1 <- quantile(df[[col]], 0.25)
# Birinci çeyrek değeri yani %25'lik dilim hesaplanıyor.
Q3 <- quantile(df[[col]], 0.75)
# Üçüncü çeyrek değeri yani %75'lik dilim hesaplanıyor.
IQR <- Q3 - Q1
# Çeyrekler arası açıklık IQR hesaplanıyor. Bu değer aykırı değer tespitinde kullanılır.
lower <- Q1 - 1.5 * IQR
# Alt sınır hesaplanıyor. Bu sınırın altındaki değerler aykırı kabul edilir.
upper <- Q3 + 1.5 * IQR
# Üst sınır hesaplanıyor. Bu sınırın üstündeki değerler aykırı kabul edilir.
outliers <- df[[col]][df[[col]] < lower | df[[col]] > upper]
# Alt veya üst sınırın dışında kalan değerler outliers vektörüne atanıyor.
cat(col, ":", length(outliers), "adet aykırı değer bulundu.\n")
# Her değişken için bulunan aykırı değer sayısı ekrana yazdırılıyor.
}
## age : 0 adet aykırı değer bulundu.
## bmi : 9 adet aykırı değer bulundu.
## children : 0 adet aykırı değer bulundu.
## charges : 139 adet aykırı değer bulundu.
df <- df %>%
mutate(
sex_encoded = ifelse(sex == "male", 1, 0),
smoker_encoded = ifelse(smoker == "yes", 1, 0)
)
# sex değişkeni için male ise 1, female ise 0 değeri atanıyor. smoker değişkeni için yes ise 1, no ise 0 değeri atanıyor. Bu işlem binary encoding olarak bilinir.
df <- dummy_cols(df, select_columns = "region", remove_first_dummy = TRUE)
# region değişkeni için one-hot encoding yapılıyor. remove_first_dummy parametresi ile ilk dummy değişken çıkarılarak çoklu bağıntı probleminden kaçınılıyor.
names(df) <- make.names(names(df))
# Sütun isimlerindeki boşluk, tire gibi karakterler R'ın kurallarına uygun hale getiriliyor.
selected_cols <- c("age", "bmi", "children", "charges", "sex_encoded", "smoker_encoded")
# Korelasyon analizi için kullanılacak sayısal sütunlar seçiliyor.
cor_matrix <- cor(df[, selected_cols])
# Seçilen sütunlar arasındaki korelasyon matrisi hesaplanıyor.
corrplot(cor_matrix, method = "color", type = "upper",
addCoef.col = "black", tl.col = "black", title = "Korelasyon Matrisi")
# Korelasyon matrisi renkli bir ısı haritası şeklinde görselleştiriliyor. Sadece üst üçgen gösteriliyor ve korelasyon katsayıları siyah yazı ile ekleniyor.
ggplot(df, aes(x = smoker, y = charges, fill = smoker)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Sigara Kullanımına Göre Maliyet Dağılımı")
# Sigara kullanan ve kullanmayan kişilerin sigorta maliyetlerinin dağılımı kutu grafiği ile görselleştiriliyor.
df$sex <- as.factor(df$sex)
# sex değişkeni faktör tipine dönüştürülüyor. Bu kategorik değişkenlerin modelde doğru işlenmesini sağlar.
df$smoker <- as.factor(df$smoker)
# smoker değişkeni faktör tipine dönüştürülüyor.
df$region <- as.factor(df$region)
# region değişkeni faktör tipine dönüştürülüyor.
set.seed(145)
# Rastgele sayı üreteci için tohum değeri belirleniyor. Bu sonuçların tekrarlanabilir olmasını sağlar.
sampleindx <- sample(1:nrow(df), size = 0.80 * nrow(df))
# Veri setinin satır numaralarından rastgele %80'i seçiliyor. Bu indeksler train seti için kullanılacak.
trainset <- df[sampleindx, ]
# Seçilen indekslerdeki satırlar train setine atanıyor.
testset <- df[-sampleindx, ]
# Seçilmeyen indekslerdeki satırlar test setine atanıyor.
cat("Train Set Boyutu:", nrow(trainset), "\n")
## Train Set Boyutu: 1070
# Train setindeki satır sayısı ekrana yazdırılıyor.
cat("Test Set Boyutu :", nrow(testset), "\n")
## Test Set Boyutu : 268
# Test setindeki satır sayısı ekrana yazdırılıyor.
model1 <- lm(charges ~ age + bmi + children + sex + smoker + region, data = trainset)
# Lineer regresyon modeli oluşturuluyor. charges bağımlı değişken, diğerleri bağımsız değişkenler olarak kullanılıyor.
summary(model1)
##
## Call:
## lm(formula = charges ~ age + bmi + children + sex + smoker +
## region, data = trainset)
##
## Residuals:
## Min 1Q Median 3Q Max
## -11042.9 -2762.4 -847.2 1332.2 25944.7
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -12392.959 1057.582 -11.718 < 2e-16 ***
## age 263.996 12.802 20.622 < 2e-16 ***
## bmi 331.190 30.483 10.865 < 2e-16 ***
## children 469.982 149.108 3.152 0.00167 **
## sexmale -75.009 357.784 -0.210 0.83398
## smokeryes 23748.810 448.020 53.008 < 2e-16 ***
## regionnorthwest 9.984 507.536 0.020 0.98431
## regionsoutheast -645.795 510.743 -1.264 0.20636
## regionsouthwest -551.467 513.830 -1.073 0.28340
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5832 on 1061 degrees of freedom
## Multiple R-squared: 0.7642, Adjusted R-squared: 0.7624
## F-statistic: 429.9 on 8 and 1061 DF, p-value: < 2.2e-16
# Model özeti ekrana yazdırılıyor. Katsayılar, p-değerleri, R-kare değeri gibi istatistikler görülebilir.
cat("\n--- VIF Değerleri ---\n")
##
## --- VIF Değerleri ---
# VIF analizi için başlık yazdırılıyor.
vif_values <- vif(model1)
# Her bağımsız değişken için VIF değerleri hesaplanıyor. VIF değeri yüksek olan değişkenler çoklu bağıntı problemi yaşıyor demektir.
print(vif_values)
## GVIF Df GVIF^(1/(2*Df))
## age 1.017100 1 1.008514
## bmi 1.097589 1 1.047659
## children 1.004480 1 1.002237
## sex 1.006471 1 1.003230
## smoker 1.010381 1 1.005177
## region 1.092154 3 1.014800
# VIF değerleri ekrana yazdırılıyor.
if(any(vif_values > 5)) cat("UYARI: 5'ten büyük VIF değeri var!\n") else cat("Multicollinearity sorunu görünmüyor.\n")
## Multicollinearity sorunu görünmüyor.
# Eğer herhangi bir VIF değeri 5'ten büyükse uyarı mesajı, değilse sorun olmadığına dair mesaj yazdırılıyor.
residuals <- residuals(model1)
# Modelin kalıntıları yani gerçek değerler ile tahmin edilen değerler arasındaki farklar hesaplanıyor.
shapiro_res <- shapiro.test(residuals[1:5000])
# Kalıntıların normal dağılıma uyup uymadığını test etmek için Shapiro-Wilk testi yapılıyor. R'da maksimum 5000 gözlem ile sınırlı.
cat("\n--- Shapiro-Wilk Normallik Testi ---\n")
##
## --- Shapiro-Wilk Normallik Testi ---
# Shapiro-Wilk testi için başlık yazdırılıyor.
print(shapiro_res)
##
## Shapiro-Wilk normality test
##
## data: residuals[1:5000]
## W = 0.90372, p-value < 2.2e-16
# Test sonucu ekrana yazdırılıyor. p-değeri 0.05'ten küçükse kalıntılar normal dağılmıyor demektir.
cat("\n--- Breusch-Pagan Testi ---\n")
##
## --- Breusch-Pagan Testi ---
# Breusch-Pagan testi için başlık yazdırılıyor.
print(bptest(model1))
##
## studentized Breusch-Pagan test
##
## data: model1
## BP = 120.92, df = 8, p-value < 2.2e-16
# Hata terimlerinin varyansının sabit olup olmadığını test eden Breusch-Pagan testi yapılıyor. p-değeri küçükse heteroskedastisite var demektir.
cat("\n--- Durbin-Watson Testi ---\n")
##
## --- Durbin-Watson Testi ---
# Durbin-Watson testi için başlık yazdırılıyor.
print(dwtest(model1))
##
## Durbin-Watson test
##
## data: model1
## DW = 1.9543, p-value = 0.2265
## alternative hypothesis: true autocorrelation is greater than 0
# Hata terimleri arasında otokorelasyon olup olmadığını test eden Durbin-Watson testi yapılıyor. Değer 2'ye yakınsa otokorelasyon yok demektir.
par(mfrow = c(2, 2))
# Grafik penceresini 2x2'lik bir ızgaraya bölerek 4 grafiği aynı anda göstermeye hazırlıyor.
plot(model1)
# Modelin varsayım kontrolü için dört standart grafik çizdiriliyor. Residuals vs Fitted, Normal Q-Q, Scale-Location ve Residuals vs Leverage grafikleri oluşur.
par(mfrow = c(1, 1))
# Grafik penceresini tekrar normal tek grafik moduna döndürüyor.
predictions <- predict(model1, newdata = testset)
# Eğitilmiş model kullanılarak test seti üzerinde tahminler yapılıyor.
rmse_val <- sqrt(mean((testset$charges - predictions)^2))
# Root Mean Squared Error hesaplanıyor. Tahmin hatalarının ortalama büyüklüğünü gösterir.
mae_val <- mean(abs(testset$charges - predictions))
# Mean Absolute Error hesaplanıyor. Tahmin hatalarının mutlak değerlerinin ortalamasıdır.
r2_val <- summary(lm(predictions ~ testset$charges))$r.squared
# Test seti için R-kare değeri hesaplanıyor. Modelin açıklama gücünü gösterir.
cat("\n--- Test Seti Performansı ---\n")
##
## --- Test Seti Performansı ---
# Test seti performans metrikleri için başlık yazdırılıyor.
cat("RMSE:", round(rmse_val, 2), "\n")
## RMSE: 6918.29
# RMSE değeri yuvarlanarak ekrana yazdırılıyor.
cat("MAE :", round(mae_val, 2), "\n")
## MAE : 4691.27
# MAE değeri yuvarlanarak ekrana yazdırılıyor.
cat("R² :", round(r2_val, 4), "\n")
## R² : 0.7036
# R-kare değeri yuvarlanarak ekrana yazdırılıyor.