İPUCU

Seçenekler

Python ile Yapay Zekâ (Makine Öğrenmesi - Python ile KNN Algoritmasının Kodlanması) #5

LEOHUNTERA - ait Kullanıcı Resmi (Avatar)
Yazılımcı
Üyelik tarihi:
12/2018
Mesajlar:
72
Konular:
12
Teşekkür (Etti):
68
Teşekkür (Aldı):
100
Ticaret:
(0) %
17-04-2019 01:47
#1
Python ile Yapay Zekâ (Makine Öğrenmesi - Python ile KNN Algoritmasının Kodlanması) #5
Python ile KNN Algoritmasının Kodlanması

Bu konumuz da, Makine Öğrenmesi Algoritmalarından olan KNN Algoritmasının, Python dili ile kodlanması işlemini gerçekleştireceğiz. Eğer KNN Algoritmasının teorik temellerine hâkim değilseniz, buradan KNN Algoritmasının teorik temellerini anlattığımız konuya giderek inceleme yaptıktan sonra kodlama aşamasına dönebilirsiniz.

Makine Öğrenmesi Algoritmalarını gerçekleştirebilmek için daha öncede bahsettiğimiz gibi, bir veri setine ihtiyaç duymaktayız.

Ne Yapacağız?

KNN Algoritmasını kodlama aşamasında, çalışacağımız proje çeşitli belirtilere göre, bir kişinin kalp hastası olup olmadığının belirlenmesine yöneliktir. Daha da açıklayıcı olmak gerekirse, bir kişinin cinsiyeti, yaşı, göğüs bölgesinde ağrı olup olmadığı, kan basıncı gibi verilere bakarak, bu kişinin kalp hastası olup olmadığının belirlenmesidir.

Veri Seti

Kafanızda daha da netleşmesi için Veri setimizin bir kısmı şu şekildedir;

Kod:
age, sex, cp, trestbps, chol, fbs, restecg, thalach, exang, oldpeak, slope, ca, thal, target
63,    1,   3,     145,    233,   1,      0,       150,      0,        2.3,       0,      0,   1,     1
37,    1,   2,     130,    250,   0,      1,       187,      0,        3.5,       0,      0,   2,     1
41,    0,   1,     130,    204,   0,      0,       172,      0,        1.4,       2,      0,   2,     1
56,    1,   1,     120,    236,   0,      1,       178,      0,        0.8,       2,      0,   2,     1
45,    1,   3,     110,    264,   0,      1,       132,      0,        1.2,       1,      0,   3,     0
68,    1,   0,     144,    193,   1,      1,       141,      0,        3.4,       1,      2,   3,     0
57,    1,   0,     130,    131,   0,      1,       115,      1,        1.2,       1,      1,   3,     0
57,    0,   1,     130,    236,   0,      0,       174,      0,        0,          1,      1,   2,     0
Şimdi veri setimizin niteliklerine değinelim;

Veri setimiz içerisinde 14 tane nitelik mevcuttur. Bu niteliklerden 13 tanesi Sistemimize girdi olarak sağlayacağımız verilerdir. Target niteliği ise bu girdilerin analiz edilmesi sonucunda elde edilmesini istediğimiz veridir.

Eğer buraya kadar anlamakta güçlük çekiyorsanız, temel konuları okuduktan sonra, bu konuya dönmelisiniz.

Bu aşamaya kadar her şey yolundaysa hangi niteliğimizin neye karşılık geldiğine göz atalım;
Kod:
age: Yaş
sex: Cinsiyet (1 = Erkek, 0 = Kadın)
cp: Göğüs ağrısı tipi (0,1,2,3)
trestbps: Dinlenme kan basıncı (hastaneye girişte mm Hg cinsinden)
chol: Serum kolestoral mg/dl cinsinden
fbs: (açlık kan şekeri> 120 mg/dl) (1 = doğru; 0 = yanlış)
restecg: Elektrokardiyografik sonuçların dinlenmesi
thalach: Elde edilen maksimum kalp atış hızı
exang: Egzersize bağlı anjin (1 = evet; 0 = hayır)
oldpeak: Dinlenmeye göre egzersiz ile indüklenen ST depresyonu
slope: Tepe egzersizi ST segmentinin eğimi
ca: Floroskopi ile renklendirilmiş ana damarların (0-3) sayısı
thal: 3 = normal; 6 = sabit hata; 7 = tersinir kusur
target: 1 veya 0 (1 = Kalp hastası, 0 = Kalp hastası değil)
Veri setindeki niteliklerin herbirini anlamanıza gerek yok, ben de bazı niteliklerin neye karşılık geldiğini bilmiyorum. En iyisi bu işi Doktorlara bırakmak. Sadece genel olarak bir proje içerisinde veri niteliklerinin nelere karşılık geldiğini anlamaya çalışarak, kafanızda genel bir şema çizin.

