Komputationell Intelligens VT02 Laboration 2 : Interface See5-Matlab Handledare: Thomas Hellström David Arnoldsson, c98dan Andreas Danielsson, c98adn ÅTKOMST OCH ANVÄNDARHANDLEDNING 3 PROBLEMSPECIFIKATION 3 SYSTEMBESKRIVNING 3 buildSee5 3 constructSee5Data 3 evalSee5 4 findSee5Class 4 getSee5Class 4 getSuffix 4 partFile 4 splitFile 4 useTree 5 PROBLEM OCH REFLEKTIONER 5 EXEMPEL PÅ ANROPSFLÖDE BILAGA 1 Åtkomst och användarhandledning Filerna finns att hämta i katalogen ~c98adn/edu/ki/lab2/ De relevanta filerna är de som har ändelsen ”.m” och programmet ”classify.exe”. Classify.exe skall ligga i samma katalog som ”.m” filerna eller på något annat sätt finnas med i matlabs path. Eftersom detta är ett interface mellan matlab och see5 så krävs att båda dessa program finns installerade. Vidare så krävs det att det är windows/dos baserade versioner för båda programmen. Sökvägen till see5 anges i buildSee5Tree.m och är för närvarande satt till ”//Dante/See5/” Användarhandledning för respektive kommando fås genom att skriva help ”kommando” i matlab. Problemspecifikation Vår uppgift var att implementera ett interface mellan See5 och Matlab. Enligt den specifikation vi fick så skulle man ”från Matlab, kunna anropa en rutin med data som inparametrar, och få tillbaka en datastruktur som man kan använda för att anropa en annan rutin som beräknar klassificeringen för nya datapunkter i det beslutsträd som See5 beräknat”. Systembeskrivning buildSee5 Skickar data till See5 som bygger upp ett beslutsträd som returneras som en kolumnvektor av ascii-kod. BUILDSEE5TREE(”file1”, ”file2”) där båda argumenten är strängar Försöker öppna filerna file1 och file2. Skickar dem till See5 ifall de existerar. BUILDSEE5TREE(”file1”, procent, ”file2”) där file1, file2 är strängar och procent är ett positivt tal Försöker öppna filerna file1 och file2. Skickar därefter de ”procent” % första posterna i file.data till See5 ifall filerna existerar. BUILDSEE5TREE(”file1”, start, stop, ”file2”) där file1, file2 är strängar och start, stop är positiva tal Försöker öppna filerna file1 och file2. Skickar därefter raderna fr.o.m start t.o.m. stop i file1 till See5 ifall filerna existerar. constructSee5Data Skapar See5-datafiler från Matlab data. Exakt vilka filer beror på inparametrarna, se nedan. CONSTRUCTSEE5DATA(”newfile”, ”matfile”), där newfile och matfile är strängar newfile ska vara filstammen till de nya filerna som kommer att skapas och matfile ska vara filnamnet på en .mat fil som innehåller de två vektorerna features och targets. features ska innehålla datapunkternas attribut. Dessa attribut måste dock vara reella tal. targets ska innehålla datapunkternas klasser. Från dessa vektorer så kommer filerana newfile.data och newfile.names att generaras, som kan användas av see5. CONSTRUCTSEE5DATA(”newfile”, features) där newfile är en sträng och features är en NxM matris En newfile.cases kommer att genereras från features-matrisen. Dock så behövs en motsvarande .names fil innan filen kan användas i See5. CONSTRUCTSEE5DATA(”newfile”, features, targets), där targets är en 1xM vektor features ska innehålla datapunkternas attribut. Dessa attribut måste dock vara reella tal. targets ska innehålla datapunkternas klasser. Från dessa vektorer så kommer filerana newfile.data och newfile.names att generaras, som kan användas av see5. evalSee5 Kontrollerar kvalitén på ett beslutsträd som är genererat av buildSee5 och returnerar reellt tal som representerar felgraden. EVALSEE5TREE(tree, ”evalfile”, ”namesfile”), där tree är ett beslutsträd och evalfile, namesfile är strängar evalfile representerar en fil som innehåller data i See5 format. Filen evalfile måste innehåller datapunkternas sanna klassificering eftersom dessa används som facit för att räkna ut fleprocenten. namesfile representerar en fil som är på See5:s .names format och innehåller information om strukturen på evalfile. findSee5Class Returnerar vilken av posterna i en See5 .names fil som representerar klassen och returnerar resultatet som ett heltal. Detta heltal motsvarar i vilken av datafilens kolumner som klassificeringen finns. FINDSEE5CLASS(”names”) där names är en sträng Försöker öppna filen ”names” och antar att den är en fil med See5’s name-file format. getSee5Class Returnerar en Nx1 cell-array som innehåller klassificeringarna i datafilen. GETSEE5CLASS(columnNr, ”data”) där columnNr är ett heltal och data är en sträng data ska vara en sträng som representerar en See5-datafil (*.cases, *.data, *.test). getSuffix Returnerar den del av en sträng som är efter den sista avskiljaren. SUFFIX(string, delimeter), där string är en sträng och delimiter är en char Kollar igenom strängen string bakifrån och returnerar den del av strängen som finns bakom tecknet delimeter. Om tecknet delimeter inte påträffas så returneras hela strängen string. partFile Skapar en fil med ett unikt namn som innehåller en del av informationen i inarguments filen och returnerar en sträng som innehåller filens namn.. PARTFILE(”file”, percent) där file är en string och percent är ett reellt tal De första percent% raderna i filen som representeras av strängen file kommer att kopieras till filen temp*.data, där * är ett så kallat jokertecken. PARTFILE(”file”, start, stop), där file är en sträng och start, stop är heltal Raderna fr.o.m. start t.o.m. stop i filen som representeras av file kommer att kopieras till filen temop*.data, där * är ett så kallat jokertecken. splitFile Skapar två filer med ett unika namn som innehåller informationen i inarguments filen och returnerar en sträng som innehåller filernas namn.. SPLITFILE(”file”, percent) där file är en string och percent är ett reellt tal De första percent% raderna i filen som representeras av strängen file kommer att kopieras till filen temp*.data och resten av file kommer att kopieras till temp*.test, där * är ett så kallat jokertecken. SPLITFILE(”file”, start, stop), där file är en sträng och start, stop är heltal Raderna fr.o.m. start t.o.m. stop i filen som representeras av file kommer att kopieras till filen temp*.data och resten av file kommer att kopieras till temp*.test, där * är ett så kallat jokertecken. useTree Används för att testa eller använda ett see5-träd. Returnerar en kolumnvektor med klassificeringar. USETREE(tree, ”file1”, ”file2”) där tree är ett beslutsträd och file1, file2 är strängar Försöker öppna filerna file1 och file2. Skickar dem och beslutsträdet tree till See5 för evaluering.. USETREE (tree, ”file1 , procent, ”file2”) där file1, file2 är strängar och procent är ett positivt tal Försöker öppna filerna file1 och file2. Skickar därefter de ”procent” % första posterna i file.data beslutsträdet tree till See5 för evaluering.. USETREE (tree, ”file1”, start, stop, ”file2”) där file1, file2 är strängar och start, stop är positiva tal Försöker öppna filerna file1 och file2. Skickar därefter raderna fr.o.m start t.o.m. stop i file1 beslutsträdet tree till See5 för evaluering.. Problem och reflektioner Vi har haft otroliga bekymmer på den här laborationen att bestämma oss exakt hur vi skulle gå till väga. Vi har växlat mellan att använda C så mycket som möjligt till att inte använda det alls, vi har växlat mellan att använda filer i stor utsträckning eller att försöka ha all information i arrayer i Matlab. Detta mycket på grund av att vi inte riktigt säkra på hur programmet skulle användas. Vi har inte vetat vad som var tyngdpunkten i laborationen eller vilka krav som ställdes på en färdig lösning. Vi har därför arbetat ut efter en bild av att varje funktion skall vara självständig och en del i en större lösning som användaren själv får sy ihop. Vi har även försökt att få med en mängd olika inpararmetrar till filerna för att ge användaren större valfrihet. Då det enda vi gjort är att programmerat ett interface till en klassificerare är det svårt att överblicka de användningsområden som man kan tänka sig. En stor del av tiden har vi funderat på användningen av temporära filer under körningens gång. Vårt beslut har hamnat på att vi skapar en arbetskopia av den data vi för närvarande arbetar med. Detta därför att See5 helt sonika kan skriva över data utan någon som helst förfrågning om detta var önskvärt. Detta gör att om man arbetar med mycket stora datamängder så kommer det krävas mycket plats för att få plats med den data som kommer att skapas. Problemet har även grundat sig i det faktum att See5 är beroende av att filerna har samma ”förnamn”. Därför har vi gjort så att det skapas temporära filer för att de alla ska ha just samma ”förnamn”. En idé vi hade var att man kan få skicka med en flagga till programmet där man talade om det var önskvärt att skapa temporära filer eller inte. Detta blev dock aldrig implementerat Beslutet att inte använda oss av C bör belysas. Vi började med att sätta oss in i såväl MX/MEX som i dll filer för att skapa bra bindningar mellan programmen. Vi hade den övertygelsen att om vi skulle arbeta med filer på olika sätt så var det bästa sättet att göra det i C. När ett par funktioner implementeras så såg vi dock rätt snart att till 80 % så handlade det koden om felkontroll och konvertering mellan Matlabs och C’s olika datatyper. Det gjordes dubbla kopior på allt. Dessutom så såg vi att de små funktioner vi verkligen skrev gick att göra lika lätt och oftast lättare i Matlab direkt. Detta ledde till beslutet att inte använda oss av C alls då vi inte såg meningen med det. Det gick att göra allt i Matlab direkt. Det är dock ett fall där det i efterhand har visats sig bättre om vi hade gjort det i C. Det är i det fallet vi anropar ett program som vi laddade hem från rulequest hemsida som klassificerar data i .cases filer med hjälp av det träd man specificerar. Det programmet var ”Open Source” vilket gjorde att vi istället kunde ha skrivit om det lite för att på så sätt göra en MEX variant av programmet. Nu anropar vi istället det kompilerade programmet externt. Det är en lösning som gått att göra bättre. Det vi känner att vi lärt oss främst av den här laborationen är inte något som är nära anknytet till KI. Det är istället på systemutvecklingssidan där vi fått ett bra exempel på hur svårt det är att göra något bra med oklara krav och specifikationer. När vi ser tillbaka på det nu så är det framför allt det att vi inte hade klart för oss hur det skulle användas som ställde till problem för oss. Vi har nog skrivit ett par tusen rader kod, men mycket har i sedan tagits bort. Även om det inte finns med funktioner som är skrivna i C så har de skrivits och vi har i och med laborationen lärt oss att använda MEX och MX biblioteket i matlab. Exempel på anropsflöde