İPUCU

Seçenekler

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

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) %
13-06-2019 04:34
#1
Python ile Yapay Zekâ (Makine Öğrenmesi - Python ile ID3 Algoritmasının Kodlanması) #7

Python ile ID3 Algoritmasının Kodlanması

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

Makine Öğrenmesi Algoritmalarını uygulayabilmek için daha öncede bahsettiğimiz gibi bir veri setine ihtiyaç duymaktayız.

Bu aşamada, zor olmayan basit bir veri seti üzerinde çalışarak bir ortamdaki belirli parametrelere göre, tenis oynayıp oynamama konusunda çıkarımlar yapabileceğimiz bir veri seti üzerinde çalışacağız.

Ne Yapacağız?

Odaklanacağımız asıl konu, bir Makine Öğrenmesi Algoritmasının teorik temellerine hakim olduktan sonraki aşamada, bu algoritmanın nasıl kodlandığı hakkında fikir sahibi olarak, kod yazabilme yeteneğimizi teorik temellerimizle birleştirmektir. Çalışacağımız veri seti, bir otamda belirli bir gün içerisindeki çeşitli parametrelere göre o gün tenis oynanıp oynanmayacağını belirlemeye yönelik bir veri setidir. Kodlayacağımız ID3 Algoritmasına bu veri setini sunarak, elde ettiğimiz sonuçları gözden geçireceğiz.

Veri setimiz şu şekildedir:
Kod:
Outlook,     Temperature,  Humidity,  Windy,   PlayTennis
Sunny,        Hot,                   High,           False,       No
Sunny,        Hot,                   High,           True,        No
Overcast,   Hot,                   High,           False,       Yes
Rainy,         Mild,                  High,           False,       Yes
Rainy,         Cool,                  Normal,     False,       Yes
Rainy,         Cool,                  Normal,     True,         No
Overcast,   Cool,                 Normal,      True,         Yes
Sunny,        Mild,                 High,           False,        No
Sunny,        Cool,                 Normal,     False,        Yes
Rainy,         Mild,                  Normal,      False,        Yes
Sunny,       Mild,                  Normal,      True,          Yes
Overcast,  Mild,                  High,           True,          Yes
Overcast,  Hot,                   Normal,      False,         Yes
Rainy,        Mild,                  High,           True,           No
Şimdi veri setimizin niteliklerine değinelim:

Veri setimiz içerisinde 5 tane nitelik mevcuttur. Bu niteliklerden 4 tanesi sistemimize girdi olarak sağlayacağımız verilerdir. Diğer bir nitelik ise bu 4 tane girdinin analiz edilmesi sonucunda elde edilmesini istediğimiz verimizdir.

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:
Outlook:           Havanın Görünümü (Sunny=Yağmurlu, Overcast=Bulutlu, Rainy=Yağışlı)
Temperature:  Sıcaklık                        (Hot=Sıcak,              Mild=Hafif,              Cool=Soğuk)  
Humidity:         Nem                            (High=Yüksek,         Normal=Normal)
Windy:              Rüzgarlı                      (False=Yanlış,           True=Doğru)
PlayTennis:      Tenis Oynama           (No=Hayır,                Yes=Evet)
Bir veri setinin hangi niteliklere sahip olabileceğiyle ilgili fikir edinerek, diğer veri setleri üzerine kafa yormanız ve gerçek hayattan örneklerle desteklemeniz, öğrenme ve algılama sürecinizi daha da hızlandıracaktır.

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

Python ile ID3 Algoritmasının Kodlanması

Kod:
#Gerekli kütüphaneler içe aktarılıyor
import sys
import pandas as pd
import math
import os

#Eğitim için kullanılacak olan dosya pandas kütüphanesi ile yükleniyor
def load_file(file):
    dataset = pd.read_csv(file)
    return dataset

#Verilen bir dizinin entropisi hesaplanıyor
def entropy(target):
    ent = 0
    result = {}
    target_n = len(target)
    #Verilen dizi içerisindeki her bir değerin sayısı hesaplanarak,
    #dictionary yapısı ile saklanıyor.
    for target_data in target:
        if target_data in result:
            result[target_data] += 1
        else:
            result[target_data] = 1
    #Shannon entropi formülü ile entropi hesabı yapılıyor
    for label in result.keys():
        p_x = result[label] / target_n
        ent += - p_x * math.log(p_x,2)
    return ent

#Bir niteliğin hesaplanabilmesi için niteliğin alacağı her bir
#değer için entropi hesaplanarak, bu entropilerin ortalaması bulunuyor
def avg_entropy_partitions(partition_data):
    avg_entropy = 0
    total = 0
    for partition in partition_data.values():
        avg_entropy += entropy(partition) * len(partition)
        total += len(partition)
    avg_entropy /= total
    return avg_entropy

#Veri seti içerisindeki niteliklerin değerlerine göre ayrıştırılarak
#diğer veri seti nitelikleriyle ayrıştırılmış olarak geriye döndürülmesi
#sağlanıyor. Her bir niteliğin entropisinin hesaplanabilmesi için
#niteliğin aldığı her bir değer için hesaplama yapılıp, bu sonuçların
#ortalaması alınmalıdır. Dolayısıyla niteliğin değerine göre ayrıştırma yapılmalıdır
def partition(data, attribute, target):
    partition_data = {}
    target_data = {}
    indx = 0
    #Veri seti içerisinde ayrıştırmada kullanılacak niteliğin aynı olan değerleri
    #gruplanıp diğer niteliklerle birleştirilerek ayrıştırma işlemi yapılıyor
    for element in data[attribute]:
        if element in partition_data:
            for attr in data.keys():
                partition_data[element][attr].append(data[attr][indx])
        else:
            partition_data[element] = {}
            for attr in data.keys():
                partition_data[element][attr] = list()
                partition_data[element][attr].append(data[attr][indx])
            target_data[element] = list()
        target_data[element].append(target[indx])
        indx += 1
    #Gruplanan veriler ve bu verilerin ait olduğu hedef değerler(sonuçlar) geriye döndürülüyor
    return partition_data, target_data