Genel olarak veri setimizi ve niteliklerimizi tanıdığımıza ve projemizin nasıl bir proje olacağını kafamızda şekillendirdikten sonra bu bilgilerimizi kullanarak kodlama aşamasına geçelim.

Veri setinin tamamına ve detaylı açıklamalara buradan ulaşabilirsiniz.

Python ile KNN Algoritmasının Kodlanması

Kod:
# Veriyi biçimlendirmek ve bazı belirli hesaplamalar yapabilmek
# için gerekli kütüphaneler içe aktarılıyor.
import pandas as pd
import numpy as np
import math
import operator

# Eğitim verileri ve test için ayrılmış verilerin bulunduğu,
# dosyaların path'leri kullanım kolaylığı olması için değişkene
# aktarılıyor.
egitim_dosya = './heart.csv'
test_dosya = './test.csv'

# KNN Algoritmasının gerçekleştiği ana fonksiyon
# egitim_verileri, içerisinde veri nitelikleri ve target değerleri
# olan eğitim için kullanacağımız verilerdir.
# test_verileri, egitim verileri içerisinden bir kısmını ayırdığımız
# verilerdir. Test verilerine ihtiyaç duymamızın sebebi, Algoritmamızın
# yeni gelen veriler üzerindeki çalışma başarımını ölçmektir.
# gercek_sonuclar ise test için ayırdığımız test_verileri nin gerçekte sahip
# olduğu target değerleridir.


def knn(k, egitim_verileri, test_verileri, gercek_sonuclar):

    test_sonuclar = []  # test için ayırdığımız verilerimizin sonuçlarının
    # ekleneceği dizi

    # test_verileri içerisindeki her bir verinin ait olduğu sınıf bulunuyor...
    for test_veri in test_verileri:
        # sonuc_bul fonksiyonuyla, her bir test_verimizin, eğitim verilerimiz
        # içerisinden en benzer k tanesine göre ait olduğu sınıf bulunuyor.
        # Sınıftan kasıt (target = 0, target = 1) durumudur. (Kalp hastalığı
        # yok, Kalp hastalığı var)
        sonuc = sonuc_bul(test_veri, egitim_verileri, k)
        test_sonuclar.append(sonuc)

    # test verilerimizin Knn Algoritmamızın işlenmesi sonucu elde edilen sonuçlar ile
    # gerçek sonuçlarının karşılaştırılması
    basarim = basarim_hesapla(test_sonuclar, gercek_sonuclar)

    print(f"Başarım Oranı : {basarim}")

# Excel dosyamızdan verilerimiz yükleniyor...


def veri_yukle(path):
    veriler = pd.read_csv(path)
    return veriler

# Yüklenen verileri DataFrame formatından dizi formatına çeviriyoruz.
# Bu fonksiyona gönderilen Heart değeri, target değerinin dahil edilip, edilmeyeceğini
# belirliyor.


def dizi_cevir(DataFrame, Heart):
    dizi = []
    if(Heart):
        for index, satir in DataFrame.iterrows():
                # target niteliği dahil ediliyor...
            dizi_satir = [round(satir[i], 3) for i in range(14)]
            dizi.append(dizi_satir)
    else:
        for index, satir in DataFrame.iterrows():
                # target niteliği dahil edilmiyor, 13. niteliğe kadar olan
                # veriler alınıyor.
            dizi_satir = [round(satir[i], 3) for i in range(13)]
            dizi.append(dizi_satir)
    return dizi

# Veri setimizde başarım hesabını yapabilmek için test verilerinin
# gerçekte olan değerleri alınıyor.


def gercek_sonuc_yukle(path):
    veriler = pd.read_csv(path)
    # sadece target niteliğinin değerleri alınıyor.
    direction_veri = veriler['target'].values
    return direction_veri

