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

LEOHUNTERA

Üye
31 Ara 2018
79
3

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:
[COLOR="Orange"]Outlook,     Temperature,  Humidity,  Windy,   PlayTennis[/COLOR]
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:
[COLOR="Orange"]Outlook:           [/COLOR]Havanın Görünümü [COLOR="Orange"](Sunny=Yağmurlu, Overcast=Bulutlu, Rainy=Yağışlı)[/COLOR]
[COLOR="Orange"]Temperature:  [/COLOR]Sıcaklık                        [COLOR="Orange"](Hot=Sıcak,              Mild=Hafif,              Cool=Soğuk)[/COLOR]  
[COLOR="Orange"]Humidity:         [/COLOR]Nem                            [COLOR="Orange"](High=Yüksek,         Normal=Normal)[/COLOR]
[COLOR="Orange"]Windy:              [/COLOR]Rüzgarlı                      [COLOR="Orange"](False=Yanlış,           True=Doğru)[/COLOR]
[COLOR="Orange"]PlayTennis:      [/COLOR]Tenis Oynama           [COLOR="Orange"](No=Hayır,                Yes=Evet)[/COLOR]

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:
[font=monospace][color=#408080][i]#Gerekli kütüphaneler içe aktarılıyor[/i][/color]
[color=#008000][b]import[/b][/color] [color=#0000FF][b]sys[/b][/color]
[color=#008000][b]import[/b][/color] [color=#0000FF][b]pandas[/b][/color] [color=#008000][b]as[/b][/color] [color=#0000FF][b]pd[/b][/color]
[color=#008000][b]import[/b][/color] [color=#0000FF][b]math[/b][/color]
[color=#008000][b]import[/b][/color] [color=#0000FF][b]os[/b][/color]

[color=#408080][i]#Eğitim için kullanılacak olan dosya pandas kütüphanesi ile yükleniyor[/i][/color]
[color=#008000][b]def[/b][/color] [color=#0000FF]load_file[/color]([color=#008000]file[/color]):
    dataset [color=#666666]=[/color] pd[color=#666666].[/color]read_csv([color=#008000]file[/color])
    [color=#008000][b]return[/b][/color] dataset

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

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

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

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

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

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

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

[color=#008000][b]if[/b][/color] [color=#19177C]__name__[/color] [color=#666666]==[/color] [color=#BA2121]"__main__"[/color]:
    main()
[/font]


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

Kod:
[COLOR="Orange"]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[/COLOR]

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.


 
Son düzenleme:
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.