#Dizi içerisindeki en çok tekrar eden eleman bulunarak,
#geriye döndürülmektedir
def common_target(target_data):
    most_frequent = 0
    target = target_data[0]
    for data in target_data:
        count_data = target_data.count(data)
        if count_data > most_frequent:
            most_frequent = count_data
            target = data
    return target

#ID3 Algoritması uygulanıyor
def id3(data, target):
    #Sonuçların toplanması için node dict tanımlanıyor
    node = {}
    #data içerisinde nitelik kalmamışsa, en çok tekrar eden değer döndürülüyor
    if len(data) == 0:
        return {'result': common_target(target)}
    max_winnings = None
    max_attribute = None
    max_attribute_data = None
    max_target_data = None
    #Genel entropi hesabı yapılıyor
    general_entropy = entropy(target)
    #Genel entropi 0 sa, yani veri setinin bu dalı için bütün değerler aynıysa
    #bu değer geriye döndürülüyor. Genel entropinin 0 olması demek, hedef
    #nitelik değerlerinin aynı olması demektir. Bu durumda ayrıştırmaya gerek yoktur
    if general_entropy == 0:
        return {'result': common_target(target)}
    #En uygun niteliğin düğüm olarak seçilebilmesi için, her bir niteliğin entropisi hesaplanıyor
    for attribute in data:
        #Her bir nitelik için, bu niteliklerin aldıkları değerlere göre ayrıştırma yapılıyor
        attribute_data, target_data = partition(data, attribute, target)
        #Niteliğin her bir dalı için entropi hesaplanarak, ortalama entropi değeri hesaplanıyor
        avg_entropy = avg_entropy_partitions(target_data)
        #Niteliğin genel sistemin entropisine göre kazanç değeri hesaplanıyor.
        winning = general_entropy - avg_entropy
        #En iyi kazanca sahip olan nitelik seçiliyor
        if max_winnings is None or winning > max_winnings:
            max_winnings = winning
            max_attribute = attribute
            max_attribute_data = attribute_data
            max_target_data = target_data
    node[max_attribute] = {}
    #Düğüm olarak seçilen niteliğin her bir dalı ayrı bir sistem olarak düşünülerek,
    #bu dallar için yeniden ID3 Algoritması uygulanıyor
    for attr_data in max_attribute_data:
        del max_attribute_data[attr_data][max_attribute]
        node[max_attribute][attr_data] = id3(max_attribute_data[attr_data], max_target_data[attr_data])
    return node

#ID3 Algoritmasından elde edilen değerlere göre,
#if-else karar yapısı belirleniyor
def print_decision(dict):
    stack = []
    rules = set()
    def traverse(node,stack,rules):
        if 'result' in node:
            stack.append(' THEN ' + node['result'])
            rules.add(''.join(stack))
            stack.pop()
        else:
            ifnd = ' IF ' if not stack else ' AND '
            stack.append(ifnd + list(node)[0] + ' EQUALS ')
            for subnode_key in node[list(node)[0]]:
                stack.append(str(subnode_key))
                traverse(node[list(node)[0]][subnode_key],stack,rules)
                stack.pop()
            stack.pop()
    traverse(dict, stack, rules)
    print(os.linesep.join(rules))

def main():
    #Komut satırından girilen argümanlar alınıyor
    argv = sys.argv
    #Veri seti yükleniyor
    dataset = load_file(argv[1])
    #Veri seti içerisindeki hedef nitelik işlem kolaylığı
    #için başka bir değişkene atanıyor
    target = dataset[dataset.keys()[-1]]
    #Veri seti içerisindeki hedef nitelik kaldırılıyor
    del dataset[dataset.keys()[-1]]
    #Verilen veri setine göre ID3 Algoritması uygulanıyor
    node = id3(dataset,target)
    #Karar yapısı (if-else) belirleniyor
    print_decision(node)

if __name__ == "__main__":
    main()

Çıktımız şu şekilde olmaktadır:

Kod:
IF Outlook EQUALS Overcast THEN Yes
IF Outlook EQUALS Sunny AND Humidity EQUALS Normal THEN Yes
IF Outlook EQUALS Sunny AND Humidity EQUALS High THEN No
IF Outlook EQUALS Rainy AND Windy EQUALS True THEN No
IF Outlook EQUALS Rainy AND Windy EQUALS False THEN Yes
Gördüğünüz gibi, ilgili veri setimize ID3 algoritmasını uyguladığımızda, yukarıdaki karar yapısını elde ettik. Bu karar yapısından yola çıkarak, yeni gelen verilerimizin niteliklerini oluşturduğumuz matematiksel modelden (karar şeması) geçirirsek sonuca ulaşmış oluruz.


Konu LEOHUNTERA tarafından (13-06-2019 04:35 Saat 04:35 ) değiştirilmiştir.
BufGix, k3~, TuranAlemdar Teşekkür etti.

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ı