# Bir test verisinin bütün eğitim verilerine olan uzaklıkları hesaplanıyor...


def mesafe_bul(test_veri, egitim_verileri):
    komsu_mesafeler = []
    for egitim_veri in egitim_verileri:
        # test verisinin her bir eğitim verisine olan öklid mesafesi bulunuyor.
        mesafe = oklid_hesapla(test_veri, egitim_veri)
        komsu_mesafeler.append((egitim_veri, mesafe))
    return komsu_mesafeler

# Öklid mesafesi hesaplanıyor...


def oklid_hesapla(veri1, veri2):
    uzunluk = len(veri1)
    mesafe = 0
    for i in range(uzunluk):
        mesafe += pow((veri1[i] - veri2[i]), 2)
    return math.sqrt(mesafe)

# En yakın k tane komşu bulunuyor...
# komsular parametresi, eğitim verilerinin nitelik değerlerini
# ve test_verisine olan uzaklığı içeriyor.


def yakin_komsular_bul(komsular, k):
    yakin_komsular = []
    # komsular dizisinin 1. indisinde mesafeler yer aldığı için,
    # mesafelere göre küçükten büyüğe sıralama yapılıyor.
    komsular.sort(key=operator.itemgetter(1))
    for x in range(k):
        # En yakın k tane komşu alınıyor...
        yakin_komsular.append(komsular[x][0])
    return yakin_komsular

# Seçilen en yakın k tane komşunun hangi sınıfa dahil olduğu bulunarak,
# Bu k tane komşu içerisinde en çok hangi sınıf mevcutsa, test Algoritmamıza
# göre hesaplanmış sınıfı da o sınıf oluyor.


def uygun_sonuc(komsular):
    dict = {}
    for komsu in komsular:
        # en yakın k tane komşu içerisindeki her bir komşunun dahil olduğu
        # sınıf komsu[-1] ile bulunarak sayılıyor.
        if(komsu[-1] in dict):
            dict[komsu[-1]] += 1
        else:
            dict[komsu[-1]] = 1

    # dict sözlüğü, test verimize en yakın k tane veri içerisindeki sınıfların sayısıdır.
    # Sınıfların sayısına göre, dict tersten(büyükten küçüğe) sıralanıyor.
    sort = sorted(dict.items(), key=operator.itemgetter(1), reverse=True)
    # En yakın k tane veri içerisinde en çok ait olunan sınıf döndürülüyor...
    return sort[0][0]

# Sonuc_bul fonksiyonuyla test_verisinin, eğitim_verilerine göre uzaklıkları hesaplanarak
# En benzer k tane veriye göre sınıfı bulunuyor.
# Eğitim verilerinin sonuç değerini de içerdiğini unutmayın.
# Eğitim verilerinin dahil olduğu sınıflara göre test_verisinin sınıfı
# belirlenir.


def sonuc_bul(test_veri, egitim_verileri, k):
    komsular = mesafe_bul(test_veri, egitim_verileri)
    yakin_komsular = yakin_komsular_bul(komsular, k)
    sonuc = uygun_sonuc(yakin_komsular)
    return sonuc

# Test verilerimize KNN Algoritmamızın uygulanmasıyla elde edilen sonuçlar ile
# test verilerimizin gerçek değerleri karşılaştırılarak, Algoritmamızın ne oranda
# başarılı çalıştığı hesaplanıyor.


def basarim_hesapla(test, gercek):
    length = len(test)
    basarim = 0
    for i in range(length):
        if(test[i] == gercek[i]):
            basarim += 1

    basarim = (basarim / float(length)) * 100.0

    return basarim

# MAX-MIN normalleştirme işlemi yapılıyor. Veri hazırlama aşamasında
# bu normalleştirme türüne değinmiştik.


def normalization(veri):
    for i in range(len(veri[0])):
        max = veri[0][i]
        min = veri[0][i]
        for j in range(len(veri)):
            if(veri[j][i] > max):
                max = veri[j][i]
            elif(veri[j][i] < min):
                min = veri[j][i]
        for j in range(len(veri)):
            veri[j][i] = (veri[j][i] - min) / (max - min)
    return veri


