Iti0210lab113

Allikas: Lambda
Redaktsioon seisuga 14. aprill 2020, kell 16:28 kasutajalt PriitJ (arutelu | kaastöö)
Mine navigeerimisribale Mine otsikasti

Informatsioon ja ennustatavus

Sissejuhatus

Treeningandmed võivad sisaldada nii kasulikku informatsiooni kui mittevajalikku müra. Paljud masinõppe meetodid, näiteks närvivõrgud, oskavad ise leida andmetest tunnuseid mis on kõige kasulikumad treenitava ülesande lahendamiseks. Siin ülesandes teeme seda käsitsi.

Katsetamiseks on mänguandmestik, "Zoo dataset", kus on 17 tunnust mille alusel loomaaia elanikke klassifitseerida putukateks, lindudeks jne.

Ülesandeks on kirjutada programm, mis leiab iga tunnuse kohta, kui palju ta looma klassi kohta informatsiooni annab, kasutades Shannoni entroopiat.

Teooria: ühe tunnuse entroopia

Tähistame tunnuse väärtuse vi, mingi klassi j ja pj on tõenäosus (selliste treeningnäidete osakaal), et kui tunnuse väärtus on vi, siis asi kuulub klassi j. Selle konkreetse väärtuse nägemisel korral on entroopia:

Tunnuse väärtuse entroopia

Informatsiooniteoorias on kokkulepe, et kui pj = 0 siis pj log pj = 0.

Väärtuste entroopiate pealt leitakse kaalutud keskmine, mis ongi tunnuse entroopia (ni - näidete arv, kus tunnuse väärtus oli vi, n - näidete koguarv).

Tunnuse keskmine entroopia

Ettevalmistus

Andmed võta siit: zoo.data

Faili laadimiseks on mugav kasutada pandas moodulit:

import pandas as pd

features = ["name", "hair", "feathers", "eggs", "milk", "airborne",
    "aquatic", "predator", "toothed", "backbone", "breathes", "venomous",
    "fins", "legs", "tail", "domestic", "catsize"]

zoo_data = pd.read_csv("zoo.data",
    header=None,
    names=features + ["type"])

Tunnused on enamasti 0/1 tüüpi, mõnedel on rohkem võimalikke väärtusi. Viimane veerg failis sisaldab looma klassi ("type"), mida peaks saama eelneva 17 tunnuse põhjal ennustada:

1. animal name: Unique for each instance
2. hair: Boolean
3. feathers: Boolean
4. eggs: Boolean
5. milk: Boolean
6. airborne: Boolean
7. aquatic: Boolean
8. predator: Boolean
9. toothed: Boolean
10. backbone: Boolean
11. breathes: Boolean
12. venomous: Boolean
13. fins: Boolean
14. legs: Numeric (set of values: {0,2,4,5,6,8})
15. tail: Boolean
16. domestic: Boolean
17. catsize: Boolean
18. type: Numeric (integer values in range [1,7])

Andmetega töötamine

Mõned lihtsamad tegevused pandas.DataFrame objektiga:

Valime ühe veeru:

 >>> zoo_data["legs"]

Kui palju on ridu:

 >>> zoo_data["legs"].size()

Ridade arv tüübi kaupa (vt groupby):

 >>> zoo_data.groupby(["legs"]).size()

Näidete arv tüübi ja klassi kaupa:

 >>> zoo_data.groupby(["legs", "type"]).size()

Siin ülesandes võib lihtsam olla, kui ühel hetkel pandas-e agregaatoperatsioonidelt üle minna lihtsale Pythoni tsüklile:

 >>> for key, val in zoo_data.groupby(["legs", "type"]).size().items():
 ...     print(key, val)

Entroopia arvutus

Arvutame entroopia mingi tunnuse jaoks, näiteks "legs".

  1. N = kõigi näidete arv
  2. Ni = näidete arv, kus "legs" väärtus on "i", näiteks 2 või 4
  3. Nij = näidete arv, kus "legs" väärtus on "i" ja klassi ("type") väärtus on j (1-7)
  4. pij = Nij / Ni
  5. Hi = -(pi1log2pi1) - (pi2log2pi2) - ... - (pi7log2pi7)
  6. H = (Ni * Hi)/N summa üle võimalike i väärtuste

Ignoreeri i ja j kombinatsioone, mida ei esine. Mida madalam on H, seda paremini ennustab tunnus klassi väärtust.

Aruanne

Aruandesse pane kirja, mis tunnus on kõige kasulikum, milline annab kõige vähem informatsiooni. Lisaks tee diagramm, kus on iga tunnuse entroopia. Diagrammi ei pea genereerima programmikoodis, võib kasutada ka Excelit, Google Sheetsi vms.