Merhabalar.
Bugün; veri odaklı çözümleri ve birçok alanda yer alan çeşitli üstünlüğü ile adından sürekli söz ettiren Python dili ile, örnek bir Keşifçi/Keşifsel Veri Analizi – Exploratory Data Analysis EDA süreci ve basit seviyede bir makine öğrenmesi algoritması uyarlanması çalışması adına bilgi ve notlarımı aktarmaya çalışacağım.
Şimdiden iyi okumalar.
Makalede Neler Var ?
Çalışma/İnceleme Süreci
Gerçekleştireceğimiz inceleme, analiz ve uygulama sürecinde;
- Veriseti yükleme,
- Veriseti tanıma (Analizi),
- Temel seviye görselleştirmeler,
- Makine öğrenmesi modeli uyarlanması,
- Başarı değerlendirmeleri
konularına değiniyor olacağız.
Veriseti Yükleme
İncelemede bulunacağımız veriseti; orijinal olarak Ulusal Diyabet ve Sindirim ve Böbrek Hastalıkları Enstitüsü‘nden alınmıştır.Veri kümesinin amacı; veri kümesinde yer alan belirli tanısal ölçümlere dayanarak, bir hastanın diyabet hastası olup olmadığını tanısal olarak tahmin etmektir.
Veri kümesi; çeşitli tıbbi öngörücü değişkenlerden ve bir hedef değişkenden (Sonuç) oluşmaktadır.Belirleyici değişkenler arasında; hastanın sahip olduğu gebelik sayısı, vücut kitle indeksi, insülin düzeyi, yaşı vb. parametrik bilgiler yer almaktadır.
Veriseti Tanıma ve Temel Analiz Görselleştirmeleri
Çalışmamızda kullanacağımız ilgili verisetini;
https://www.kaggle.com/datasets/uciml/pima-indians-diabetes-database
bağlantısı üzerinden .csv formatında, yada;
https://github.com/miracozturk17/basic-python-data-analysis
bağlantısı üzerinden .txt formatında indirebilirsiniz.
***
Gerekli veriseti edinme işlemleri ardından temel seviyede incelemelerimize başlayabiliriz
Öncelikle çeşitli veri analizi ve manipülasyon işlemleri için pandas kütüphanesini çalışmamıza dahil edelim;
# Veri analizi ve manipulasyon islemleri icin pandas kutuphanesini ekledik.
import pandas as pd
Ardından verisetimizi hızlıca çalışmamıza ekleyelim;
# Raw String Notasyonu ile dosyaya ulastik.
data = pd.read_csv(r'C:\Users\user\Documents\GitHub\basic-python-data-analysis\diabetes-dataset.txt', delimiter='\t', header=None)
dilerseniz ek farklı notasyonlar ile de kullanımda bulunabilirsiniz;
#Ters Egik Cizgi notasyonu;
data = pd.read_csv('C:\\Users\\user\\OneDrive\\Belgeler\\Zoom\\veri-seti.txt', delimiter='\t', header=None)
#Ileri Egik Cizgi notasyonu;
#data = pd.read_csv('C:/Users/user/OneDrive/Belgeler/Zoom/veri-seti.txt', delimiter='\t', header=None)
İlk adım olarak; .txt formatında yüklemiş olduğumuz verisetimize sütun adları ekleyelim;
# Sutunlari yeniden adlandirdik.
data.columns = [
'n_times_pregnant', # Number of Times Pregnant - Gebe Kalma Sayisi
'p_g_concentration', # Plasma glucose Concentration - Plazma Glikoz Konsantrasyonu
'd_b_pressure', # Diastolic Blood Pressure - Diyastoli Kan Basinci
't_s_thickness', # Triceps Skinfold Thickness - Triseps Deri Kivrim Kalinligi
's_insulin', # 2-Hour Serum Insulin - 2 Saatlik Serum Insulini
'b_m_index', # Body Mass Index - Vucut Kitle Indeksi
'd_p_function', # Diabetes Pedigree Function - Diyabet Soyagaci Islevi
'age', # Age - Yas
'c_variable' # Class Variable - Sinif Degiskeni
]
Düzenlemiş olduğumuz verisetimizi önizleyelim;
# Veri onizlemesinde bulunduk.
data
Dilerseniz ilk 5 satır içinde önizlemede bulunabilirsiniz;
# Ilk 5 satir uzerinden veri kontrolunde bulunduk.
data.head(5)
Verisetimizin yapısal özelliklerine yönelik kontrolde bulunalım;
# Verisetimizin ozet bilgilerine yonelik kontrolde bulunduk.
data.info()
Burada, mevcut verisetimizin;
- Alan sayısı,
- Alan adları,
- Alan veri kalitesi,
- Alan veritipi,
- Özet veritipi sayısı,
- Hafıza kullanım boyutu
gibi özellikler paylaşılmaktadır.
Yanı sıra, verimiz üzerinde Boş – NULL alanların kontrolünde bulunalım;
# Verisetimiz uzerinde; NULL degerlerin kontrolunde bulunduk.
data.isnull().sum()
n_times_pregnant 0
p_g_concentration 0
d_b_pressure 0
t_s_thickness 0
s_insulin 0
b_m_index 0
d_p_function 0
age 0
c_variable 0
dtype: int64
Verisetimizin istatistiksel özelliklerine yönelik kontrolde bulunalım;
# Verisetimize yonelik istatistiksel ozet bilgilerin kontrolunde bulunduk.
data.describe().T
Burada, mevcut verisetimize yönelik;
- Toplam veri sayisi, (Satır bazlı.)
- Alanların ortalaması,
- Alanların standart sapması,
- Alanların minumum değeri,
- Alanların maksimum değeri
ve,
- %25 (Birinci Çeyrek, veya Q1): Bu değer, verilerin altından yukarıya doğru sıralandığında ilk %25’lik dilimi temsil eder.Yani; tüm verilerin %25’i bu değerden daha küçük veya buna eşittir.
- %50 (Medyan, veya Q2): Medyan, verilerin orta noktasını temsil eder.Veriler küçükten büyüğe sıralandığında, medyan verilerin tam ortasında yer alır.Tüm verilerin yarısı bu değerden daha küçük veya buna eşittir.
- %75 (Üçüncü Çeyrek, veya Q3): Bu değer, verilerin altından yukarıya doğru sıralandığında ilk %75’lik dilimi temsil eder.Yani; tüm verilerin %75’i bu değerden daha küçük veya buna eşittir.
Yanı sıra; bu yüzdelikler, veri dağılımını ve dağılımdaki potansiyel eşitsizlikleri anlamada önemli rol oynar.
Örneğin; medyan ve ortalamayı karşılaştırmak, verilerin ne kadar simetrik dağıldığını gösterir; birinci ve üçüncü çeyrekler arasındaki fark (interquartile range, IQR) ise verilerin ne kadar yayıldığını anlamamıza yardımcı olur.
Özet olarak, verilerimizi temel düzeyde inceleme adına Histogram grafiğinde görselleştirelim;
# Verilerimizi temel duzeyde incelemek için histogram olarak gorsellestirdik.
data.hist(figsize = (10,10))
Görselleştirmelerimizi biraz daha detaylı ve kesitirimde bulunabileceğimiz şekilde yorumlama adına farklı bir boyuta taşıyalım.
Bunun için çalışmamıza matplotlib kütüphanesini dahil edelim;
# Temel veri gorsellestirme islemleri icin matplotlib kutuphanesini ekledik.
import matplotlib.pyplot as plt
Öncelikle temel parametremiz ve yorumlamada önemli rol oynayan age – yaş alanı üzerine biraz incelemede bulunalım;
# Verisetimiz uzerindeki age / yas dagilimina yonelik ornek bir gorsellestirme ile incelemede bulunduk.
# age sutunu icin istatistikler belirledik.
mean_age = data['age'].mean()
min_age = data['age'].min()
max_age = data['age'].max()
# Yas dagilimi histogrami olusturduk.
plt.figure(figsize=(10, 5))
plt.hist(data['age'], bins=20, color='blue', alpha=0.7)
# Ortalama yasi gssteren bir dikey cizgi ekledik.
plt.axvline(mean_age, color='black', linestyle='dashed', linewidth=2)
plt.text(mean_age + 1, 5, f'Ortalama Yas: {mean_age:.2f}', rotation=0, color='white')
# Minimum yasi gosteren bir dikey cizgi ekledik.
plt.axvline(min_age, color='black', linestyle='dashed', linewidth=2)
plt.text(min_age + 1, 5, f'Min Yas: {min_age}', rotation=0, color='white')
# Maksimum yasi gosteren bir dikey cizgi ekledik.
plt.axvline(max_age, color='black', linestyle='dashed', linewidth=2)
plt.text(max_age + 1, 5, f'Max Yas: {max_age}', rotation=0, color='black')
# Grafik basligi ve etiketleri duzenledik.
plt.title('Yas Dagilimi Histogrami')
plt.xlabel('Yas')
plt.ylabel('Frekans')
plt.grid(True)
plt.show()
Çıktımız;
şeklindedir.
Burada yaş dağılımındaki yoğunluk ve minimum, ortalama ve maksimum üzerine yorumlamada bulunmaya çalıştık.
Şimdi ise verisetimiz uzerindeki, b_m_index / vucut kitle indeksi ve p_g_concentration / plazma glikoz konsantrasyonuna yönelik incelemede bulunalım;
*VKİ değerine yönelik diğer alanlarda gözden geçirilebilir.İlişkisel bağı yüksek bir alan.
# Verisetimiz uzerindeki b_m_index / vucut kitle indeksi ve p_g_concentration / plazma glikoz konsantrasyonuna yonelik ornek bir karsilastirma ile incelemede bulunduk.
bmi = data['b_m_index']
glucose = data['p_g_concentration']
# b_m_index sutunu icin istatistikler belirledik.
avg_bmi = bmi.mean()
min_bmi = bmi.min()
max_bmi = bmi.max()
# p_g_concentration sutunu icin istatistikler belirledik.
avg_glucose = glucose.mean()
min_glucose = glucose.min()
max_glucose = glucose.max()
# Karsilastirma icin Sacilim grafigi olusturduk.
plt.figure(figsize=(10, 5))
plt.scatter(bmi, glucose, alpha=0.5, label='BMI vs Glucose')
plt.title('Vucut Kitle Indeksi ve Plazma Glikoz Konsantrasyonu Iliskisi')
plt.xlabel('Vücut Kitle Indeksi')
plt.ylabel('Plazma Glikoz Konsantrasyonu')
# Ortalama degerler icin cizgi ekledik.
plt.axvline(avg_bmi, color='black', linestyle='dashed', linewidth=2, label=f'Ort. BMI: {avg_bmi:.2f}') # Ortalama deger icin siyah cizgi ekledik.
plt.axhline(avg_glucose, color='black', linestyle='dashed', linewidth=2, label=f'Ort. Glukoz: {avg_glucose:.2f}')
# Min ve max degerler icin cizgi ekledik.
plt.axvline(min_bmi, color='darkred', linestyle='dotted', linewidth=3, label=f'Min. BMI: {min_bmi:.3f}') # Min ve Max BMI icin koyu kirmizi cizgi ekledik.
plt.axvline(max_bmi, color='darkred', linestyle='dotted', linewidth=3, label=f'Max. BMI: {max_bmi:.3f}')
plt.axhline(min_glucose, color='darkorange', linestyle='dotted', linewidth=3, label=f'Min. Glukoz: {min_glucose:.2f}') # Min ve Max BMI icin koyu turuncu cizgi ekledik.
plt.axhline(max_glucose, color='darkorange', linestyle='dotted', linewidth=3, label=f'Max. Glukoz: {max_glucose:.2f}')
plt.grid(True)
plt.legend()
plt.show()
Ardından, dağılımı farklı bir boyutta ele alma adına verisetimiz uzerindeki,d_b_pressure / diyastolik kan basincina yönelik incelemede bulunalım;
# Verisetimiz uzerindeki d_b_pressure / diyastolik kan basincina yonelik ornek bir gorsellestirme ile incelemede bulunduk.
blood_pressure = data['d_b_pressure']
# d_b_pressure sutunu icin istatistikler belirledik.
min_bp = blood_pressure.min()
max_bp = blood_pressure.max()
mean_bp = blood_pressure.mean()
# Kutu grafigi olusturduk.
plt.figure(figsize=(8, 6))
plt.boxplot(blood_pressure, notch=True, vert=False, patch_artist=True)
plt.title('Diyastolik Kan Basinci Kutu Grafigi')
plt.xlabel('Diyastolik Kan Basinci (mm Hg)')
# Minimum, maksimum ve ortalama degerleri grafiğe ekledik.
plt.scatter(min_bp, 1, color='red', label=f'Min: {min_bp} mm Hg') # Min deger icin kirmizi nokta ekledik.
plt.scatter(max_bp, 1, color='blue', label=f'Max: {max_bp} mm Hg') # Max deger icin mavi nokta ekledik.
plt.scatter(mean_bp, 1, color='green', label=f'Mean: {mean_bp:.2f} mm Hg') # Ortalama deger icin yesil nokta ekledik.
plt.legend(loc='upper center')
plt.grid(True)
plt.show()
Makine Öğrenmesi Modeli Uyarlanması
Gerçekleştirdiğimiz analiz sonrasında; verisetimize yönelik basit seviyede makine öğrenmesi modeli uyarlaması ve başarı analizinde bulunalım.
Öncelikle model seçimi ve değerlendirmeleri adına sklearn kütüphanesini çalışmamıza dahil edelim;
# Model secimi ve degerlendirmeleri icin sklearn.model_selection kutuphanesini ekledik.
from sklearn.model_selection import train_test_split
Şimdi ise verisetimizi bagimsiz değişken ve hedef değişken olarak planlayalım;
# Ozellikler (X) ve Hedef (y) degiskenlerini ayirdik.
#Bagimsiz degiskenler ve hedef degisken olarak.
X = data.drop('c_variable', axis=1)
y = data['c_variable']
Ardından, verisetimizi %30 oranında test veriseti olarak ayıralım;
# Veri setini; egitim ve test verisetlerine ayirdik.
# test_size=0.3 argumani; veri setimizin %30'unun test seti olarak ayrılmasi icin kullandik.
# Geri kalan %70; egitim seti olarak kullanildi.
# random_state=42 argumani; islemi tekrarlanabilir kilmak için bir rastgelelik saglamasi için kullanildi.
# Bu; kodu her calistirdigimizda ayni sonucu almamizi sagladi.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
Sonrasında ise ölçek birliği, algoritma performansı, sayısal kararlılık adına verisetimizi normalize etmemiz gerekmektedir.
Bunun için çalışmamıza sklearn.preprocessing kütüphanesini dahil edelim;
# Normalizasyon yontemlerinden Min-Max normalizasyonu tercih edildi.
# Min-Max normalizasyonu icin sklearn.preprocessing kutuphanesini ekledik.
from sklearn.preprocessing import MinMaxScaler
Normalizasyon uygulanması için tanımlamada bulunalım;
# Min-Max normalizasyonu tanimladik.
scaler = MinMaxScaler()
Normalizasyon uygulamasından sonra eğitim verisi üzerinde ölçekleyiciyi eğiterek, ölçeklendirilmiş eğitim verisi elde edelim;
# Egitim verisi uzerinde olcekleyici egitilerek; olceklendirilmis egitim verisi elde edildi.
X_train_scaled = scaler.fit_transform(X_train)
Ardından ölçekleyiciyi test verisi üzerinde uygulayalım;
# Olcekleyici; test verisi üzerinde uygulandi.
X_test_scaled = scaler.transform(X_test)
Şimdi ise; verisetimiz üzerinde örnek bir algoritma belirleyerek, uygulayalım.
Buradaki tercihimizi; popülerliği yüksek ve uygulanabilirliği kolay olan Decision Tree – Karar Ağaçları yönünde kullanalım.
Bunun için sklearn.tree model kütüphanesini çalışmamıza dahil edelim;
# Karar Agaclari kullanimi icin sklearn.tree kutuphanesini ekledik.
from sklearn.tree import DecisionTreeClassifier
Ardından karar ağacı sınıflandırıcısını, aynı sonucu alabileceğimiz şekilde tanımlayalım;
# Karar Agaci siniflandiricisi tanimladik.
# random_state=42 argumani; islemi tekrarlanabilir kilmak icin bir rastgelelik saglamasi icin kullanildi.
# Bu; kodu her calistirdigimizda ayni sonucu almamizi sagladi.
dt_classifier = DecisionTreeClassifier(random_state=42)
Sonrasında modelimizi, ölçeklendirilmiş veriseti üzerinde eğitelim;
# Olceklendirilmis egitim verisi uzerinde modelimizi egittik.
dt_classifier.fit(X_train_scaled, y_train)
Son olarak ise, tahminlemede bulunalım;
# Olceklendirilmis test verisi uzerinden tahmin yaptik.
y_pred_dt = dt_classifier.predict(X_test_scaled)
Genel olarak verisetimizi normalize edip; basit bir seviyede makine öğrenmesi modeli uygulayarak, tahminlemede bulunduk.
Şimdi sonuç ve performans üzerine kısaca işlemlerde bulunalım.
Başarı Değerlendirmeleri
Gerçekleştirdiğimiz veri analizi ve model uygulamasına yönelik kısa sonuç değerlendirmelerinde bulunalım.
Öncelikle karar ağacı modelimizin doğruluk değerinden başlayalım.
Bunun için değerlendirme adına sklearn.metrics kütüphanesini çalışmamıza dahil edelim;
# Tahminlerin dogrulugunun kontrolu icin sklearn.metrics kutuphanesini ekledik.
from sklearn.metrics import recall_score, accuracy_score, precision_score, confusion_matrix, f1_score
Sonrasında ise skorumuzu görüntüleyelim;
# Tahminimizin dogrulugunu hesapladik.
accuracy_dt = accuracy_score(y_test, y_pred_dt)
# Tahminimizin dogrulugunu yazdirdik.
print(f'Karar Agaci Dogrulugu: {accuracy_dt}')
Karar Agaci Dogrulugu: 0.7012987012987013
Yanı sıra ek performans metriklerine de göz atalım;
# Performans ve raporlama metriklerini hesapladik.
# Confusion Matrix
conf_matrix = confusion_matrix(y_test, y_pred_dt)
# Accuracy Score
accuracy_score = accuracy_score(y_test, y_pred_dt)
# Precision Score
precision_score = precision_score(y_test, y_pred_dt)
# Recall Score
recall_score = recall_score(y_test, y_pred_dt)
# F1 Score
f1_score = f1_score(y_test, y_pred_dt)
ve bunları çıktı olarak yazdıralım;
# Performans ve raporlama metriklerini yazdirdik.
print("Karar Agaci Model Performans Metrikleri\n")
print("Konfuzyon Matrisi\n", conf_matrix)
print("\nDogruluk (Accuracy)\n", accuracy_score)
print("\nHassasiyet (Precision)\n", precision_score)
print("\nDuyarlilik (Recall)\n", recall_score)
print("\nF1 Skoru\n", f1_score)
Karar Agaci Model Performans Metrikleri
Konfuzyon Matrisi
[[107 44]
[ 25 55]]
Dogruluk (Accuracy)
0.7012987012987013
Hassasiyet (Precision)
0.5555555555555556
Duyarlilik (Recall)
0.6875
F1 Skoru
0.6145251396648045
Ek olarak, karar ağacımızın yapısını görsel olarak ele alalım.
Bunun için değerlendirme adına graphviz kütüphanesini çalışmamıza dahil edelim;
# Modeli gorsellestirmek icin sklearn.tree ve graphviz kutuphanelerini ekledik.
from sklearn.tree import export_graphviz
import graphviz
Çıktı karşılığı ise;
# Karar agacinin grafigini cizdirdik.
# Cikti olarak verdigi icin burada gosteremedik, ek olarak dosyalara ekledik.
dot_data = export_graphviz(dt_classifier, out_file=None, feature_names=X.columns, class_names=['0', '1'], filled=True, rounded=True, special_characters=True)
graph = graphviz.Source(dot_data)
graph.render("decision-tree",directory=r'C:\Users\user\OneDrive\Masaüstü\basic-python-data-analysis',format='pdf')
'C:\\Users\\user\\OneDrive\\Masaüstü\\basic-python-data-analysis\\decision-tree.pdf'
şeklindedir.
Okunabilir görsele;
https://github.com/miracozturk17/basic-python-data-analysis/blob/main/decision-tree.pdf
bağlantısı altından ulaşabilirsiniz.
Çalışmanın kaynak kodlarına ise;
https://github.com/miracozturk17/basic-python-data-analysis
bağlantısından ulaşabilirsiniz.
Buraya kadar, genel olarak; bir verisetini tanıma, analiz etme, basit seviyede bir model uyarlama ve uygulama, son olarak ise çıktıları ve performansı analiz etme adına işlemlerde bulunduk.
Umarım faydalı olur.
İyi çalışmalar.