def main():
    # Test verimiz excel dosyasından yükleniyor...
    test_verileri = veri_yukle(test_dosya)
    # DataFrame olarak elde ettiğimiz verilerimizi
    test_dizi = dizi_cevir(test_verileri, Heart=False)
    # Kolaylıkla işleyebilmek için dizi formatına çeviriyoruz.

    # Eğitim verileri, excel dosyasından yükleniyor...
    egitim_verileri = veri_yukle(egitim_dosya)
    # Verileri kolayca işleyebilmek için dizi formatına çeviriyoruz.
    egitim_dizi = dizi_cevir(egitim_verileri, Heart=True)

    # Eğitim verimizde tutarlılık ve dengeyi sağlayabilmek için normalization
    # uyguluyoruz.
    normalization(egitim_dizi)
    # Test verimizde tutarlılık ve dengeyi sağlayabilmek için normalization
    # uyguluyoruz.
    normalization(test_dizi)

    # Başarım hesabını yapabilmek için test verilerinin gerçek sonuç
    # değerlerini yüklüyoruz.
    gercek_sonuclar = gercek_sonuc_yukle(test_dosya)

    knn(5, egitim_dizi, test_dizi, gercek_sonuclar)
    # eğitim aşamasında kaç tane benzer verinin dikkate alınması gerektiğini
    # k değeri ile belirtiyoruz. k = 5 seçildi. En yakın 5 veri dikkate alınacak.
    # Niteliklerine göre hangi sınıfa dahil olduklarını bulacağımız
    # test_verisi, ve bu verilerin dahil oldukları sınıfları bulmak için benzerlik
    # hesabında kullandığımız egitim_verisi parametre olarak gönderilmektedir.
    # Bu değerlerin yanısıra test_verilerinin Algoritmamıza göre başarımının ölçülmesi
    # için bu verilerin gerçek değerleri gönderilmektedir.


if __name__ == "__main__":
    main()
Sonuç olarak çıktımız şu şekilde olmaktadır;
Kod:
Başarım Oranı : 100.0
Her zaman, başarım oranı %100 çıkmayabilir, burada dikkat edilmesi gereken ve önemli olan nokta hangi veri seti ile neyin çıkarımının yapıldığıdır. Bazı veri setlerinde %80 lik bir başarı kabul edilebilirken, bazılarında kabul görmeyebilir.

Normalleştirme ile ilgili önemli bir konuda bu örnek için bazı niteliklerin sahip oldukları değerlerin aralarındaki fark ve dolayısıyla uzaklıkları fazla iken bazı verilerin uzaklıkları görece az olmaktadır. Bu istenmeyen bir durumdur. Bunun sebebi, KNN Algoritmamızın uzaklığı fazla olan değerleri daha fazla işin içerisine katarak, daha küçük bir aralığa yayılmış verileri görmezden gelmesine neden olabilir. Bunu engellemek için veriler tutarlı bir hâle getirilerek aralıkların büyüklükleri bütün nitelikler için aynı ölçüde olmalıdır. Burada önemli olan görece (aynı nitelikteki verilerin birbirlerine göre uzaklıkları) uzaklıklardır.

Verileri normalleştirmeden Algoritmamızı uygularsak, buradaki çıktımız şu şekilde olmaktadır;
Kod:
Başarım Oranı : 65.04
Gördüğünüz gibi, normalleştirme başarım oranımıza ciddi oranda etki ediyor. Bu bağlamda veri hazırlama aşamasının, Makine Öğrenmesi Sürecinin en önemli aşaması olduğunu söyleyebiliriz. Bu aşamada yapılabilecek herhangi bir tutarsızlık veya dengesizlik, başarımı doğrudan etkileme potansiyeline sahiptir.
Konu LEOHUNTERA tarafından (17-04-2019 02:21 Saat 02:21 ) değiştirilmiştir.

Bookmarks


« Önceki Konu | Sonraki Konu »
Seçenekler

Yetkileriniz
Sizin Yeni Konu Acma Yetkiniz var yok
You may not post replies
Sizin eklenti yükleme yetkiniz yok
You may not edit your posts

BB code is Açık
Smileler Açık
[IMG] Kodları Açık
HTML-Kodları Kapalı
Trackbacks are Kapalı
Pingbacks are Kapalı
Refbacks are Kapalı