Utilizarea Algoritmilor de Clasificare Pentru Imbunatatirea Interactiunii Dintre Profesori Si Studenti
Utilizarea algoritmilor de clasificare pentru îmbunătățirea interacțiunii dintre profesori și studenți
CUPRINSUL
1 Introducere
1.1 Scopul
1.2 Motivația
1.3 Obiective
1.4 Contributii personale
2 Considerente teoretice
2.1 Java
2.1.1 Vectori-Map
2.1.2 Încărcarea claselor în memorie
2.1.3 Reflectarea(eng. Reflection)
2.1.4 Lucrul cu bazele de date
2.1.4.1 Generalități despre baze de date
2.1.4.2 JDBC
2.1.5 Java Swing și AWT
2.1.5.1 GUI.
2.2 XML
2.3 Weka
2.3.1 Generalități
2.4 Clasificare tehnici data mining
2.4.1 Tehnica Bayes.
2.4.1.1 Limitele tehnicii
2.4.1.2 Avantajele tehnicii.
2.4.2 k-NN
2.4.2.1 Limitele tehnicii.
2.4.2.2 Avantajele tehnicii.
2.4.3 Retele neuronale
2.4.3.1 Limitele tehnicii
2.4.3.2 Avantajele tehnicii.
2.4.4 Arbori de decizie
2.4.4.1 Limitele tehnicii.
2.4.4.2 Avantajele tehnicii
2.5 Arbori de decizie
2.6 Complexitatea arborilor de decizie
2.6.1 Complexitatea arborilor de decizie pe mai multe modele de algoritmi
2.6.1.1 Deterministe
2.6.1.2 2.Aleatoare(nedeterministe)
2.6.1.3 3.Cuantice
3 Prezentarea metodei
3.1 Algoritm de incarcare a datelor
3.2 Calculul de outlieri si extreme values
3.3 Calcul succesor si predecesor
3.4 Interfata aplicatiei
4 Experimente și analiza rezultatelor
4.1 Constrangeri
4.2 Incarcarea arborelui
4.3 Calculul de Successori si predecesori
4.4 Detectia de outlieri si valori extreme
4.4.1 Valori extreme
4.4.2 Outliers
5 Termeni de utilizare
5.1 Autorii
5.2 Licența de utilizare
6 Concluzii
7 Bibliografie
LISTA FIGURILOR
Figură 1 Organizarea ClassLoader
Figură 2 JDBC-ODBC Bridge
Figură 3 Driver JDBC nativ
Figură 4 Driver JDBC Server
Figură 5 Driver JDBC nativ
Figură 6 Ierarhia AWT
Figură 7 Ierarhia SWING
Figură 8 Arhitectura generala sistem
Figură 9 Data flow
Figură 10 Calcul Outlieri si Extreme Values
Figură 11 Exemplu successor si predecesor
Figură 12 Exemplu interfata
Figură 13 Exemplu dataset
Figură 14 Exemplu arbore
Figură 15 Date validare arbore
Figură 16 Frunza analizata
Figură 17 Rezultat successori
Figură 18 Rezultat Predecesori directi
Figură 19 Predecesori nivel 2
Figură 20 Valori extreme
Figură 21 Exemplu Outliers
ANEXE
Anexă 1
Anexă 2
Anexă 3
Introducere
In ultimii ani, invatamantul la distanta prin intermendiul platformelor web a capatat un din ce in ce mai mare avant, motiv pentru care si uneltele dezvoltate pentru acestea au crescut in numar si in complexitate. Datorita modului de interactiune, in mare parte diferit fata de sistemele de invatamant clasice, felul cum un profesor isi reprezinta activitatea studentilor la nivel psihologic poate sa fie destul de diferita. In acest sens, utilizand tehnici ce fac parte din data mining si machine learning incercam sa realizam o unealta ce poate fi integrata in mod generic in astfel de platforme care sa micsoreze distanta dintre nivelul de intelegere actual al studentilor din platformele de e-learning si nivelul de intelegere al studentilor din cadrul invatamantului clasic.
In cadrul acestui proiect de dizertatie ne propunem un studiu in vederea imbunatatirii interactiunii la nivelul student-profesor in special in cadrul platformelor de invatamant la distanta. Una din principalele modalitati de rezolvare a acestei probleme vine din zona de invatare supervizata si mai precis algoritmii de clasificare.
Pentru a completa studiul realizat ne propunem sa dezvoltam si unealta necesara rezolvarii problemei de cercetare luate in considerare. Acest aspect ne conduce la ideea de a dezvolta o unealta care sa inglobeze operatiile necesare pentru a imbunatatii interactiunea dintre profesori si studenti.
Scopul
Scopul realizarii acestui proiect este acela de a imbunatati interactiunea intre studenti si profesori sau studenti si studenti in cadrul platformelor de invatamant la distanta. Pe langa acest scop exista si necesitatea de a crea un clasificator care sa aduca metode noi si, de asemena, sa acopere necesitatile existente in cazul in care dorim sa il implicam in procese de clasificare legate de zona invatamantului la distanta.
Motivația
Motivatia survine din dorinta de a gasi noi modalitati de imbunatatire a interactiunii in cadrul platformelor de invatamant la distanta. In plus ideea de a realiza un algoritm care sa poata aduce noi functionalitati si sa deschida noi perspective de cercetare m-a motivat sa o pun in practica in cadrul acestui proiect.
Obiective
O1. Imbunatatirea interactiunii dintre profesor si studenti. Acest obiectiv al lucrarii de dizertatie vizeaza modalitati de a imbunatati interactiunea profesor-student in cadrul platformelor de invatamant la distanta. Pentru indeplinirea acestui obiectiv este necesar un studiu asupra platformelor de e-Learning pentru localizarea zonelor unde se poate interveni.
O2. Contributia la realizarea unui model mental. Ne referim in special la felul cum profesorii percep nivelul de pregatire al studentilor ce activeaza in cadrul platformelor de invatamant la distanta. Acest aspect se poate realiza in principal prin analiza detaliata a studentilor si extragerea caracteristicilor care ii definesc pentru ca mai apoi sa fie incluse intr-un proces de clasificare. .
Pentru a putea realiza obiectivul propus, in urma unei analize atente a zonei de cercetare s-a concluzionat ca este necesara implementarea unui clasificator care sa inglobeze anumite fuctionalitati ce urmeaza sa concure la rezolvarea problemei mai sus mentionata.
O3. Implementarea unui clasificator care sa ajute la identificarea studentilor ce au nevoie de ajutor, sa inglobeze functionalitati avansate pentru studiul lor si care sa permita gasirea de modalitati pentru a fi ajutati.
In invatamantul clasic profesorul, atunci cand preda o anumita materie, are posibilitatea de a evalua in diverse moduri studentul pentru a evalua gradul de intelegere a materiei. Implicit, profesorul isi poate crea un model mental asupra felului in care se pregateste studentul sau care este interesul sau raportat la acea disciplina. In cadrul unei platforme de invatamant la distanta profesorul este destul de limitat.
Prin procedee de data mining si machine learning putem modela fiecare student pe baza informatiilor care pot fi logate despre el. Astfel de informatii se pot referi pe de o parte la felul cum studentul aloca timpul activitatilor de acumulare de cunostiinte si autotestare (spre exemplu cat de des rapid vizioneaza cursurile dupa ce au fost incarcate pe platforma, cat de mult timp petrece pe platforma), sau pe de alta parte la partea de testare. In aceasta zona putem discuta fie de interesul acordat autotestarii, fie de notele pe care le obtine la testele finale. In amebele cazuri notele primeaza pentru a ne face o idee asupra gradului de intelegere a materiei dar daca analizam cu atentie numarul de teste pe care il da un student si felul cum notele oscileaza ne putem crea o impresie asupra gradului de interes pe care studentul il manifeste referitor la o materie predata.
O4. Integrarea clasificatorului obtinut intr-o librarie ce inglobeaza algoritmi de machine learning sau data mining. Un alt obiectiv al proiectului de dizertatie este integrarea clasificatorului obtinut intr-o librarie open source care inglobeaza algoritmi de machine learning. Acest aspect este important deoarece face ca acest clasificator sa poata fi folosit intr-o mai mare varietate de aplicatii.
Contributii personale
Realizarea acestui proiect a presupus etape de analiza, proiectare si dezvolatare. Pentru partea de dezvoltare au fost utilizate cateva librarii open source cum ar fi simple xml, jdom sau weka pentru a furniza metode si algoritmi bruti clasici. In restul proiectului, totul a fost dezvoltat in java fara alte implicatii de cod librarii software.
Pe parcursul realizarii proiectului s-a realizat un studiu al literaturii care a influentat direct partea de proiectare a proiectului. Mai precis s-au gasit lacune in zona de implementare a algoritmilor si aceste zone au incercat sa fie umplute prin proiectarea si dezvoltarea acestui algoritm.
Prin realizarea acestui proiect s-a contribuit:
La imbunatatirea interactiunii dintre studenti si profesori prin realizarea de tool-uri care inglobeaza tehnici de Intelligent Data Analysis si Human Computer Interaction
La marirea gamei de algoritmi existenti in zona de cercetare a analizei datelor
Obtinerea de noi functionalitati care aplicate pe algorimii standard de Intelligent Data Analysis imbunatatesc procesul de analiza si usureaza modul in care persoana care este implicata in procesul de analiza a datelor interpreteaza rezultatele.
Crearea unui tool care sa inglobeze functionalitatile considerate ca fiind necesare si care sa usureze procesul de analiza a datelor.
Redactarea si trimiterea unei lucrari stiintifice pe baza rezultatelor obtinute. Aceasta lucrare se numeste „Building and advances dense classifier” si este acceptata spre publicare la workshop-ul IDAIR din cadrul conferintei IISA 2014.
Considerente teoretice
Java
Java a fost lansata în 1995 de Sun Microsystems și a avut un impact remarcabil asupra dezvoltatorilor de produse software deoarece a adus cu sine cateva calitati foarte importante cum ar fi robustete, portabilitate și simplitate. Initial Java a fost numita OAK și este formata din limbaj de programare de nivel inalt pe baza caruia sunt construite o serie de platforme destinate implementarii de aplicatii pentru toate segmentele industriei software.
Limbajul de programare Java a devenit una dintre cele mai populare optiuni pentru dezvoltarea de produse software datorita catorva caracteristici foarte importante.
1.Robustete: elimina principalele surse de erori din programarea clasica. Astfel se renunta la pointeri, memoria este administrata automat, eliminandu-se prierderile de memorie printr-o procedură de colectare a obiectelor care nu mai sunt referite (garbage collector).
2.Este complet orientat pe obiecte și elimina total stilul de programare procedural.
3.Simplitate:elimina supraincarcarea operatorilor,mostenirea multipla și alte caracteristici care pot genera un cod confuz.
4.Usurinta in crearea de aplicatii ce folosesc programarea in retea, fire de executie,interfața grafică,etc.
5. Securitate – este un limbaj de programare sigur deoarece furnizeaza mecanisme stricte de securitate a programelor concretizate prin verificarea dinamica a codului pentru detectarea secventelor periculoase,impunerea unor reguli stricte pentru rularea proceselor la distanta, etc.
6. Neutralitate arhitecturală – comportamentul unei aplicatii Java nu depinde de arhitectura mașinii pe care ruleaza.
7.Portabilitatea. Este un mare avantaj oferit de limbajul Java. Doarece Java este un limbaj independent de platforma, aceeași aplicație ruleaza fara nici o modificare pe diverse sisteme de operare cum ar fi Windows,Linux,Mac OS,etc.
8. Este compilat și interpretat, aceasta fiind solutia eficienta pentru obtinerea portabilitatii.
9.Performanta- deși este mai lent decat limbajele de programare care genereaza executabile native pentru o anumita platformă, compilatorul Java asigură o performanță ridicată pentru codul de octeti, astfel încat viteza de lucru putin mai scazuta nu va ridica probleme in desvoltarea aplicatiilor oricat de complexe.
10. Este un limbaj modelat dupa c/c++ ceea ce face trecerea de la c/c++ la java foarte usoara.
Limbajul Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvarii poblemelor din domentii cat mai diverse. Aceste tehnologii au fost grupate in „platforme de lucru” ce reprezinta seturi de librarii scrise in limbajul java precum și diverse programe utilitare folosite pentru dezvoltarea de aplicatii sau componente destinate unei anumite categorii de utilizatori.
In functie de modul de executie a aplicatiilor, limbajele de programare se impart in două categorii:
Limbaje interpretate în care instrucțiunile sunt citite linie dupa linie de un interpretor și sunt traduse în intrucțiuni cod mașină. Avanii Java nu depinde de arhitectura mașinii pe care ruleaza.
7.Portabilitatea. Este un mare avantaj oferit de limbajul Java. Doarece Java este un limbaj independent de platforma, aceeași aplicație ruleaza fara nici o modificare pe diverse sisteme de operare cum ar fi Windows,Linux,Mac OS,etc.
8. Este compilat și interpretat, aceasta fiind solutia eficienta pentru obtinerea portabilitatii.
9.Performanta- deși este mai lent decat limbajele de programare care genereaza executabile native pentru o anumita platformă, compilatorul Java asigură o performanță ridicată pentru codul de octeti, astfel încat viteza de lucru putin mai scazuta nu va ridica probleme in desvoltarea aplicatiilor oricat de complexe.
10. Este un limbaj modelat dupa c/c++ ceea ce face trecerea de la c/c++ la java foarte usoara.
Limbajul Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvarii poblemelor din domentii cat mai diverse. Aceste tehnologii au fost grupate in „platforme de lucru” ce reprezinta seturi de librarii scrise in limbajul java precum și diverse programe utilitare folosite pentru dezvoltarea de aplicatii sau componente destinate unei anumite categorii de utilizatori.
In functie de modul de executie a aplicatiilor, limbajele de programare se impart in două categorii:
Limbaje interpretate în care instrucțiunile sunt citite linie dupa linie de un interpretor și sunt traduse în intrucțiuni cod mașină. Avantajul acestei soluții este pe de o parte simplitatea și pe de alta faptul că fiind interpretată sursa programului obținem avantajul portabilității. Dezavantajul este în mod evident viteza scazuta de executie a programului.
Limbajele compilate sunt acele limbaje in care codul sursă al programelor este transformat de compilator într-un cod ce poate fi executat de catre procesor in mod direct, numit și cod mașina. Avantajul este ca execuția este extrem de rapidă, dezavantajul este insa lipsa portabilității, codul compilat intr-un format de nivel scăzut nu poate fi rulat decăt pe platforma de lucru pe care a fost compilat.
Limbajul de programare Java combina ambele soluții amintite mai sus și deci programele scrise in Java sunt atât interpretate cât și compilate. Deci vom avea la dispoziție un compilator care va transforma sursele programului in așa numitul cod de octeti dar și un interpretor care va executa codul de octeți. Acest cod este diferit de codul mașină. Codul mașina este reprezentat de o succesiune de instrucțiuni specifice unei anumite platforme(inclusiv procesul mașinii pe care va rula) de lucru in format binar astfel încat să poată fi executate fără a mai necesita alte prelucrari.
Codurile de octeti sunt seturi de instrucțiuni asemanatoare cu codul scris în limbaj de asamblare și sunt generate de compilator independent de mediul de dezvoltare. Diferenta principala este ca in timp ce codul mașina poate fi executat direct de catre procesorul platformei pe care a fost creat dar numai pe acea platforma, codul de octeți este interpretat de mediul Java și de aceea poate fi rulat indiferent de platforma atata timp cat va avea instalat mediul de executie Java.
Prin masina virtuala Java se ințelege mediul de execuție al aplicațiilor Java. Pentru ca un cod de octeți să poată fi executat pe o anumita platforma, pe această platformă trebuie să fi fost instalată in prealabil o masină virtuală Java.
Există trei mari platforme pe care se dezvolta limbajul Java.
1.J2SE(Standard Edition). Este platforma standard care ofera suport pentru crearea de aplicații independente și appleturi. Tot aici este inclusă și tehnologia Java Web Start ce furnizează o modalitate foarte usoara pentru lansarea și instalarea locală a programelor scrise în Java direct de pe WEB, oferind in acest fel cea mai comodă soluție pentru distribuția și actualizarea aplicațiilor scrise in Java.
2.J2ME(Micro Edition). Pentru programarea dispozitivelor mobile se foloseste platforma de lucru J2ME care ofera suportul necesar scrierii de programe dedicate acestui scop.
3.J2EE(Enterprise Edition). Aceasta platforma oferă API-ul pentru dezvoltarea de aplicații complexe, formate din componente ce trebuie să ruleze în sisteme eterogene cu informații memorate in baze de date distribuite,etc. Tot in cadrul J2EE putem găsi și suportul pentru dezvoltarea de aplicatii și servicii Web, bazate pe componente cum ar fi pagini JSP și servleturi,etc.
Ca și în alte limbaje și în Java avem anumite tipuri de date. In cadrul acestui limbaj, aceste tipuri de date se împart în doua mari categorii și anume tipuri primitive și tipuri referinta. Pe de o parte sunt tipurile de date definite de clase deoarece „Java porneste de la premiza ca orice este un obiect”, însa pentru ușurința în programare avem tipurile de date primitive dintre care putem aminti cateva care se folosesc mai des.
-tipuri de date pentru operatii aritmetice(int,long,short,byte,float,double)
-tipuri de date pentru operatii pe caractere(char,string)
-tipuri de date logice, unde putem aminti tipul „boolean” ce poate lua valorile true(adevarat) sau false(fals).
In Java, formatul și dimensiunea tipurilor de date primitive nu depind de platforma pe care ruleaza programul spre deosebire de alte limbaje de programare. Variabilele referință pot fi vectori, clase sau interfete, în cazul lor valoarea unei astfel de variabile este o referință(adica o adresa de memorie) către valoarea sau mulțimea de valori reprezentată de variabila care face referința.
Cu toate că exista multe similitudini între Java și c/c++ există trei tipuri de date care au fost omise din Java. Acestea sunt pointerii, structurile și union. Deoarece pointerii creau des diverse erori, ei au fost înlocuiți de tipul referință iar tipurile struct și union au fost înlocuite de clase.
Vectori-Map
Un loc aparte în cadrul limbajului Java este ocupat de vectori. Pentru a crea un vector trebuie sa parcurgem cateva etape:
1.Declararea-acest lucru se realizeaza prin doua metode: TipDate[] NumeVector sau TipDate NumeVector[].
2.Instanțierea vectorului- în cadrul acestei etape i se va aloca memorie folosind operatorul „new” și are urmatoarea forma:
NumeVector = new TipDate[dimensiune].
Declararea și instanțierea pot fi facute împreuna folosind o expresie de genul:
TipDate [] NumeVector = new TipDate[dimensiune]
3.Ultima etapa este instanțierea, este o etapa care poate lipsi deoarece uneori nu avem nevoie de un vector care sa detina de la bun început date(putem sa îl încarcam în urma unor calcule realizate in program). Un model de instantiere poate fi urmatorul: String ț0ari[] = {”Romania”,”Franta”,”Spania”,”Anglia”};
In cazul unui vector avem o corespondență între un index și un element, dar în Java exista și un alt tip de date(pentru colectiile de date) care realizează această corespondentă și care se numeste Map. Un „Map” este un obiect care realizeaza o corespondentă între o cheie și o valoare. In cadrul său nu pot exista mai multe chei cu aceeași valoare deoarece fiecare cheie va avea în corespondență o singură valoare. Un Map se specifică după urmatoarea formă: Map<k,v> unde k este cheia iar v reprezintă valoarea corespunzătoare cheii k. In Java există mai multe clase care implementeaza interfața Map printre care putem aminti HashMap,TreeMap și LinkedHashMap,etc. In cadrul acestui proiect a fost folosit ideea de MultiMap care este un tip particular de Map in care o cheie poate specifica o lista de valori. Operațiile de bază care se pot efectua pe o astfel de colecție de date sunt urmatoarele: put(K key, V value); get(Object key); remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty();
In cazul în care dorim sa manipulam cantități mari de date putem folosi doua metode:
void putAll(Map<? extends K, ? extends V> m); și void clear();
Pentru vizualizarea datelor avem: public Set<K> keySet(); public Collection<V> values();
public Set<Map.Entry<K,V>> entrySet();
Iar pentru a putea obține chei sau valori din setul de înregistrări putem utiliza getKey(), getValue() și setValue(V value).
Încărcarea claselor în memorie
Pentru a putea utiliza date generice în cazul creării fișierelor XML din baza de date am folosit mecanismul reflectării, mecanism ce face parte din cadrul lucrului dinamic cu clasele din Java.
Asa cum am amintit mai sus, există diferente între anumite limbaje de programare cum ar fi C/C++ și Java, unul dintre acestea este ca în urma compilării un program Java nu este descris de un executabil ci de o colectie de fișiere care au extensia .class în care se afla fiecare clasa din program. Un avantaj al acestui aspect este ca aceste clase nu sunt încărcate toate în moementul lansării în execuție a aplicației ci pe parcursul executiei în momentul in care este nevoie de ele. In cazul execuției unei clase avem 4 etape:
I.Incarcarea – este acel proces în urma caruia fișierul .class este regăsit pe baza numelui complet. In urma încarcarii, un obiect de tip java.lang.Class corespunzator clasei respective va fi instanțiat. Această operație precede prima utilizare a clasei.
II.Editarea de legaturi – Noul tip de date este încorportat in JVM pentru a putea fi utilizat
III.Inițializarea – In cadrul acestei etape se execută blocurile statice de inițializare precum și inițializarea variabilelor de clasă.
IV.Descărcarea – Se realizeaza atunci când nu mai există nici o referință a clasei și în cadrul ei obiectul de tip Class va fi marcat pentru a putea fi eliminat de către garbage collector din memorie.
Pentru a încărca clasele unei aplicații în memorie avem nevoie de anumite obiecte pe care le vom numi in continuare class loader. Aceste obiecte sunt de doua tipuri: Class loader-ul primordial(sau bootstrap) și Class loader-e proprii.
Bootstrap-ul reprezina o parte integrata a JVM și este responsabil cu încărcarea claselor standard din distribuția Java. Class loader-ele proprii nu fac pate din masina virtuala și reprezinta instanțe ale clasei java.lang.ClassLoader.
Așa cum se va prezenta în continuare, la execuția unui program în Java se vor crea două obiecte de tip ClassLoader pentru încărcarea în memorie a claselor specifice aplicației. Există și posibilitatea de a crea noi tipuri derivate din ClassLoader care să încarce clasele conform anumitor specificații cu scopul de a obține diverse optimizări. In acest fel, încarcarea unei clase poate determina încărcarea altor clase care vor fi utilizate cu prima sau a unor resurse necesare functionării acestei clase, etc.
Organizarea class loader-erelor începand cu versiunea 1.2 a platformei Java s-a realizat conform unui model „delegat” în cadrul caruia class loade-rele sunt dispuse în forma arborescenta, în varful ierarhiei(rădăcina) aflandu-se class loader-ul primordial(bootstrap). Cu exceptia rădăcinii, fiecare instanța va avea un „parinte”, acesta fiind specificat la crearea sa. Atunci cănd aplicația necestita încărcarea unei clase , un class loader poate delega întâi operatia de încărcare a părintelui său care va delega în continuare cererea până se va ajunge la bootstrap pana cănd unul dintre aceștia reuseste sa o încarce. In cazul în care nu se reuseste încarcarea unei clase va fi aruncată(throw) o excepție de tipul ClassNotFoundException. Cu toate că acest comportament nu este unul obligatoriu,în cele mai multe situații el este preferat pentru a minimiza cazul în care o clasă este încărcata de mai multe ori utilizând class loader-e diferite.
In masina virtuala Java exista în mod implicit trei class loader-e, class loader-ul primordial și inca doua proprii. Aceste class loadere se numesc:
1. Bootstrap Class Loader – Numit și class loader-ul primordial, este responsabil cu încărcarea claselor din distribuția Java standard.
2. Extension Class Loader – Este utilizat pentru încărcarea claselor din directoarele care conțin extensiile JRE
3. System Class Loader – Acesta realizează încărcarea claselor specifice aplicațiilor Java. Acest class loader este de tipul java.lang,URLClassLoader
Figură 1 Organizarea ClassLoader
Se pot utiliza diverse instanțe de tip ClassLoader pentru a încarca tipurile de date Java, din acest motiv fiecare obiect Class va retine class-loaderul utilizat pentru încărcare putând fi obtinut folosind metoda getClassLoader.
Incărcarea dinamica a unei clase în memorie înseamna că nu cunoaștem tipul acesteia decât in momentul execuției aplicației, moment în care se va solicita încarcarea folosind numele său complet prin intermediul unui șir de caractere. Cele mai comune pentru a realiza acest lucru sunt:
• Metoda loadClass apelata pentru un obiect de tip ClassLoader
ClassLoader load = new MyClassLoader();
load.loadClass(”Nume clasa”);
• Metoda Class.forName care va încărca respectiva clasa folorind class loader-ul obiectului curent:
Class c = Class.forName(”Nume Clasa”);
// echivalent cu
ClassLoader loader = this.getClass().getClassLoader();
loader.loadClass("ClasaNecunoscuta");
// Clasele standard pot fi și ele incarcate astfel
Class t = Class.forName("java.lang.Thread");
Dacă dorim să instanțiem un obiect dintr-o clasă încărcată dinamic putem folosi metoda newInstance, cu condiția să existe constructorul fără argumente pentru clasa respectivă. După cum vom vedea în secțiunea următoare, mai există și alte posibilități de a instanția astfel de obiecte.
Class c = Class.forName("java.awt.Button");
Button b = (Button) c.newInstance();
Folosirea interfețelor sau a claselor abstracte împreună cu încărcarea dinamică a claselor oferă un mecanism extrem de puternic de lucru îın Java. Vom detalia acest lucru prin intermediul unui exemplu. Să presupunem că dorim să creăm o aplicație care să genereze aleator un vector de numere după care să aplice o anumită funcție acestui vector. Numele funcției care trebuie apelată va fi introdus de la tastatură, iar implementarea ei va fi conținută într-o clasă a directorului curent. Toate funcțiile vor extinde clasa abstractă „Funcție”. In felul acesta, aplicația poate fi extinsă cu noi funcții fără a schimba codul ei, tot ce trebuie să facem fiind să scriem noi clase care extind „Functie” și să implementăm metoda „executa”. Aceasta va returna 0 dacă metoda s-a executat corect sau −1 în caz contrar.
Un obiect de tip URLClassLoader menține o listă de adrese URL de unde va încerca să încarce în memorie clasa al cărei nume îl specificăm ca argument al metodelor de mai sus. Implicit, la crearea class loader-ului această listă este completată cu informațiile din variabila sistem CLASSPATH sau cu cele specificate prin opțiunea -classpath la lansarea aplicației. Folosind metoda getURLs putem afla aceste adrese, iar cu addURL putem adăuga o nouă adresă de căutare a claselor. Bineînțeles, adresele URL pot specifica și directoare ale sistemului de fișiere local. Să presupunem că în directorul c:\clase\demo există clasa cu numele Test, aflată în pachetul demo și dorim să o încărcăm dinamic în memorie:
// Obtinem class loaderul curent
URLClassLoader urlLoader = (URLClassLoader) this.getClass().getClassLoader();
// Adaugam directorul sub forma unui URL
urlLoader.addURL(new File("c:\\clase").toURL());
// Incarcam clasa
urlLoader.loadClass("demo.Test");
După ce o clasă a fost încărcată folosind un class loader, ea nu va mai putea fi descărcată explicit din memorie. In cazul în care dorim să avem posibilitatea de a o reîncărca, deoarece a fost modificată și recompilată, trebuie să folosim class-loadere proprii și să instanțiem noi obiecte de tip ClassLoader, ori de câte ori dorim să forțăm reîncărcarea claselor. Crearea unui class loader propriu se face uzual prin extinderea clasei URLClassLoader.
Încărcarea claselor folosind clasa nou creată se va face astfel:
// La initializare
URLClassLoader systemLoader =(URLClassLoader) this.getClass().getClassLoader();
URL[] urls = systemLoader.getURLs();
// Cream class loaderul propriu
MyClassLoader myLoader = new MyClassLoader(urls);
myLoader.loadClass("Clasa");
…
// Dorim sa reincarcam clasa
myLoader.loadClass("Clasa"); // nu functioneaza !
// Cream alt class loader
MyClassLoader myLoader = new MyClassLoader(urls);
myLoader.loadClass("Clasa"); // reincarca clasa
Reflectarea(eng. Reflection)
Mecanismul prin care o clasă, interfață sau obiect ”reflectă” la momentul execuției structura lor internă se numește reflectare (eng. reflection), acesta punând la dispoziție metode pentru:
• Determinarea clasei unui obiect.
• Aflarea unor informații despre o clasă (modificatori, superclasa, constructori,metode).
• Instanțierea unor clase al căror nume este știut abia la execuție.
• Setarea sau aflarea atributelor unui obiect, chiar dacă numele acestora este știut abia la
execuție.
• Invocarea metodelor unui obiect al căror nume este știut abia la execuție.
• Crearea unor vectori a căror dimensiune și tip nu este știut decât la execuție.
Suportul pentru reflectare este inclus în distribuția standard Java, fiind cunoscut sub numele de Reflection API și conține următoarele clase: java.lang.Class, java.lang.Object și
Clasele din pachetul java.lang.reflect:
– Array
– Constructor
– Field
– Method
– Modifier
Examinarea claselor și interfețelor se realizează cu metode ale clasei java.lang.Class, un obiect de acest tip putând să reprezinte atât o clasă cât și o interfață, diferențierea acestora făcându-se prin intermediul metodei isInterface.
Reflection API pune la dispoziție metode pentru obținerea următoarelor informații:
Aflarea instanței Class corespunzător unui anumit obiect sau tip de date:
Class c = obiect.getClass();
Class c = java.awt.Button.class;
Class c = Class.forName("NumeClasa");
Tipurile primitive sunt descrise și ele de instanțe de tip Class având forma TipPrimitiv.class: int.class, double.class, etc., diferențierea lor făcânduse cu ajutorul metodei isPrimitive.
Aflarea numelui unei clase – Se realizează cu metoda getName:
Class clasa = obiect.getClass();
String nume = clasa.getName();
Aflarea modificatorilor unei clase – se realizează cu metoda getModifiers, aceasta returnând un număr întreg ce codifică toți modificatorii clasei. Pentru a determina ușor prezența unui anumit modificator se folosesc metodele statice ale clasei Modifier isPublic, isAbstract și isFinal:
Class clasa = obiect.getClass();
int m = clasa.getModifiers();
String modif = "";
if (Modifier.isPublic(m))
modif += "public ";
if (Modifier.isAbstract(m))
modif += "abstract ";
if (Modifier.isFinal(m))
modif += "final ";
System.out.println(modif + "class" + c.getName());
Aflarea superclasei – se realizează cu metoda getSuperclass ce returnează o instanță de tip Class, corespunzătoare tipului de date al superclasei sau null pentru clasa Object.
Aflarea interfețelor implementate de o clasă sau extinse de o interfață – se realizează cu metoda getInterfaces, ce returnează un vector de tip Class[].
Aflarea variabilelor membre – Se realizează cu una din metodele getFields sau getDeclaredFields, ce returneză un vector de tip Field[], diferența între cele două constând în faptul că prima returnează toate variabilele membre, inclusiv cele moștenite, în timp ce a doua le returneză doar pe cele declarate în cadrul clasei. La rândul ei, clasa Field pune la dispoziție metodele getName, getType și getModifiers pentru a obține numele, tipul, respectiv modificatorii unei variabile membru. Cu ajutorul metodei getField este posibilă obținerea unei referințe la o variabilă membră cu un anumit nume specificat. Aflarea constructorilor – Se realizează cu metodele getConstructors sau getDeclaredConstructors, ce returnează un vector de tip Constructor[]. Clasa Constructor pune la dispoziție metodele getName, getParameterTypes, getModifiers, getExceptionTypes pentru a obține toate informațiile legate de respectivul constructor. Cu ajutorul metodei getConstructor este posibilă obținerea unei referințe la constructor cu o signatură specificată.
Aflarea metodelor – se realizează cu metodele getMethods sau getDeclaredMethods, ce returnează un vector de tip Method[]. Clasa Method pune la dispoziție metodele getName, getParameterTypes, getModifiers, getExceptionTypes, getReturnType pentru a obține toate informațiile legate de respectiva metodă.
Cu ajutorul metodei getMethod este posibilă obținerea unei referințe la o metodă cu o signatură specificată. Aflarea claselor imbricate – se realizează cu metodele getClasses sau getDeclaredClasses, ce returneză un vector de tip Class[]. Aflarea clasei de acoperire – se realizează cu metoda getDeclaringClass.
Această metodă o regăsim și în clasele Field, Constructor, Method, pentru acestea returnând clasa cărei îi aparține variabila, constructorul sau metoda respectivă.
Pe lângă posibilitatea de a examina structura unei anumite clase la momentul execuției, folosind Reflection API avem posibilitatea de a lucra dinamic cu obiecte, bazându-ne pe informații pe care le obținem abia la execuție.
Crearea obiectelor
După cum sțim, crearea obiectelor se realizează cu operatorul new urmat de un apel la un constructor al clasei pe care o instanțiem. In cazul în care numele clasei nu este cunoscut decât la momentul execuției nu mai putem folosi această metodă de instanțiere. In schimb, avem la dispoziție alte două variante:
• Metoda newInstance din clasa java.lang.Class
Aceasta permite instanțierea unui obiect folosind constructorul fără argumente ale acestuia. Dacă nu există un astfel de constructor sau nu este accesibil vor fi generate excepții de tipul InstantiationException, respectiv IllegalAccessException.
Class c = Class.forName("NumeClasa");
Object o = c.newInstance();
// Daca stim tipul obiectului
Class c = java.awt.Point.class;
Point p = (Point) c.newInstance();
• Metoda newInstance din clasa Constructor Aceasta permite instanțierea unui obiect folosind un anumit constructor, cel pentru care se face apelul. Evident, această soluție presupune în primul rând obținerea unui obiect de tip Constructor cu o anumită signatură, apoi specificarea argumentelor la apelarea sa. Să rescriem exemplul de mai sus, apelând constructorul cu două argumente al clasei Point.
Excepții generate de metoda newInstance sunt: InstantiationException,
IllegalAccessException, IllegalArgumentException și InvocationTargetException. Metoda getConstructor poate provoca excepții de tipul NoSuchMethodException.
Invocarea unei metode al cărei nume îl cunoaștem abia la momentul execuției se realizează cu metoda invoke a clasei Method. Ca și în cazul constructorilor, trebuie să obținem întâi o referință la metoda cu signatura corespunzătoare și apoi să specificăm argumentele. In plus, mai putem obține valoarea returnată. Să presupunem că dorim să apelăm metoda contains a clasei Rectangle care determină dacă un anumit punct se găsește în interiorul dreptunghiului. Metoda contains are mai multe variante, noi o vom apela pe cea care acceptă un argument de tip Point.
Dacă numărul argumentelor metodei este 0, atunci putem folosi valoarea null în locul vectorilor ce reprezintă signatura, respectiv parametri de apelare ai metodei.
Excepțiile generate de metoda invoke sunt: IllegalAccessException și InvocationTargetException. Metoda getMethod poate provoca excepții de tipul NoSuchMethodException. Setarea și aflarea variabilelor membre Pentur setarea și aflarea valorilor variabilelor membre sunt folosite metodele set și get ale clasei Field. Să presupunem că dorim să setăm variabila x a unui obiect de tip Point și să obținem valoarea variabilei y a aceluiași obiect
Excepțiile generate de metodele get, set sunt: IllegalAccessException și IllegalArgumentException. Metoda getField poate provoca excepții de tipul NoSuchFieldException.
Revenind la exemplul din secțiunea anterioară cu apelarea dinamică a unor funcții pentru un vector, să presupunem că există deja un număr însemnat de clase care descriu diferite funcții dar acestea nu extind clasa abstractă Functie. Din acest motiv, soluția anterioară nu mai este viabilă și trebuie să folosim apelarea metodei executa într-un mod dinamic. Vectorii sunt reprezentați ca tip de date tot prin intermediul clasei java.lang.Class, diferențierea făcându-se prin intermediul metodei isArray. Tipul de date al elementelor din care este format vectorul va fi obținut cu ajutorul metodei getComponentType, ce întoarce o referință de tip Class.
Point []vector = new Point[10];
Class c = vector.getClass();
System.out.println(c.getComponentType());
// Va afisa: class java.awt.Point
Lucrul dinamic cu obiecte ce reprezintă vectori se realizează prin intermediul clasei Array. Aceasta conține o serie de metode statice ce permit:
• Crearea de noi vectori: newInstance
• Aflarea numărului de elemente: getLength
• Setarea / aflarea elementelor: set, get
Lucrul cu bazele de date
In cadrul acestui proiect pentru a se putea realiza conectarea la baza de date, interogarea ei și in final realizarea fișierelor de tip XML,XLS, documentelor PDF sau fișierelor HTML am folosit tehnologia DBCP, așa că în continuare se va arata cum funcționează și ce presupune această tehnologie.
Generalități despre baze de date
Aplicațiile care folosesc baze de date sunt, ȋn general, aplicații complexe folosite pentru gestionarea unor informații de dimensiuni mari ȋntr-o manieră sigură și eficientă.
Ce este și ce presupune o baza de date:
La nivelul cel mai general, o bază de date reprezintă o modalitate de stocare a unor informații (date) pe un suport extern, cu posibilitatea regăsirii acestora. Uzual, o bază de date este memorată ȋntr-unul sau mai multe fișiere. Modelul clasic de baze de date este cel relațional, ȋn care datele sunt memorate ȋn tabele. Un tabel reprezintă o structură de date formată dintr-o mulțime de articole, fiecare articol având definite o serie de atribute – aceste atribute corespund coloanelor tabelului, ȋn timp ce o linie va reprezenta un articol. Pe lânga tabele, o bază de date mai poate conține: proceduri și funcții, utilizatori și grupuri de utilizatori, tipuri de date, obiecte, etc. Dintre producătorii cei mai importanți de baze de date amintim companiile Oracle, Sybase, IBM, Informix, Microsoft, etc. fiecare furnizând o serie ȋntreagă de produse și utilitare pentru lucrul cu baze de date. Aceste produse sunt ȋn general referite prin termenii DBMS (Database Management System) sau, ȋn traducere, SGBD (Sistem de Gestiune a Bazelor de Date). In acest capitol vom analiza lucrul cu baze de date din perspectiva programării ȋn limbajul Java, fără a descrie particularități ale unei soluții de stocare a datelor anume. Vom vedea că, folosind Java, putem crea aplicații care să ruleze fără nici o modificare folosind diverse tipuri de baze care au aceeași structură, ducând ȋn felul acesta noțiunea de portabilitate și mai departe.
Crearea unei baze de date
Crearea unei baze de date se face uzual folosind aplicații specializate oferite de producătorul tipului respectiv de sistem de gestiune a datelor, dar există și posibilitatea de a crea o baza folosind un script SQL. Acest aspect ne va preocupa ȋnsă mai puțin, exemplele prezentate presupunând că baza a fost creată deja și are o anumită structură specificată.
Accesul la baza de date
Se face prin intermediul unui driver specific tipului respectiv de SGBD. Acesta este responsabil cu accesul efectiv la datele stocate, fiind legatura dintre aplicație și baza de date.
Limbajul SQL
SQL (Structured Query Language) reprezintă un limaj de programare ce permite interogarea și actualizarea informațiilor din bazele de date relaționale.Acesta este standardizat astfel ȋncât diverse tipuri de drivere să se comporte identic, oferind astfel o modalitate unitară de lucru cu baze de date.
JDBC
JDBC (Java Database Connectivity) este o interfață standard SQL de acces la baze de date. JDBC este constituită dintr-un set de clase și interfețe scrise ȋn Java, furnizând mecanisme standard pentru proiectanții aplicațiilor ce se folosesc de baze de date.
Folosind JDBC este ușor să transmitem secvențe SQL către baze de date relaționale. Cu alte cuvinte, nu este necesar să scriem un program pentru a accesa o bază de date Oracle, alt program pentru a accesa o bază de date Sybase și asa mai departe. Este de ajuns să scriem un singur program folosind API-ul JDBC și acesta va fi capabil să comunice cu drivere diferite, trimițând secvențe SQL către baza de date dorită. Bineȋnțeles, scriind codul sursă ȋn Java, ne este asigurată portabilitatea programului. Deci, iată două motive puternice care fac combinația Java – JDBC demnă de luat ȋn seamă. Pachetele care oferă suport pentru lucrul cu baze de date sunt java.sql ce reprezintă nucleul tehnologiei JDBC și, preluat de pe platforma J2EE, javax.sql.
In linii mari, API-ul JDBC oferă următoarele facilități:
1. Stabilirea unei conexiuni cu o bază de date.
2. Efectuarea de secvențe SQL.
3. Prelucrarea rezultatelor obținute.
Conectarea la o bază de date
Procesul de conectare la o bază de date implică efectuarea a două operații:
1. Inregistrarea unui driver corespunzător.
2. Realizarea unei conexiuni propriu-zise.
O conexiune (sesiune) la o bază de date reprezintă un context prin care sunt trimise secvențe SQL și primite rezultate. Intr-o aplicație pot exista simultan mai multe conexiuni la baze de date diferite sau la aceeași bază. Clasele și interfețele responsabile cu realizarea unei conexiuni sunt:
• DriverManager – este clasa ce se ocupă cu ȋnregistrarea driverelor ce vor fi folosite ȋn aplicație;
• Driver – interfața pe care trebuie să o implementeze orice clasă ce descrie un driver;
• DriverPropertyInfo – prin intermediul acestei clase pot fi specificate diverse proprietăți ce vor fi folosite la realizarea conexiunilor;
• Connection – descrie obiectele ce modelează o conexiune propriu-zisă cu baza de date.
Primul lucru pe care trebuie să-l facă o aplicație ȋn procesul de conectare la o bază de date este să ȋnregistreze la mașina virtuală ce rulează aplicația driverul JDBC responsabil cu comunicarea cu respectiva bază de date. Acest lucru presupune ȋncărcarea ȋn memorie a clasei ce implementează driver-ul și poate fi realizată ȋn mai multe modalități.
a. Folosirea clasei DriverManager: DriverManager.registerDriver(new TipDriver());
b. Folosirea metodei Class.forName ce apelează ClassLoader-ul mașinii virtuale:
Class.forName("TipDriver"); Class.forName("TipDriver").newInstance();
c. Setarea proprietății sistem jdbc.drivers, care poate fi realizată ȋn două feluri:
– De la linia de comandă: java -Djdbc.drivers=TipDriver Aplicație
– Din program: System.setProperty("jdbc.drivers", "TipDriver");
Folosind această metodă, specificarea mai multor drivere se face separând numele claselor cu punct și virgulă. Dacă sunt ȋnregistrate mai multe drivere, ordinea de precedență ȋn alegerea driverului folosit la crearea unei noi conexiuni este:
1) Driverele ȋnregistrate folosind proprietatea jdbc.drivers la inițializarea mașinii virtuale ce va rula procesul.
2) Driverele ȋnregistrate dinamic din aplicație.
O dată ce un driver JDBC a fost ȋnregistrat, acesta poate fi folosit la stabilirea unei conexiuni cu o bază de date. Având ȋn vedere faptul ca pot exista mai multe drivere ȋncărcate ȋn memorie, trebuie să avem posibilitea de a specifica pe lângă un identificator al bazei de date și driverul ce trebuie folosit. Aceasta se realizează prin intermediul unei adrese specifice, numită JDBC URL, ce are următorul format: jdbc:sub-protocol:identificator.
Câmpul sub-protocol denumește tipul de driver ce trebuie folosit pentru realizarea conexiunii și poate fi odbc, oracle, sybase, db2 și așa mai departe. Identificatorul bazei de date este un indicator specific fiecărui driver corespunzător bazei de date cu care aplicația dorește să interacționeze. In funcție de tipul driver-ului acest identificator poate include numele unei mașini gazdă, un număr de port, numele unui fișier sau al unui director, etc., ca ȋn exemplele de mai jos:
jdbc:odbc:test
jdbc:oracle:[anonimizat]:1521:test
jdbc:sybase:test
jdbc:db2:test
Subprotocolul odbc este un caz special, ȋn sensul că permite specificarea ȋn cadrul URL-ului a unor atribute ce vor fi realizate la crearea unei conexiuni. Sintaxa completa subprotocolului odbc este:
jdbc:odbc:identificator[;atribut=valoare]
jdbc:odbc:test
jdbc:odbc:test;CacheSize=20;ExtensionCase=LOWER
jdbc:odbc:test;UID=duke;PWD=java
La primirea unui JDBC URL, DriverManager-ul va parcurge lista driverelor ȋnregistrate ȋn memorie, pâna când unul dintre ele va recunoaște URL-ul respectiv. Dacă nu exista nici unul potrivit, atunci va fi lansata o excepție de tipul SQLException, cu mesajul "no suitable driver".
Tipuri de drivere
Tipurile de drivere existente ce pot fi folosite pentru realizarea unei conexiuni prin intermediul JDBC se ȋmpart ȋn următoarele categorii:
JDBC-ODBC Bridge
Figură 2 JDBC-ODBC Bridge
Acest tip de driver permite conectarea la o bază de date care a fost ȋnregistrată ȋn prealabil ȋn ODBC. ODBC (Open Database Conectivity) reprezintă o modalitate de a uniformiza accesul la baze de date, asociind acestora un identificator DSN (Data Source Name) și diverși parametri necesari conectării. Conectarea efectivă la baza de date se va face prin intermediul acestui identificator, driver-ul ODBC efectuând comunicarea cu driverul nativ al bazei de date.
Deși simplu de utilizat, soluția JDBC-ODBC nu este portabilă și comunicarea cu baza de date suferă la nivelul vitezei de execuție datorită multiplelor redirectări ȋntre drivere. De asemenea, atât ODBC-ul cât și driver-ul nativ trebuie să existe pe mașina pe care rulează aplicația. Clasa Java care descrie acest tip de driver JDBC este: sun.jdbc.odbc.JdbcOdbcDriver și este inclusă ȋn distribuția standard J2SDK. Specificarea bazei de date se face printr-un URL de forma jdbc:odbc:identificator unde identificator este profilul (DSN) creat bazei de date ȋn ODBC.
2. Driver JDBC – Driver nativ
Figură 3 Driver JDBC nativ
Acest tip de driver transformă cererile JDBC direct ȋn apeluri către driverul nativ al bazei de date, care trebuie instalat ȋn prealabil. Clase Java care implementează astfel de drivere pot fi procurate de la producătorii de SGBD-uri, distribuția standard J2SDK neincluzând nici unul.
3. Driver JDBC – Server
Figură 4 Driver JDBC Server
Acest tip de driver transformă cererile JDBC folosind un protocol de rețea independent, acestea fiind apoi transormate folosind o aplicație server ȋntr-un protocol specfic bazei de date. Introducerea serverului ca nivel intermediar aduce flexibilitate maximă ȋn sensul că vor putea fi realizate conexiuni cu diferite tipuri de baze, fără nici o modificare la nivelul clientului. Protocolul folosit este specific fiecărui producător.
4. Driver JDBC nativ
Figură 5 Driver JDBC nativ
Acest tip de driver transformă cererile JDBC direct ȋn cereri către baza de date folosind protocolul de rețea al acesteia. Această soluție este cea mai rapidă, fiind preferată la dezvoltarea aplicațiilor care manevrează volume mari de date și viteza de execuție este critică. Drivere de acest tip pot fi procurate de la diverși producători de SGBD-uri.
Realizarea unei conexiuni
Metoda folosită pentru realizarea unei conexiuni este getConnection din clasa DriverManager și poate avea mai multe forme:
Connection c = DriverManager.getConnection(url);
Connection c = DriverManager.getConnection(url, username, password);
Connection c = DriverManager.getConnection(url, dbproperties);
Efectuarea de secvențe SQL
O dată facută conectarea cu metoda DriverManager.getConection, se poate folosi obiectul Connection rezultat pentru a se crea obiecte de tip Statement, PreparedStatement sau CallableStatement cu ajutorul cărora putem trimite secvențe SQL către baza de date. Cele mai uzuale comenzi SQL sunt cele folosite pentru:
• Interogarea bazei de date: SELECT
• Actualizarea datelor: INSERT, UPDATE, DELETE
• Actualizarea structurii: CREATE, ALTER, DROP – acestea mai sunt numite instrucțiuni DDL (Data Definition Language)
• Apelarea unei proceduri stocate: CALL
După cum vom vedea, obținerea și prelucrarea rezultatelor unei interogări este realizată prin intermediul obiectelor de tip ResultSet.
Interfața Statement
Interfața Statement oferă metodele de bază pentru trimiterea de secvențe SQL către baza de date și obținerea rezultatelor, celelalte două interfețe:
PreparedStatement și CallableStatement fiind derivate din aceasta. Crearea unui obiect Statement se realizează prin intermediul metodei createStatement a clasei Connection, fără nici un argument:
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();
Execuția unei secvențe SQL poate fi realizată prin intermediul a trei metode:
1. executeQuery
Este folosită pentru realizarea de interogări de tip SELECT.Metoda returnează un obiect de tip ResultSet ce va conține sub o formă tabelară rezultatul interogării.
2. executeUpdate
Este folosită pentru actualizarea datelor (INSERT, UPDATE, DELETE) sau a structurii bazei de date (CREATE, ALTER, DROP). Metoda va returna un ȋntreg ce semnifică numărul de linii afectate de operațiunea de actualizare a datelor, sau 0 ȋn cazul unei instrucțiuni DDL.
3. execute
Această metodă va fi folosită doar dacâ este posibil ca rezultatul unei interogări să fie format din două sau mai multe obiecte de tip ResultSet sau rezultatul unei actualizări să fie format din mai mule valori, sau o combinație ȋntre aceste cazuri. Această situație, deși mai rară, este posibilă atunci când sunt executate proceduri stocate sau secvențe SQL cunoscute abia la momentul execuției, programatorul neștiind deci dacă va fi vorba de o actualizare a datelor sau a structurii. Metoda ȋntoarce true dacă rezultatul obținut este format din obiecte de tip ResultSet și false dacă e format din ȋntregi.
In funcție de aceasta, pot fi apelate metodele: getResultSet sau getUpdateCount pentru a afla efectiv rezultatul comenzii SQL. Pentru a prelua toate rezultatele va fi apelată metoda getMoreResults, după care vor fi apelate din nou metodele amintite, până la obținerea valorii null, respectiv −1. Secvența completă de tratare a metodei execute este prezentată mai jos:
Folosind clasa Statement, ȋn cazul ȋn care dorim să introducem valorile unor variabile ȋntr-o secvență SQL, nu avem altă soluție decât să creăm un șir de caractere compus din instrucțiuni SQL și valorile variabilelor:
Interfața ResultSet
Pentru a putea avea acces la datele rezultate ȋn urma interogarilor am folosit interfata resultSet care va fi prezentată in continuare.
In urma execuției unei interogări SQL rezultatul va fi reprezentat printr-un obiect de tip ResultSet, ce va conține toate liniile ce satisfac condițiile impuse de comanda SQL. Forma generală a unui ResultSet este tabelară, având un număr de coloane și de linii, funcție de secvența executată. De asemenea, obiectul va conține și meta-datele interogării cum ar fi denumirele coloanelor selectate, numărul lor, etc.
Statement stmt = con.createStatement();
String sql = "SELECT cod, nume FROM persoane";
ResultSet rs = stmt.executeQuery(sql);
Rezultatul interogării de mai sus va fi obiectul rs cu următoarea structură:
Tabel 1 Model Rezultat interogare
Pentru a extrage informațiile din această structură va trebui să parcurgem tabelul linie cu linie și din fiecare să extragem valorile de pe coloane. Pentru acest lucru vom folosi metode de tip getXXX, unde XXX este tipul de dată al unei coloane iar argumentul primit indică fie numărul de ordine din cadrul tabelului, fie numele acestuia. Coloanele sunt numerotate de la stânga la dreapta, ȋncepând cu 1. In general, folosirea indexului coloanei ȋn loc de numele său va fi mai eficientă. De asemenea, pentru maximă portabilitate se recomandă citirea coloanelor ȋn ordine de la stânga la dreapta și fiecare citire să se facă o singură dată.
Un obiect ResultSet folosește un cursor pentru a parcurge articolele rezultate ȋn urma unei interogări. Inițial acest cursor este poziționat ȋnaintea primei linii, fiecare apel al metodei next determinând trecerea la următoarea linie. Deoarece next returnează false când nu mai sunt linii de adus, uzual va fi folosită o buclă while-loop pentru a itera prin articolele tabelului:
Implicit, un tabel de tip ResultSet nu poate fi modificat iar cursorul asociat nu se deplasează decât ȋnainte, linie cu linie. Așadar, putem itera prin rezultatul unei interogări o singură dată și numai de la prima la ultima linie. Este ȋnsă posibil să creăm ResultSet-uri care să permită modificarea sau deplasarea ȋn ambele sensuri. Exemplul următor va folosi un cursor care este modificabil și nu va reflecta schimbările produse de alți utilizatori după crearea sa:
Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT cod, nume FROM persoane";
ResultSet rs = stmt.executeQuery(sql);
Dacă un ResultSet folosește un cursor modificabil și care poate naviga ȋn ambele sensuri, atunci are la dispoziție o serie de metode ce se bazează pe acest suport:
• absolute – Deplasează cursorul la o anumită linie specificată absolut;
• updateXXX – Actualizează valoarea unei coloane din linia curentă, unde XXX este un tip de date.
Java Swing și AWT
Pentru realizarea interfeței grafice cu utilizatorul am folosit atât tehnologia Swing cât și AWT, ambele tehnologii sunt disponibile în pachetul standard Java. Interfața grafică cu utilizatorul (GUI), este un termen cu ȋnțeles larg care se referă la toate tipurile de comunicare vizuală ȋntre un program și utilizatorii săi. Aceasta este o particularizare a interfeței cu utilizatorul (UI), prin care vom ȋntelege conceptul generic de interacțiune dintre program și utilizatori. Limbajul Java pune la dispoziție numeroase clase pentru implementarea diverselor funcționalitati UI, ȋnsă ne vom ocupa ȋn continuare de cele care permit realizarea intefeței grafice cu utilizatorul (GUI). De la apariția limbajului Java, bibliotecile de clase care oferă servicii grafice au suferit probabil cele mai mari schimbări ȋn trecerea de la o versiune la alta. Acest lucru se datorează, pe de o parte dificultății legate de implementarea noțiunii de portabilitate, pe de altă parte nevoii de a integra mecanismele GUI cu tehnologii apărute și dezvoltate ulterior, cum ar fi Java Beans. In momentul actual, există două modalități de a crea o aplicație cu interfață grafică și anume:
• AWT(Abstract Windowing Toolkit) – este API-ul inițial pus la dispoziție ȋncepând cu primele versiuni de Java;
• Swing – parte dintr-un proiect mai amplu numit JFC (Java Foundation Classes) creat ȋn urma colaborării dintre Sun, Netscape și IBM,
Swing se bazează pe modelul AWT, extinzând funcționalitatea acestuia și adăugând sau ȋnlocuind componente pentru dezvoltarea aplicațiilor
GUI.
Așadar, este de preferat ca aplicațiile Java să fie create folosind tehnologia Swing, aceasta punând la dispoziție o paletă mult mai largă de facilități, ȋnsă nu vom renunța complet la AWT deoarece aici există clase esențiale, reutilizate ȋn Swing.
In acest capitol vom prezenta clasele de bază și mecanismul de tratare a evenimentelor din AWT, deoarece va fi simplificat procesul de ȋnțelegere a dezvoltării unei aplicații GUI, după care vom face trecerea la Swing.
In principiu, crearea unei aplicații grafice presupune următoarele lucruri:
• Design
– Crearea unei suprafețe de afișare (cum ar fi o fereastră) pe care vor fi așezate obiectele grafice (componente) care servesc la comunicarea cu utilizatorul (butoane, controale pentru editarea textelor, liste, etc);
– Crearea și așezarea componentelor pe suprafața de afișare la pozițiile corespunzătoare;
• Funcționalitate
– Definirea unor acțiuni care trebuie să se execute ȋn momentul când utilizatorul interacționează cu obiectele grafice ale aplicației;
– ”Ascultarea” evenimentelor generate de obiecte ȋn momentul interacțiunii cu utilizatorul și executarea acțiunilor corespunzătoare, așa cum au fost ele definite.
Modelul AWT
Pachetul care oferă componente AWT este java.awt. Obiectele grafice sunt derivate din Component, cu excepția meniurilor care descind din clasa MenuComponent. Așadar, prin noțiunea de componentă vom ȋntelege ȋn continuare orice obiect care poate avea o reprezentare grafică și care poate interactiona cu utilizatorul. Exemple de componente sunt ferestrele, butoanele, listele, bare de defilare, etc. Toate componentele AWT sunt definte de clase proprii ce se gasesc ȋn pachetul java.awt, clasa Component fiind superclasa abstractă a tuturor acestor clase.
Figură 6 Ierarhia AWT
Crearea obiectelor grafice nu realizează automat și afișarea lor pe ecran. Mai ȋntâi ele trebuie așezate pe o suprafata de afișare, care poate fi o fereastră sau un applet, și vor deveni vizibile ȋn momentul ȋn care suprafața pe care sunt afișate va fi vizibilă. O astfel de suprafață pe care sunt plasate componente se mai numește container și reprezintă o instanță a unei clase derivate din Container. Clasa Container este o subclasă aparte a lui Component, fiind la rândul ei superclasa tuturor suprafetelor de afișare Java. Așa cum am văzut, interfață grafică servește interacțiunii cu utilizatorul. De cele mai multe ori programul trebuie să facă o anumită prelucrare ȋn momentul ȋn care utilizatorul a efectuat o acțiune și, prin urmare, componentele trebuie să genereze evenimente ȋn funcție de acțiunea pe care au suferit-o (acțiune transmisă de la tastatură, mouse, etc.). Incepând cu versiunea 1.1 a limbajului Java, evenimentele sunt instanțe ale claselor derivate din AWTEvent.
Așadar, un eveniment este produs de o acțiune a utilizatorului asupra unui obiect grafic, deci evenimentele nu trebuie generate de programator. In schimb, ȋntr-un program trebuie specificat codul care se execută la apariția unui eveniment. Tratarea evenimentelor se realizează prin intermediul unor clase de tip listener (ascultător, consumator de evenimente), clase care sunt definite ȋn pachetul java.awt.event. In Java, orice componentă poate ”consuma” evenimentele generate de o altă componentă (vezi ”Tratarea evenimentelor”).
Modelul Swing
Tehnologia Swing face parte dintr-un proiect mai amplu numit JFC (Java Foundation Classes) care pune la dispoziție o serie ȋntreagă de facilități pentru scrierea de aplicații cu o interfață grafică mult ȋmbogățită funcțional și estetic față de vechiul model AWT. Ierarhia claselor din pachetul Swing este următoarea:
Figură 7 Ierarhia SWING
In JFC sunt incluse următoarele:
• Componente Swing
Sunt componente ce ȋnlocuiesc și ȋn același timp extind vechiul set oferit de modelul AWT.
• Look-and-Feel
Permite schimbarea ȋnfățișării și a modului de interacțiune cu aplicația ȋn funcție de preferințele fiecăruia. Același program poate utiliza diverse moduri Look-and-Feel, cum ar fi cele standard Windows, Mac, Java, Motif sau altele oferite de diverși dezvoltatori, acestea putând fi interschimbate de către utilizator chiar la momentul execuției .
• Accessibility API
Permite dezvoltarea de aplicații care să comunice cu dispozitive utilizate de către persoane cu diverse tipuri de handicap, cum ar fi cititoare de ecran, dispozitive de recunoaștere a vocii, ecrane Braille, etc.
• Java 2D API
Folosind Java 2D pot fi create aplicații care utilizează grafică la un nivel avansat. Clasele puse la dispoziție permit crearea de desene complexe, efectuarea de operații geometrice (rotiri, scalări, translații, etc.), prelucrarea de imagini, tipărire, etc.
• Drag-and-Drop
Oferă posibilitatea de a efectua operații drag-and-drop ȋntre aplicații Java și aplicații native.
• Internaționalizare
Internaționalizarea și localizarea aplicațiilor sunt două facilități extrem de importante care permit dezvoltarea de aplicații care să poată fi configurate pentru exploatarea lor ȋn diverse zone ale globului, utilizând limba și particularitățile legate de formatarea datei, numerelor sau a monedei din zona respectivă.
In aceste capitol vom face o prezentare scurtă a componentelor Swing, deoarece prezentarea detaliata a tuturor facilităților oferite de JFC ar oferi suficient material pentru un volum de sine stătător
Componentele folosite pentru crearea interfețelor grafice Swing pot fi grupate astfel:
• Componente atomice JLabel, JButton, JCheckBox, JRadioButton, JToggleButton, JScrollBar, JSlider, JProgressBar, JSeparator
• Componente complexe JTable, JTree, JComboBox, JSpinner, JList, JFileChooser, JColorChooser, JOptionPane
• Componente pentru editare de text JTextField, JFormattedTextField, JPasswordField, JTextArea, JEditorPane, JTextPane
• Meniuri JMenuBar, JMenu, JPopupMenu, JMenuItem, JCheckboxMenuItem, JRadioButtonMenuItem
• Containere intermediare JPanel, JScrollPane, JSplitPane, JTabbedPane, JDesktopPane, JToolBar
• Containere de nivel ȋnalt JFrame, JDialog, JWindow, JInternalFrame, JApplet.
XML
Pentru a înțelege limbajul XML, este necesar să înțelegem ideea de marcare a datelor. De foarte mult timp, oamenii au elaborat diverse documente și de tot atâta timp tot ei au marcat aceste documente. Spre exemplu, dascălii au marcat(notat) întotdeauna lucrările elevilor. Dascalii le-au spus elevilor să modifice paragrafe, să reformuleze propoziții, să elimine greșelile de ortografie și multe altele. Marcarea unui document reprezintă modul în care definim structura, semnificația și aspectul vizual al datelor din document.
În informatică, „marcarea" a devenit „marcaj”. Acesta este procesul de utilizare a unor coduri numite etichete pentru a defini structura, aspectul vizual și în cazul XML, semnificația acestor informații.
Atat documentele HTML cât și XML conțin date cuprinse între etichete, dar acestea sunt singurele asemanari între aceste două limbaje. În HTML, etichetele definesc felul cum vor arata datele din document, titlul, paragrafele, tabelele, etc. În XML etichetele definesc atăt structura datelor cat și ȋnsemnatatea acestora.
Când structura și semnificația datelor este descrisa, se face posibilă reutilizarea acestor date în orice modalitate. Spre exemplu, dacă dețineți un set de date cu caracter comercial și fiecare element din bloc este bine identificat, se pot încărca doar elementele de care aveți nevoie într-un raport de vânzări și utilizarea celorlalte date într-o bază de date de contabilitate. Deci, se poate utiliza un sistem pentru generarea informațiilor și marcarea lor cu etichete XML, procesând apoi aceste informații în orice alt sistem, indiferent de platforma hardware sau software. Această portabilitate a făcut din standardul XML una dintre cele mai populare tehnologii pentru transferul de date.
Pe măsură ce avansăm trebuie sa precizăm cateva aspecte:
Nu este posibilă utilizarea HTML în loc de XML. Totuși, datele XML se pot include între etichete HTML pentru a fi afișate într-o pagină Web.
HTML conține un set predefinit de tag-uri standard care pot fi folosite de toți programatorii.
XML permite crearea oricărui tag necesar pentru descrierea datelor și a structurii acestora.
Un fișier XML bine formatat se conformează unui set de reguli foarte stricte ce guvernează limbajul XML. Dacă un fișier nu se conformează acestor reguli, XML nu mai funcționează.
Un document XML trebuie sa ȋnceapa cu sintaxa <?xml version="1.0"?> apoi trebuie să apară rădăcina documentului care va cuprinde restul elementelor( ȋn html avem etichetele <html> </html> pe post de radacina). Toate elementele trebuie sa aiba tag-uri de ȋnchidere sau ȋnchidere singulara(„/” la sfarsitul tag-ului) și să fie ierarhice,deci este corect: <a> <b>…</b> </a> sau <a /> <b>…</b> (incorect <a> <b> </a> sau <a> <b> </a> </b>). Caracterele &, <, >, ",’ sunt considerate caractere speciale și pot fi folosite doar utilizand caractere „escape” cum ar fi &, <, >,",'.
XML-urile sunt case-sensitive, astfel că <root> e diferit de <Root>și de aceea este indicata folosirea literelor mici la elemente și atribute pentru a evita eventualele confuzii sau erori.
Un atribut in XML este asemanator cu unul ȋn HTML el avand rolul de a descrie elementele. Atributele sunt localizate ȋn eticheta de start a unui element, imediat după numele elementului respectiv și sunt urmate de semnul ‘=’, care este urmat de valoarea atributului ȋntre ghilimele.
Pentru parsarea fișierelor XML s-au folosit tehnologiile Simple XML și DOM (Document Object Model).
Parsarea fișierelor XML utilizand SAX este destul de usoara și se poate realiza parcurgându-se fișierul, iar la aparitia etichetelor din XML se declanseaza evenimente ce pot fi tratate de programator. In Java fiecare eveniment are asociata o metoda din interfata ContentHandler, aceasta gasindu-se implementata de clasa DefaultHandler,deci trebuie declarată o clasă care fie implementează interfață ContentHandler, fie extinde clasa DefaultHandler.
Principalele metode care sunt apelate automat de către parser la procesarea documentului XML sunt următoarele:
– void startDocument() – metoda e apelata la intalnirea elementului radacina
– void endDocument() – apelata la sfarsitul documentului
– void startElement() – metoda e invocata la aparitia unui tag
– void endElement() – e apelata atunci când se intalneste un tag de sfarsit
– void characters() – metoda apelata la aparitia unui text între taguri
– void processingInstruction() – se apeleaza daca se intalnesc instrucituni de procesare
Avantaje oferite de DOM:
– ofera acces aleator la informațiile din diferite porțiuni ale documentului
– permite modificarea fișierelor XML.
– este independent de platforma ca și limbajul Java
Dezavantaje oferite de DOM:
– consumul de memorie este mare
– parsarea fișierului XML dureaza mult
Weka
Generalități
Weka este o colecție de algoritmi de învățare pentru data mining. Algoritmii pot fi aplicați fie direct pe un set de date sau folosiți chiar din codul Java. Weka conține instrumente pentru preprocesarea datelor, clasificare, regresie, reguli de asociere și pentru vizualizare. De asemenea, este potrivit pentru dezvoltarea de noi scheme de învățare.
Weka este utilizat in cercetare, educație și în cadrul aplicațiilor. Aplicația insumeaza un set vast de instrumente de preprocesare a datelor, algoritmi de invatare și metode de evaluare, interfete grafice utilizator (incluzand vizualizarea datelor) și un mediu pentru compararea algoritmilor de invatare. Weka este un software open source, sub licenta generala publica GNU.
"WEKA" provine de la Mediul Waikato pentru Analiza Cunostiintelor (Waikato Environment for Knowledge Analysis), și a fost dezvoltat la Universitatea Waikato din Noua Zeelanda. WEKA este extensibil și a devenit o colectie de algoritmi pentru invatare in scopul rezolvarii problemelor de data mining din lumea reala. A fost implementat in limbajul Java și ruleaza aproape pe orice platforma. WEKA este usor de folosit și usor de aplicat pe mai multe nivele diferite. Libraria WEKA poate fi accesata de propriul program Java, și poate implementa noi algoritmi pentru invatare. Exista trei scheme majore implementate in WEKA. (1) Scheme implementate pentru clasificare. (2) Scheme implementate pentru previziunea numerica. (3) Meta-scheme implementate.
În afara schemelor actuale de învățare, WEKA conține, de asemenea, o varietate mare de instrumente care pot fi folosite pentru preprocesarea seturilor de date, astfel incat este posibila concentrarea pe propriul algoritm fara a se tine cont de detalii precum citirea datelor din fișier, implementarea algoritmilor de filtrare și oferirea de code sursa pentru evaluarea rezultatelor.
Clasificare tehnici data mining
Tehnicile de data mining au fost grupate în trei categorii, în functie de tipul de probleme pe care le pot modela[MIL03]:
a) Clasificarea si regresia reprezinta cea mai larga categorie de aplicatii, constând în construirea de modele pentru previzionarea apartenentei la un set de clase (clasificare) sau a unor valori (regresie). Exista câteva tehnici dedicate rezolvarii problemelor de clasificare si regresie, dintre care arborii decizionali, tehnica Bayes, retelele neuronale si k-NN se bucura de o larga recunoastere.
b) Analiza asocierilor si succesiunilor, denumita uneori analiza cosului de cumparaturi; aceasta tehnica genereaza modele descriptive care evidentiaza reguli de corelatie între atributele unui set de date.
c) Analiza de tip cluster este o tehnica descriptiva utilizata pentru gruparea entitatilor similare dintr-un set de date sau în egala masura pentru evidentierea entitatilor care prezinta diferentieri substantiale fata de un grup. Tehnicile de grupare în clustere se bazeaza pe algoritmi din sfera retelelor neuronale, algoritmi demografici, k-NN etc.
Pentru rezolvarea problemelor de clasificare si regresie exista o serie de tehnici, iar pentru fiecare tehnica sunt disponibili mai multi algoritmi. Diferenta dintre clasificare si regresie este aceea ca în primul caz, outputul previzionat este apartenenta la o anumita clasa, în timp ce în al doilea caz, outputul estimeaza valoarea unui atribut. Regresia este utilizata în cazurile în care outputul este definit pe un domeniu foarte larg (chiar infinit) de valori si nu trebuie confundata cu notiunea de “regresie liniara” din matematica.
De remarcat ca o problema de regresie poate fi usor transformata într-una de clasificare si invers. În multe cazuri, instrumentele pot fi utilizate pentru rezolvarea ambelor tipuri de probleme.
Tehnica Bayes.
Mai putin implementata în aplicatiile de explorare a datelor, tehnica Bayes naiva este o metoda de clasificare care îsi datoreaza numele ministrului britanic Thomas Bayes (1702- 1761).
Teoria probabilitatilor a lui Bayes, pe care se bazeaza si tehnica ce-i poarta numele, a fost publicata postum, abia în 1764. Bayes este o tehnica de clasificare cu potential atât predictiv, cât si descriptiv. Ea permite analiza relatiei dintre fiecare variabila independenta si variabila dependenta, prin calcularea unei probabilitati conditionate pentru fiecare din aceste relatii. Când o noua instanta se doreste a fi clasificata, predictia se realizeaza prin combinarea efectelor variabilelor independente asupra variabilei dependente.
Limitele tehnicii
Pentru instantele care apartin setului de date utilizat la calculul probabilitatilor a priori si al celor conditionale, “predictia” atributului-obiectiv este 100% corecta. Însa pentru instante din afara se tului de date de instruire, eficienta algoritmului este puternic afectata de prezenta unor probabilitati conditionate egale sau foarte aproape de zero. O alta limita a algoritmului provine din asumtia ca între atributele independente din setul de date exista (teoretic) o independenta statistica. Aceasta asumtie sta si la originea adjectivului “naiv” din denumirea algoritmului, având în vedere ca independenta statist ica de regula nu se verifica si în practica. Algoritmul este limitat din punct de vedere al inputului la date booleene sau categorice. Dincolo de efortul de preprocesare necesar pentru transformarea datelor cu caracter continuu în intervale valorice, asa cum s-a mai mentionat, operatiunea este de multe ori dependenta de experienta si chiar intuitia analistului, factori subiectivi care vor marca rezultatele explorarii.
Avantajele tehnicii.
Tinând seama de faptul ca pentru calculul probabilitatilor nu este nevoie decât de o singura parcurgere a setului de date, algoritmul prezinta avantajul important al unei viteze mari de construire a modelului de clasificare. Ca avantaj semnificativ, algoritmul prezinta capacitatea de a realiza predictii din informatii partiale. În ciuda sensibilitatii la caracteristici slab reprezentate în setul de date, pentru realizarea unei predictii algoritmul nu are obligatoriu nevoie de toate atributele independente, astfel încât cele identificate de analist a fi irelevante pot fi usor eliminate din algoritm.
De fapt, chiar daca nu s-ar cunoaste nimic despre atributele independente, analistul tot ar putea face o predictie (fara pretentia de a fi foarte acurata) numai pe baza probabilitatilor apriori. Modelul obtinut prin aplicarea algoritmului are si un continut descriptiv, care poate fi util analistului. Probabilitatile conditionate aferente fiecarui atribut independent pot fi utilizate în a descrie legatura dintre acestea si atributul-obiectiv.
k-NN
Tehnica (prescurtare a expresiei engleze k-Nearest Neighbor) este predictiva de explorare a datelor utilizata cu precadere în probleme de clasificare. Principiul care sta la baza tehnicii este relativ simplu: o instanta noua este clasificata prin analiza “proximitatii” sale (sau gradului de similitudine) cu alte instante dintr-un set de date cunoscut. k-NN este o tehnica folosita în special pentru clasificarea datelor în categorii multiple, însa poate fi aplicata inclusiv pentru previzionarea unui atribut-obiectiv de natura numerica (continua sau discreta), ca rezultat al unor dependente neliniare. Fie un set de date compus din ins tante care au urmatoarea structura:
– n atribute numerice independente {Xi, i=1,n};
– m atribute booleene sau categorice independente {Aj, j=1,m};
– un atribut-obiectiv Y, reprezentând variabila dependenta a carui valoare va trebui estimata pentru noile instante.
Pentru a previziona valoarea atributuluiobiectiv al unei instante noi, algoritmul cauta în setul de date k înregistrari “apropiate” de acea instanta, pentru care se cunosc valorile lui Y. Predictia este data de media valorilor lui Y aferente “vecinilor” identificati în setul de date. Aplicarea conceptului în practica ridica urmatoarele probleme:
i) Prin ce metoda se stabileste relatia de vecinatate dintre doua instante? Care este metrica utilizata la calculul distantelor dintre doua instante?
ii) Care este valoarea optima pentru k? De câte instante similare este nevoie pentru ca media atributelor-obiectiv sa se constituie Revista Informatica Economica, nr. 3(27)/2003 107 într –o predictie cu grad acceptabil de reprezentativitate?
iii) Ce metoda de calcul a mediei va fi utilizata pentru predictia lui Y? Întrebar ea este importanta în special pentru cazurile în care atributul-obiectiv nu este de natura numerica, ci booleana sau categorica.
iv) Care din atributele {Xi} si {Aj} sunt cu adevarat reprezentative pentru predictie? Care din aceste atribute identifica cel mai bine “vecinii” instantei de analizat?
Limitele tehnicii.
Timpul de calcul este direct proportional cu numarul de instante din setul de date. Din acest motiv, pentru seturi mari de date se impune ca în etapa de prepr ocesare, din setul initial de date sa se selecteze un subset de instante cu dimensiuni rezonabile. Algoritmul lucreaza eficient în probleme de clasificare atunci când toate clasele aferente atributului-obiectiv au o reprezentare egala ca pondere în setul de date, fapt care face necesara “îmbogatirea” setului de date original. Algoritmul pe care se bazeaza te hnica k-NN permite doar realizarea unei estimari a valorii atributului-obiectiv, fara a produce informatii suplimentare despre instanta supusa analizei, despre structura setului de date ori despre categoriile de clasificare a atributului-obiectiv. De cele mai multe ori este dificil de stabilit ce tip de functie estimeaza cel mai bine distanta dintre doua instante. Desi din punct de vedere matematic tehnica permite calculul distantelor si pentru atribute categorice si booleene, în astfel de cazuri metrica devine puternic influentata de transformarile aplicate de analist setului de date în preprocesare. De aceea, k-NN este de preferat a fi utilizata mai mult în situatiile în care pentru toate atributele instantelor se poate aplica aceeasi functie de distanta.
Avantajele tehnicii.
Tehnica permite clasif icarea în multiple clase si modelarea relatiilor neliniare dintre date (în probleme de predictie). Pentru tehnicile care necesita o etapa de învatare a carei output îl constituie un model predictiv, exista riscul ca acest model sa devina desuet în timp, iar predictiile realizate în baza lui sa piarda din reprezentativitate. În cazul k-NN, modelul îl constituie chiar setul de date, care se presupune ca odata supus analizei, este deja în forma sa cea mai recenta. Chiar daca de multe ori pot aparea dificultati în stabilirea unei metrici eficiente, algoritmul este unul dintre putinele care accepta ca input date de natura diferita (continua, categorica, booleana etc.).
Retele neuronale
Tehnica are la baza doua concepte apartinând dome niului inteligentei artificiale. Neuronul artificial reprezinta unitatea de baza pentru prelucrarea informatiei în cadrul calculului neuronal. Prin analogie cu neuronul biologic, el a fost definit ca o unitate ce proceseaza inputuri informationale si genereaza outputuri. Reteaua neuronala artificiala reprezinta un ansamblu de neuroni artificiali, legati prin conexiuni. Retelele neuronale sunt sisteme dinamice, al caror comportament poate fi caracterizat prin urmarirea starilor la momente diferite de timp. Starea unei retele la un moment dat este definita de ansamblul nivelurilor de activare a neuronilor si de intensitatile conexiunilor dintre neuroni. În plus fata de acesti parametri ajustabili, o retea este definita si de urmatorii parametri ficsi: configuratia conexiunilor si tipul functiilor de activare.
Limitele tehnicii
Retelele neuronale nu opereaza decât direct asupra variabilelor numerice. Drept urmare, orice variabila nonnumerica din setul de date care se doreste analizat va trebui convertita în variabila numerica înainte de utilizarea sa în instruirea retelei. În cazul problemelor complexe, utilizatorul este pus în situatia de a rezolva un compromis, între a creste numarul de neuroni ascunsi, ceea ce poate conduce la o instruire foarte lenta si a accepta o topologie mai simpla, asociata unei solutii mai putin precise. Pentru seturi de date cu numar mare de atribute, folosirea retelelor neuronale devine nefezabila.
Determinarea numarului de neuroni ascunsi, pentru probleme complexe de clasificare, nu se poate face decât experimental, ceea ce pe de o parte creste substantial timpul alocat cautarii modelului optim de clasificare, iar pe de alta parte lasa calitatea rezultatelor analizei sa depinda de nivelul de experienta al utilizatorului. Absenta componentei descriptive într-un model generat de o retea neuronala face ca evolutia modelului în etapa de instruire sa fie lipsita de transparenta pentru utilizator. Datorita acestei caracteristici, tehnica este deseori comparata cu o “cutie neagra”. Totusi, cea mai suparatoare caracteristica a retelelor neuronale este timpul îndelungat necesar pentru o buna instruire, fapt corelat cu necesitatea existentei unui numa r relativ mare de instante în setul de instruire.
Avantajele tehnicii.
Reteaua odata instruita poate realiza predictii rapide pentru instante noi. Aceasta caracteristica face ca retelele neuronale sa fie utilizate cu succes în probleme care necesita raspuns în timp real. Pâna în prezent, retelele neuronale reprezinta metoda cea mai eficienta de modelare a unor relatii neliniare. Mai mult, aplicatiile de pâna acum au demonstrat aplicabilitatea acestei tehnici în domenii dificil de modelat, precum vederea electronica sau recunoastere vocala. Spre deosebire de celelalte tehnici de data mining, retelele neuronale nu restrictioneaza output-ul la un singur atribut. Folosind o arhitectura de retea potrivita se pot obtine predictii simultane pentru mai multe variabile, ceea ce poate însemna o eficientizare semnificativa a proceselor de explorare a datelor.
Arbori de decizie
Arborele decizional este o tehnica de explorare a datelor cu potential atât predictiv, cât si descriptiv. Denumirea sa provine de la aceea ca rezultatul se prezinta utilizatorului sub forma unui graf de tip arbore. Output-ul major al unui model bazat pe arbori decizionali este arborele în sine. Procesul de instruire care creeaza arborele este numit inductie. Inductia presupune, ca si în cazul retelelor neuronale, parcurgerea de câteva ori a setului de date de instruire, cu deosebirea ca în cazul arborilor, timpul de instruire si implicit numarul de baleieri ale setului de date este mult mai mic decât la retelele neuronale. Mai precis, numarul de parcurgeri ale setului de instruire este egal cu numarul de niveluri în arbore.
Limitele tehnicii.
Majoritatea algoritmilor nu folosesc întregul set de date indicat de util izator pentru inductie. Pentru acesti algoritmi, construirea arborelui presupune transferul instantelor din setul de date de instruire în memoria RAM. Dimensiunea limitata a memoriei face ca programul sa transfere în RAM numai un subset de date, selectat aleator. În consecinta, gradul de reprezentativitate al modelului construit este deter minat de capacitatea aplicatie de a selecta un subset reprezentativ pentru întreg setul de inductie. O critica adusa frecvent arborilor decizionali este aceea ca algoritmii de inductie nu iau în considerare la momentul splitarii efectul pe care respectiva separare o are asupra viitoarelor splitari. În plus, toate separarile se fac secvential, ceea ce determina dependenta fiecarei splitari de cele precedente.
Avantajele tehnicii
Majoritatea algoritmilor care construiesc arbori decizionali pot fi aplicati fara restrictii legate de tipul datelor. Desi variabila dependenta trebuie sa fie de natura numerica (în cazul problemelor de regresie) sau categorica (în cazul problemelor de clasificare), pentru majoritatea algoritmilor, variabilele independente pot lua valori în orice domeniu. Tehnica se caracterizeaza prin capacitate de prelucrare a unor seturi de date cu numar mare de atribute. Exista situatii în care o instanta poate fi descrisa printr-un numar relativ mare de atribute, de ordinul sutelor sau chiar miilor. În astfel de situatii, explorarea prin tehnica arborilor decizionali reprezinta singura alternativa, cei mai multi algoritmi fiind capabili sa trateze seturi de date cu peste 1000 de coloane. Algoritmii de construire a arborilor decizionali necesita un numar redus de parcurgeri a setului de date utilizat în inductie. Consecinta directa a acestei caracteristici functionale este rapiditatea procesului de inductie si aplicarea eficienta asupra seturilor mari de date. Forma outputului permite nu numai realizarea de previziuni si clasificari, ci si descrierea relatiilor existente între variabilele independente si variabila dependenta. În plus, forma grafica a outputului faciliteaza analiza relatiilor. Exista aplicatii care permit reprezentarea arborelui sub forma unui set de reguli care, pentru arbori de dimensiuni mari, este mai usor de înteles.
Arbori de decizie
Definiție: Arborii de decizie sunt una dintre modalitățile de reprezentare a „structurii din date”, unde nodurile reprezintă teste făcute pe atributele datelor de input iar frunzele reprezintă categoriile, modelul final. Un arbore de decizie reprezintă „cunoștințele invățate” de algoritmi.
Începand de la rădăcina fiecare dintre noduri reprezintă un test făcut pe unul dintre atributele setului de date. Arborele se va forma testând pe rând ficare atribut al setului de date. Rezultatul testului va „ramifica” arborele până la ultimul nivel unde sunt situate frunzele.
Modul de construire a arborilor de decizie cu metoda divide-andconquer: arborele va fi construit recursiv urmand pasii:
Pas1: se alege un atribut care va fi considerat „radacina”
Pas2: se imparte setul de date conform valorilor acestui atribut
Pas3: pentru fiecare din ramificâri se va relua procesul de la „Pas1” cu datele care au ajuns în acest set
Algoritmul se opreste in momentul în care o sub-ramura va conține date cu o singura valoare a atributului clasa. Problema de implementare pe care o ridica acest algoritm este metoda prin care se alege atributul dupa care sa se faca impartirea. Se va calcula, prin diferite formule, o marime numita „informatie” și intuitiv aceasta marime va masura „cat de curata” va fi impartirea folosind acel atribut.
Aceasta marime, „informatia”, se masoara in unitati numite „biti”. In cazul arborilor de decizie marimea este de obicei fractionara și mai mica decat 1.
Pentru calculul informatiei vom avea premizele:
1. clasa setului de date are valori binare (ex: 0/1, da/nu, -1/1) ,deci atunci cand numarul de „da” sau „nu” este zero informatia este zero (intuitiv: daca setul de date conține o singura valoare a atributului clasa, scindarea setului dupa oricare dintre atribute este inutila deoarece detin deja o „structura” a datelor conform clasei urmarite, deci clasificarea este deja făcută).Daca numarul de „da” este egal cu numarul de „nu” informatia va atinge un maxim deci metoda trebuie sa suporte și clase cu mai multe valori
Pentru a indeplini toate aceste premize s-a ales pentru calculul informatiei mărimea „entropie”: Entropie(p1, p2, .,pn) = – p1 log p1 – p2 log p2 – – pn log pn
Daca entropia este calculata in logaritmi cu baza 2 se va masura in „biti” in acceptiunea in care sunt folositi in calculul numeric. Informația calculata in aceasta maniera este asociata unui nod (radacina sau intermediar) și reprezinta cantitatea de informatie pe care ar trebui sa o stim ca sa putem clasifica o instanță noua.
Dupa ce am calculat informatia castigata in urma unei clasificari folosind un anumit atribut se poate decide care din atribute va fi ales pentru a efectua clasificarea setului de date, urmand pasii:
Pas1: se calculeaza informatia castigata in urma clasificarii pentru fiecare din atribute
Pas2: se vor compara informațiile castigate clasificand fiecare din atribute
Pas3: se va alege atributul cu cea mai mare informatie castigata in urma clasificarii
Procedeul descris se va continua recursiv pentru formarea fiecarui nod. In cazul in care frunzele sunt „pure” adica vor conține o singura valoare a clasei clasificarea este terminata. In teorie clasificarea se termina cand toate frunzele sunt „pure”. In practica, pe date reale, nu se vor obtine intotdeauna frunze „pure” caz in care algoritmul se va opri cand datele nu mai pot fi impartite.
Pseudocod:
Algoritm: Generate_Decision_Tree: Creates a decision tree
Input : Instances with discrete attribute values
Output : Decision tree
Method :
(1) Create a node N ;
(2) if instances are all in same class C than
(3) return N – leaf node labeled with class C;
(4) if attribute list is empty than
(5) return N as leaf node labeled with most appropriate class;// majority voting;
(6) Select a test attribute , attribute with largest information gain
(7) Label node N with test attribute
(8) For each possible value of test attribute
//instance partitioning
(9) Create a branch for each test attribute;
(10) Let Si be the set of instances for which test attribute = ai //a partition
(11) if Si is empty than
(12) Create a leaf labeled with the most representative class.
(13) else create a node returned by Generate_Decision_Tree (Si, attribute list, test attribute)
Complexitatea arborilor de decizie
Complexitatea calculului este ramura stiintei calculatoarelor care analizeaza proprietatile „computationale”. In mod particular incearca sa inteleaga cat de multa putere de calcul este necesara pentru a se putea efectua anumite sarcini computationale. Spre exemplu pentru o problema data se pune problema gasirii marginilor superioara si inferioara pentru capacitatea de calcul.
Din pacate pentru multe probleme, aceste margini nu sunt cunoscute. Un exemplu bun ar putea fi cel al problemelor P versus cele NP: pentru toate problemele NP- complete marginile superioara si inferioara sunt greu de gasit. Cei mai eficienti algoritmi pentru acest tip de probleme au nevoie de un timp exponential(raportat la dimensiunea intrarii) dar marginea de jos are de obicei o natura lineara.
Informatica este în cea mai mare parte îngrijorată de o singură întrebare: „De cât timp este nevoie pentru a executa un algoritm dat?”. Dar informaticienii nu dau răspunsul în câteva minute sau milisecunde, aceștia dau răspunsul comparativ cu numărul de elemente pe care algoritmul le are de manipulat.
Imaginați-vă, de exemplu, că aveți o listă de numere nesortate și doriți să scrieți un algoritm pentru a-l găsi pe cel mai mare. Algoritmul trebuie să ia în considerare toate numerele din listă: nu există altă variantă. Dar dacă păstrează pur și simplu o înregistrare cu cel mai mare număr pe care l-a văzut în fiecare moment, se va uita la fiecare intrare doar o singură dată. Timpul necesar execuției unui algoritm este, astfel, direct proporțional cu numărul de elemente de manipulat – pe care informaticienii l-au numit N. Desigur, cei mai mulți algoritmi sunt mult mai complicați și, astfel, mai puțin eficienți, decât unul care găsește cel mai mare număr dintr-o listă, dar cei mai familiari algoritmi au timpul de execuție proporțional cu N2, sau de N ori logaritm (N) sau altceva asemănător.
O expresie matematică care implică ridicarea la diferite puteri a lui N (N, N2 și alte puteri) se numește un polinom și asta este ceea la ce "P" din "P = NP" se referă. P este un set de probleme al căror timp de rezolvare este proporțional cu expresii polinomiale ale lui N.
O abordare generala pentru a rezolva o problema dificila ar putea fi setarea de tinte putin mai coborate si de a incerca abordarea unor probleme mai simple intai in speranta ca prin intelegerea problemei mai simple sa se inteleaga mai bine problema originala care este implicit mult mai dificila. Aceasta abordare a fost luata in considerare respectand complexitatea calculului asa ca vom studia in continuare modele de calcul simple sau oarecum limitate. Poate ca unul dintre cele mai simple modele de calcul este cel al arborilor de decizie. Scopul acestui referat este de a calcula o functie booleana f:{0,1}n {0,1} folosind interogari ca date de intrare. In cea mai simpla forma interogarile le putem considera de forma xi iar raspunsul este varloarea lui xi. Sigur ca interogarile pot fi mai complicate dar in acest referat vom considera doar forme simple. Algoritmul este adaptiv, deci cea de-a k interogare poate sa depinda de cele k-1 interogari anterioare. Algoritmul in sine poate fi descris si ca un arbore binar, de unde si numele sau de „arbore de decizie”.
Pentru o functie booleana f definim complexitatea arborelui de decizie, D(f), ca fiind un numar minim de interogari necesare unui algoritm determinist pentru a rezolva un set de date de intrare. Aceasta masura corespunde adancimii arborelui indusa de un anumit algoritm. O data ce puterea de calcul a arborelui de decizie este bine inteleasa aceasta notiune ar putea fi extinsa la interogari mai complexe. Acestea duc la arbori de decizie aleatori si chiar arbori de decizie cuantici.
In vederea intelegerii puterii de calcul a arborilor de decizie( fara sa ne referim strict la cei deterministi, aleatori sau cuantici), alte masuri ale complexitatii functiilor booleene au fost definite si studiate. Un prim exemplu ar putea fi senzitivitatea, senzitivitatea de bloc, gradul de reprezentare polinomial, si gradul de aproximare polinomiala. Principalele rezultate arata ca toate aceste masuri ale complexitatii(cu exceptia senzitivitatii) sunt legate polinomial unele de altele si de complexitatea arborilor de dezicie in varianta clasica, aleatoare sau cuantica.
Functiile booleene
O functie booleana f poate fi definita ca f:{0,1}n {0,1}. Consideram ca f este definita pe toti n-bitii de intrare. Pentru o intrare x{0,1}n vom folosi xi pentru a nota cel de-al i-lea bit, deci x= x1,x2,…xn. Vom folosi |x| pentru a reprezenta greutatea Hamming a lui x(numarul de „1” din reprezentarea binara a lui x). Daca S este un set de (indici de) variabile atunci vom folosi xs pentru a nota datele de intrare obtinute prin complementarea bitilor de pe pozitiile S din x. Spre exemplu daca x = 0011 atunci x{2,3} = 0101 iar x4 = 0010.
Complexitatea arborilor de decizie pe mai multe modele de algoritmi
In cele ce urmeaza se va defini complexitatea arborilor de decizie pentru trei tipuri diferite de masini: deterministe, aleatoare(nedeterministe) si cuantice.
Deterministe
Un arbore de decizie determinist poate fi considerat un arbore binar T. Fiecare nod intern este etichetat cu o variabila xi si fiecare frunza este etichetata cu o valoare de 0 sau 1. Oferindu-se o intrare x{0,1}n, arborele este evaluat dupa cum urmeaza: pornind de la radacina arborelui, daca aceasta este o frunza, ne oprim, altfel interogheaza valoarea variabilei xi. Daca xi =0, atunci in mod recursiv se va evalua subarborele stang, altfel, daca xi=1 atunci vom evalua subarborele drept. Iesirea arborelui este valoarea(0 sau 1) a frunzei care este atinsa. Trebuie sa remarcam ca o intrare x va determina o frunza care este iesirea arborelui si astfel procedura se termina.
Am putea spune ca arborele de decizie calculeaza functia f daca iesirea lui reprezinta f(x) pentru fiecare x din intervalul {0,1}n. In mod cert exista multi arbori de decizie diferiti care pot calcula functia f. Complexitatea unui astfel de arbore este adancimea sa, sau mai bine zis numarul de interogari necesare pentru cel mai defavorabil caz de date de intrare. Putem defini D(f), complexitatea arborelui de decizie pentru functia f, ca adancimea unui arbore de decizie optim capabil sa calculeze functia f. Acesti arbori de decizie sunt arborii clasici, intalniti in marea majoritate a algoritmilor de clasificare.
In cazul unui arbore determinist pentru generarea unui arbore de decizie se poate considera urmatorul algoritm scris in pseudocod:
Method :
(1) Create a node N ;
(2) if instances are all in same class C than
(3) return N – leaf node labeled with class C;
(4) if attribute list is empty than
(5) return N as leaf node labeled with most appropriate class;
// majority voting;
(6) Select a test attribute , attribute with largest information gain
(7) Label node N with test attribute
(8) For each possible value of test attribute //instance partitioning
(9) Create a branch for each test attribute;
(10) Let Si be the set of instances for which test attribute = ai
//a partition
(11) if Si is empty than
(12) Create a leaf labeled with the most representative class.
(13) else create a node returned by Generate_Decision_Tree
(Si, attribute list, test attribute)
Asa cum a fost mai sus precizat putem calcula complexitatea acestui arbore de decizie ca fiind D(f) = 5 deoarece in cazul nostru pentru a atinge frunza cea mai defavorabila( frunza poate fi atat cea din stanga nodului care are conditia avgMark cat si cea din dreapta lui) sunt necesare fix 5 interogari. De asemenea se poate observa ca exista mai multe frunze care pot fi atinse avand complexitati mai mici( intre 1 si 4). In acest caz pentru a antrena algoritmul de clasificare a fost folosit un set de date care contine 3 atribute(eng:feature-uri) cu insemnatate intr-un domeniu bine stabilit si anume cel educational.
2.Aleatoare(nedeterministe)
La fel ca in multe alte modele de calcul putem adauga la arborii de decizie puterea generarii aleatoare. Ar putea exista doua feluri de a genera un arbore de decizie aleator. In primul rand am putea adauga in mod aleator valori nodurilor interne arborelui. In acest caz, o intrare x nu va mai putea determina care frunza a arborelui va fi atinsa dar va putea induce o distributie de probabilitate peste un set de frunze. Astfel, arborele va da la iesire valorile 0 sau 1 cu o anumita probabilitate. Complexitatea acestui arbore este numarul de interogari pentru cel mai nefavorabil x aflat la intrare si cea mai nefavorabila varianta de alegere a nodurilor.
O a doua varianta de a defini un arbore de decizie este o distribuire a probabilitatii µ peste un arbore de decizie determinist. Arborele nedeterminist este evaluat prin alegerea unui arbore determinist in concordanta cu µ care mai apoi este evaluat. Complexitatea unui arbore de decizie aleator pentru acest tip de definire este adancimea celui mai adanc T care are µ(T)>0. Nu este greu de observat ca aceste doua tipuri de a defini un arbore de decizie sunt echivalente.
Putem spune ca un arbore de decizie aleator calculeaza functia f cu o eroare delimitata(bounded error) daca iesirea lui este f(x) cu o probabilitate de cel putin 2/3 pentru fiecare x din {0,1}n. R2(f) denota complexitatea arborelui de decizie optim care poate calcula functia f cu o eroare limitata.
3.Cuantice
Vom trece in vedere rapid framework-ul pentru calculul cuantic. Unitatea elementară folosită în informatica cuantică este qubit-ul (corespondentul cuantic al bit-ului clasic). O stare m-qubit |ⱷ) este o superpozitie a tuturor sirurilor de m-biti.
|ⱷ)=
Aici ai este un numar complex care este numit amplitudinea starii de baza |i). Avem nevoie de = 1. Exista doua lucruri pe care le putem face cu o asemenea stare: sa o masuram sau sa ii aplicam o transformare unitara. Mecanica cuantica spune ca daca masuram registrul de m-qubiti |ⱷ) atunci vom vedea starea de baza |i) cu probabilitatea |ai|2. Deoarece = 1 avem o distributie a probabilitatii peste sirurile clasice de m-biti.
Separat de masurarea lui |ⱷ),ii putem aplica o transformare unitara. Aceasta este vederea amplitudinii 2m a lui |ⱷ) ca un vector in C2m(a se citi 2m), putem obtine o stare noua |¥) = prin multiplicarea lui |ⱷ) cu o matrice unitara U: |¥)=U|ⱷ). O matrice U este unitara daca inversa sa este egala cu conjugata trasnpusei matricii U*. Deoarece unitar este echivalent cu a pastra norma Euclidiana, noua stare |¥) va avea =1. Exista o gramada de lucrari scrise despre cat de mare poate fi obtinut U dintr-o mica transformare unitara peste cativa qubiti la un moment de timp.
Un arbore de decizie cuantic are urmatoarea forma: pornim de la o stare de m-qubiti |) in care fiecare bit este 0. Apoi aplicam o transformare unitara U0 la aceasta stare, apoi aplicam o interogare O, apoi inca o transformare unitara U1,etc. Un arbore de decizie cuantic cu T-interogari corespunde unei transformari unitare mari A= UTOUT-1…OU1OU0. Aici Ui sunt unitati de transformare fixe, independente de intrarea x. Starea finala A|) depinde de intrarea x numai prin aplicarea interogarii O. Iesirea este obtinuta prin masurarea starii finale si prin oferirea la iesire a celui mai din dreapta bit a starii de baza observate(fara sa pierdem caracterul generic putem sa ne asumam faptul ca nu exista masuratori intermediare).
Spunem ca un arbore de decizie cuantic calculeaza f exact daca iesirea este f(x) cu probabilitatea 1 pentru toti x din multimea {0,1}n. QE(f) denota numarul de interogari ale unui arbore de decizie cuantic care calculeaza f cu o eroare bine delimitata. Trebuie sa precizam si faptul ca noi numaram numai numarul de interogari nu si complexitatea lui Ui.
Spre deoasebire de varianta clasica, determinista sau cea aleatoare a arborilor de decizie algoritmii cuantici nu reprezinta cu adevarat niste arbori(numele de algoritm cuantic de interogare sau algoritm cuantic de tip black-box se mai folosesc de asemenea). Noi preferam termenul de arbore de decizie cuantic deoarece acesti algoritmi cuantici generalizeaza arborii clasici de decizie in sensul ca ii simuleaza asa cum a fost precizat mai sus. Consideram un arbore de decizie determinist cu T-interogari. Intai el determina care variabile vor fi interogate initial, apoi determina urmatoarea interogare depinzand de intamplarile precedente si tot asa pentru T interogari. Eventual poate oferi la iesire un bit de iesire care va depinde de toate intamplarile precedente. Starile de baza care corespund algoritmului cuantic au forma |i,b,h,a) unde i, b reprezinta partea de interogare si h se refera la toate actiunile precendente din calculul clasic(aceste actiuni cuprind atat interogarile cat si raspunsurile la interogari) iar a este cel mai din dreapta qubit care eventual contine si rezultatul. Consideram ca U0 mapeaza starea intiala |,0,,0) la |i,0,,0) unde xi este prima variabila pe care arborele clasic ar interoga-o. Acum algoritmul cuantic aplica O, care transforma starea in |i,xi,,0). Apoi algoritmul aplica o transformare U1 care mapeaza |i,xi,,0) la |j,0,h,0) unde h este noul trecut (care include si pe i si xi) si xj este variabila pe care arborele clasic ar interoga-o dand rezultatul la interogarea precendenta. Apoi arborele cuantic aplica O pentru a doua oara, el aplica o transformare U2 care reinnoieste spatiul de lucru si determina urmatoarea interogare. In sfarsit, dupa T interogari arborele cuantic seteaza bitul de raspuns pe 0 sau 1 depinzand de trecutul total. Toate operatiile Ui facute aici sunt mapari injective de la stari de baza la stari de baza deoarece exista posibilitatea de extindere la permutari ale starilor de baza care reprezinta transformari unitare. Astfel un arbore de t-interogari determinist poate fi simulat de exact un algoritm cuantic de T-interogari. In mod similar un arbore de decizie aleator poate fi simulat de un arbore de decizie cuantic cu aceeasi eroare de probabilitate. Astfel, considerand cele de mai sus avem Q2(f)R2(f)D(f) si Q2(f)QE(f)D(f).
Prezentarea metodei
Prima activitate care a avut loc pentru realizarea lucrarii de diploma se refera la un studiu asupra activitatilor intreprinse in cadrul platformelor de invatamant la distanta. Acest studiu este necesar pentru obtinerea unui model care sa creasca gradul de interactiune dintre profesor si student in cazul invatamantului la distanta.In prima am studiat activitatiile care au loc in mod generic pe aceste platforme.
De aici se pot desprinde cateva atribute care pot fi alocate studentilor din majoritatea platformelor de invatamant la distanta. Acestea se refera la: numarul de ore pe care le petrec studiind, notele pe care le optin in timpul semestrului pentru diverse activitati, interactiunea dintre studenti si dintre studenti si cadrele didactice, participarea la prezentarile live, etc.
Analizand aceste atribute putem trage cateva concluzii care ne pot ajuta in continuare in analiza si dezvoltarea uneltei software menita sa ajute acesti utilizatori. Prima concluzie este ca toate datele pot fi codificate numeric, deci ca tip de date avem cifre. Acest aspect este important pentru ca analizand mai departe valorile care pot fi obtinute putem concluziona ca pentru un student care urmeaza sa fie clasificat valori mai mari ale unui atribut sunt si valori mai bune.
Continuand analiza atributelor si felul cum acestea influenteaza crearea unui arobre de decizie ce este obtinut in urma rularii algoritmului C4.5 putem observa ca atunci cand pe un nod exista o decizie avem mereu in dreapta valorile mai mari si in stanga valorile mai mici. Aceeasi regula se pastreaza si pentru frunzele arborelui deoarece acestea sunt ordonate dupa un sir de decizii luate in prealabil.
In urmatoarea faza este necesar sa localizam zonele unde se poate interveni pentru a imbunatati interactiunea dintre profesor si student. si pe de alta de a implementa o unealta care sa vina in ajutorul profesorilor. Studiul este necesar deoarece unealta trebuie gandita in mod generic pentru a putea fi integrata intr-o varietate cat mai mare de platforme de invatamant la distanta cu un minim de modificari.
Pentru aceasta situatie am analizat elementele de interactiune dintre utilizatori puse la dispozitie de platformele de invatamant la distanta. Se poate concluziona ca mesajele private sau publice (forum, comentarii la teme de casa/rezultate examene) sunt un element des intalnit. In plus interactiunea profesor-student este existenta si la nivelul de ajustare a materialului didactic/resurse educationale. Atunci cand un profesor stabileste un set de intrebari pentru examen, dificultatea temelor de casa, complexitatea cursurilor incarcate, el tine seama de nivelul estimativ al grupei. Acest nivel este mai putin clar in cazul platformelor de invatamant la distanta, neexistand o interactiune fizica intre profesor si studenti iar evaluarea curenta din timpul orelor de curs/laborator este deficitara. Folosind tehnici de data mining putem modela utilizatorii platformelor de invatamant la distanta si putem sa le facem anumite recomandari.
Obtinerea unui clasificator imbunatatit a fost urmatorul pas in cadrul acestui proiect de dizertatie.. In mod normal acest lucru se poate realiza fie prin modificarea procesului de clasificare, proces ce difera in mod normal de la un tip de clasificator la altul si, mai precis, chiar de la un algoritm la altul sau la adaugarea de functionalitati. In cazul nostru, modalitatea vizata se refera la adaugarea de functionalitati pentru algoritm.
Algoritmii specifici vizati sa fie imbunatatiti in cadrul acestui proiect de dizertatie se se refera la zona arborilor de decizie. In cadrul acestor algoritmi prin calculul unor masuri specifice se ajunge la un numar de frunze care sunt divizate in clasele de decizie specificate in fisierul de antrenament. Daca consideram doua clase, in general se poate observa ca pentru o anumita clasa de decizie avem mai multe frunze. Aceste frunze sunt diferite intre ele iar instantele alocate in ele au proprietati diferite daca analizam nodurile premergatoare la acestea. Problema este ca arborii de decizie obijnuiti trateaza toate clasele de decizie identi. Din acest motiv ne propunem sa „incarcam” cu date arborele de decizie si sa analizam instantele din fiecare frunza.
Pentru incarcarea datelor in arborii de decizie, intrucat nu este deja elaborat un algoritm care sa faca acest lucru, am proiectat si sa dezvoltat un algoritm care sa incarce cu instante un model obtinut in urma procesului de clasificare, iar mai apoi am implementat diverse tehnici de analiza.
Calculul succesorului si al predecesorului este destul de util atunci cand vine vorba de utilizare deoarece ne pot ajuta sa vedem felul cum studentii sunt dispusi in frunze, vizualizarea intuitiva a datelor poate ajuta mult profesorul in a-si crea modele de reprezentare a datelor in minte.
Calculul celui de-al i-elea succesor sau predecesor vine sa completeze activitatea prezentata mai sus. Acest aspect este important atunci cand avem un arbore de decizie cu cateva clase si dorim sa localizam studenti din aceeasi clasa dar care fac parte din frunze diferite, uneori dintr-o parte in alta a arborelui.
Un aspect interesant de analizat in urma realizarii setului de date este obtinerea de instante Outlier si Extreme Values. Acest lucru ne poate arata cat de „dispersate” sunt datele, mai precis studentii in cazul nostru. Acest aspect este important deoarece un student care este astfel catalogat poate fi fie un student bun, foarte bun fie unul foarte slab. Exista cazuri in care astfel de instante pot modifica arborele de decizie si prin urmare modelul creat pe baza datelor de antrenament nu va avea performanta dorita. De asemenea, ne intereseaza in special astfel de studenti pentru ca daca ne gandim la un student „genial”, un mod de a fi tratat standard, ca si ceilalti studenti poate duce la performante care sa nu ii puna in valoare capacitatile intelectuale pe cand, daca ne referim la un student foarte slab, pentru a nu avea un esec, acesta trebuie analizat si motivat sa invete sau ajutat cu materiale didactice suplimentare pentru a suplini lipsa de interes sau deficitul intelectual.
Realizarea unei aplicatii care sa permita utilizatorului sa primeasca informatia necesara in mod eficient. Avand in vedere ca problema incarcarii cu date a unui model de clasificare nu a fost abordata, am proiectat si implementat o interfata grafica capabila sa afiseze in mod optim arborele cat si operatiile care pot fi efectuate pe acesta.
Figură 8 Arhitectura generala sistem
In figura de mai sus este prezentat felul in care componentele clasificatorului interactioneaza intre ele.
Pornind de la primul nivel avem in primul rand partea de antrenare a algoritmului de clasificare si obtinerea unui model raportat la datele de antrenament. Acest model foloseste doar algoritmul de clasificare pus la dispozitie de Weka.
Considerand un set de date cu instante noi sau chiar setul de date pe care a fost creat modelul putem aplica algoritmul de incarcare de instante in model si vom obtine un model pe care il numim „Dense Decision Tree”, model pe care putem aplica metode de calcul de successor, predecesor sau calculul celui de-al i-elea successor/predecessor.
De asemenea pentru clasificatorul incarcat avem si o interfata elaborata de noi care sa permita selectarea optiunilor de calcul al successor-ului sau al predecesorului.
Utilizand un algoritm de filtrare care va fi aplicat pe setul de date curent (adica cel care va fi incarcat in model) putem localiza instantele care vor fi catalogate ca outlier sau ca extreme values. Analistul de date va putea alege daca va introduce in procesul de clasificare sau daca va incarca in model acele instante deoarece ele pot modifica rezultatul final.
Algoritm de incarcare a datelor
Primul pas in realizarea unui clasificator care sa ofere eficienta pentru date educationale a fost realizarea unui algoritm generic care sa poata incarca datele din fisierul de invatare(sau orice fisier arff) in modelul arborescent creat.
Algoritmul urmeaza cativa pasi principali:
Se preia modelul oferit de algoritm, se parseaza si se incarca in memorie. In acest pas se si creaza si modelul aborelui in memorie. Pentru realizarea acestui aspect au fost trecute in revista cateva tehnologii care permiteau lucrul cu fisiere XML dar pentru a putea stoca datele si pentru a putea sa le manipulam in mod eficeint doar SimpleXML Parser a permis acest aspect.
Se creaza un hashMap de reguli definite de arbore pentru fiecare frunza in parte. Acest pas este realizat prin explorarea in adancime a arborelui. Practic plecam din radacina si memoram fiecare regula de la fiecare nod prin care trecem pana cand ajungem la o frunza apoi se creaza o regula compusa pentru frunza respectiva care este stocata intr-un hashMap.
Se extrage o instanta din fisierul de antrenament sau de test si se testeaza setul de reguli pentru atributele instantei. Se incarca instanta in lista de instante disponibila pentru fiecare clasa.
Pseudocod:
Procedure LoadInstances()
call createLeafRulles();
for every instance in dataset
call loadInstance(instance)
*
*
*
Procedure LoadInstance(instance)
for every leaf in tree
if(call testRulles(instance,leaf))
call AddInstance(instance,leaf)
*
*
*
Asa cum s-a precizat in prealabil pentru ca algoritmul de incarcare a datelor sa functioneze au fost luate in calcul mai mutle librarii software cu licenta opern source iar libraria care a putut sa ne satisfaca necesitatile de implementare a fost Simple XML. Aceasta librarie structureaza pe nivele elementele din fisierele xml putand fi create nivele ca: Radacina, Nod, Frunza. Aceste aspect ne-a ajutat enorm in aplicarea algoritmului deoarece, spre deosebire de DOM (tehnologie care a fost prima optiune), tehnologie care creaza in mare aceeasi structura, SimpleXML vine sa simplifice legaturile dintre elemente. Putem crea clase care sa mapeze elementele esentiale pentru procesul nostru iar mai apoi putem defini liste pentru fiecare dintre ele.
Figură 9 Data flow
In figura de mai sus sunt prezentati pasii pentru a obtine arborele incarcat cu date. Se pleaca de la algoritmul de baza C4.5 implementat in Weka sub numele de J48, se obtine arborele in format .txt, singurul disponibil apoi se trece intr-un format XML. Aceasta tranzitie ne usureaza algoritmul de incarcare de date aplicat pe modelul creat cu ajutorul Simple XML si creaza posibilitatea de a genera arborele in mod generic. Asupra modelului creat se vine cu instanetele stocate intr-un fisier .arff si apoi se afisaza intr-un mod prietenos pe itnerfata.
Calculul de outlieri si extreme values
Pe langa algoritmul de incarcare a datelor un aspect important in analiza utilizatorilor unui sistem educational trebuie sa fie capabil sa detecteze studentii care sunt „diferiti”. Pentru a putea obtine aceste instante am utilizat algoritmul Interquartile Range (IQR). Acest algoritm este folosit in statisticile descriptive si mai este numit si “midspread” sau “middle fifty” si este o masura a dispersiei statistice. Cu alte cuvinte, IQR este prima quartila scazut din a 3-a quartila; aceste cuartile pot fi vazute clar cu un plot efectuat asupra datelor. Este un estimator definit ca fragmentul de 25% din gama de mijloc, și este cea mai importantă măsură de bază de scară.
Spre deosebire de gama totala, Interquartile range are o cadere de avarie de 25% si din acest motiv este preferat in pofida algoritmului total range.
O quartila este definita ca fiecare dintre cele patru grupe in care o populatie poate fi divizata in acord cu distributia unor valori ale unei variabile particulare.
In cazul nostru am utilizat algoritmul implementat in Weka si am obtinut pentru fiecare instanta situatia in care se afla. Pentru a putea afisa utilizatorului am inclus pe interfata un panel in care instantele au fost afisate ca fiind outlieri sau valori extreme. Practic am initializat algoritmul cu datele de antrenament folosite si pentru clasificare, au fost extrase acele instante care erau considerate de algoritm ca fiind outlieri sau valori extreme si au fost afisate.
Figură 10 Calcul Outlieri si Extreme Values
In figura de mai sus este prezentat fluxul datelor pentru extragerea de outlieri si valori extreme din dataset. Se poate observa ca totul pleaca de la dataset care in cazul nostru este fisierul .arff, este aplicat algoritmul interquartile Range disponibil in libraria Weka apoi pentru fiecare instanta in parte avem un marker care ne indica daca aceasta este outlier sau valoare extrema. Totul este afisat pe interfata pentru a putea oferi utilizatorului un acces usor la rezultate.
Calcul succesor si predecesor
In cadrul aplicatiei experimentale am inclus calculul successorilor si predecesorilor unei instante. Acest lucru este valabil pentru successorii/predecesorii directi(rang 1) sau de un rang mai mare.
Obtinerea acestor liste de instante se realizeaza parcurgand arborele in inordine sau portordine in functie de operatia dorita. In obtinerea acestor date ne ajuta mult tehnologia de parsare a fisierelor XML deoarece organizarea in forma de liste a frunzelor ajuta la accesul facil al datelor.
Figură 11 Exemplu successor si predecesor
Deoarece cand ne referim la successor si predecessor pentru arborele nostru de decizie exista diferente fata de acceptiunea standard referitoare la aceste notiuni, pentru a putea exemplifica calculul succesorului si al predecesorului, putem considera figura de mai sus in care luam ca nod de referinta pe cel marcat cu “L”. Succesorul sau direct se regaseste in frunza M iar predecesorul sau direct este K. Tot in figura de mai sus se poate observa ca daca vrem sa calculam al 4-lea predecesor al nodului L, vom returna nodul cu litera F. Pentru a calcula al doilea successor al nodului L gasim nodul J.
Se poate observa faptul ca in calculul successorului si al predecesorului nu ne intereseaza rangul frunzei din arbore, practic tratam frunzele ca o lista de elemente dublu inlantuite ce poate fi parcursa in ambele sensuri.
Pseudocod:
createLeafList(node)
parentStack = empty stack
leafList = empty stack
while (not parentStack.isEmpty() or node ≠ null)
if (node ≠ null)
parentStack.push(node)
node = node.left
else
node = parentStack.pop()
if (node.type = leaf)
leafList .add(node)
node = node.right
return leafList
computeSuccessor(leafList,node,no)
newNode = null
while (leafList.hasMoreElements())
if (node = = leafList.next())
for (i=0;i<no;i++)
if (leafList.hasMoreElements())
newNode = leafList.next()
else
return null
return newNode
return newNode
computePredecessor(leafList,node, no)
newNode = null
count = 0
while (leafList.hasMoreElements())
if (node = = leafList.next())
if (no > count)
return null
for (i=0;i<no;i++)
newNode = leafList.previous()
else
count++;
return newNode
return newNode
Interfata aplicatiei
Acesta este principalul mod de interactiune intre sistem si utilizator. Proiectarea interfetei a facut pare dintr-un studiu separat deoarece influenteaza direct ergonomia aplicatiei.
Figură 12 Exemplu interfata
Asa cum se poate vedea in figura de mai sus interfata este impartita in 2 zone. Una de afisare si una de selectare de operatii. In stanga avem arborele de decizie creat si incarcat cu instante iar in drepta avem operatiile disponibile pe acesta.
Experimente și analiza rezultatelor
Aplicatia a fost realizata pentru a putea fi utilizata preponderent in domeniul educational. Acest lucru implica crearea de dataset-uri care sa fie in concordanta cu acest domeniu. Sigur ca gama de aplicatii ale algoritmului creat poate fi extinsa usor catre modelarea utilizatorilor( domeniul User Modeling) sau catre alte domenii
Constrangeri
Pentru a putea folosi aplicatia in mod cat mai eficient si pentru a asigura o modalitate de a obtine date relevante pentru scopul cercetarii in domeniu, se pot defini cateva constrangeri mostenite pe de o parte de la algoritmul de baza si pe de alta parte introduse de noul algoritm cu extra-functionalitati.
Introducerea de functionalitati noi a implicat si limitarea la anumite tipuri de date. In acest caz putem mentiona faptul ca algoritmul este optimizat pentru tipurile de date „Numeric”, „Nominal” si „String”.
Tipul de date „Numeric” include toate tipurile de date numerice incluse in Java, repectiv majoritatea limbajelor de programare.
Tipul de date „Nominal” se refera la atribute de tip text sau numerice cu valori specificate in prealabil. Mai precis avem <nominal-specification> pentru specificarea atributului si apoi sunt prezentate valorile posibile: {<nominal-name1>, <nominal-name2>, <nominal-name3>, …}.
Pentru datele de tip String putem pune ca valoare a atributului selectat orice valoare de tip text. Acest aspect creaza o gama destul de larga de valori alaturi de cele de tip numeric.
Aplicarea algoritmului se poate face in aproape orice domeniu posibil dar pentru a putea beneficia de eficienta ei este important sa folosim date ordonate. Mai precis este recomandabil sa se utilizeze date care atunci cand vin cu valori mai mari pentru un anumit atribut reliefeaza o clasa ce inglobeaza itemuri de nivel ridicat/bun. Recriproca este si ea adevarata in acest sens. Aceasta constrangere survine din calculul predecesorului si al successorului. Avand date ordonate putem spune ca daca ne deplasam prin arbore mai intr-un sens vom gasi clase superioare sau inferioare celei selectate.
Incarcarea arborelui
Primul experiment este realizat pe date educationale si vizeaza utilizarea arborelui incarcat cu instante pentru observarea si analiza studentilor. Pentru antrenarea algoritmului si pentru incarcarea cu date a fost utilizat un fisier .arff ce contine 788 de instante. O captura din acest fisier este prezentata mai jos:
Figură 13 Exemplu dataset
Se poate observa ca pentru procesul de clasificare au fost selectate patru atribute mai importante. Acestea includ numarul de ore alocate pentru invatatul la o materie, media notelor obtinute la teste si prezenta care este discretizata in valorile „DA” si „NU”.
Arborele rezultat in urma rularii clasificatorului pe aceste date este prezentat mai jos:
Figură 14 Exemplu arbore
La o analiza sumara a arborelui se pot observa nodurile marcate cu gri deschis si frunzele cu gri mai inchis. In fiecare dintre frunze avem si numarul de instante afarent acelei frunze.
Fiind date educationale se poate observa regula mai sus mentionata si anume ca parcurgand arborele in adancime, in dreapta gasim clase din ce in ce mai bune la fiecare frunza.
Arborele de decizie mai sus mentionat a are urmatoarele date de validare:
Figură 15 Date validare arbore
Din analiza datelor de validare se poate trage usor concluzia ca acuratetea algoritmului pe aceste date este destul de ridicata. De asemenea comparand arborele de decizie creat de noi si cel standard oferit de weka se poate observa ca nu avem nici un fel de diferente fapt ce valideaza modelul nostru.
Calculul de Successori si predecesori
Una din capabilitatile algoritmului imbunatatit este aceea de a calcula succesori si predecesori directi la fel cum este capabil sa calculeze al i-elea successor sau predecesor pentru o anumita frunza specificata.
Pentru arbrele obtinut in urma utilizarii algoritmului am selectat o frunza asa cum se poate observa in imaginea de mai jos
Figură 16 Frunza analizata
Avem pentru successori directi 5 sintante aflate in frunza high de pe nivelul superior mai in drepta. In figura de mai jos poate fi observat acest aspect.
Figură 17 Rezultat successori
Daca pentru aceeasi frunza ne refetim la predecesorii sai directi vom primi frunza de pe acelasi nivel din stanga asa cum paote fi vazut mai jos.
Figură 18 Rezultat Predecesori directi
Tot pentru aceeasi frunza avem pentru successorii de nivel doi urmatoarea lista de instance. Asa cum se poate observa in arbore, lista este destul de lunga deoarece contine 196 de elemente.
Figură 19 Predecesori nivel 2
Detectia de outlieri si valori extreme
Folosind dataset-ul mai sus mentionat am incercat sa obtinem ourierii si valorile extreme din setul nostru de date. Reamintim aici faptul ca daele folosite sunt unele sintetice si nu trebuie neaparat sa avem astfel de valori.
Valori extreme
Ruland algoritmul pe setul de date specificat obtinem urmatorul rezultat:
Figură 20 Valori extreme
Instanta cu id-ul 4 are urmatoarele valori special trecute in dataset pentru a fi afisate pe interfata.: 9,500,1,DA,high. Se poate observa faptul ca acest individ are un numar de ore alocate studiului destul de mare si o nota obtinuta minima… Aceste valori pentru atribute fac ca algoritmul sa considere aceasta instanta ca avand valori extreme.
Outliers
Ruland algoritmul pe setul de date specificat obtinem urmatorul rezultat:
Figură 21 Exemplu Outliers
Se poate observa ca instantele cu id-urile 4 si 9 sunt considerate a fi outlieri. De asemenea, se paote observa si faptul ca instanta asimilata ca fiind extreme value este in acelasi timp si o instanta de tip outlier.
Valorile pentru cele 2 instante sunt urmatoarele: 4,100,10,NU,low si 9,500,1,DA,high.
Termeni de utilizare
Autorii
Autorii acestui proiect de dizertatie sunt reprezentati de coordonatorul stiintific dl. Conf.dr.ing. Mihaescu Marian Cristian si masterandul Popescu Paul Stefan.
Licența de utilizare
Licenta de utilizare se refera la autorii acestui proiect de dizertatie. Ei au dreptul de utilizare.
Concluzii
In cadrul accestui proiect de dizeratie ne-am propus sa gasim noi modalitati de imbunatatire a interactiunii dintre studenti si profesori. Acest aspect a condus la necesitatea obtinerii unui nou algoritm de clasificare capabil sa inglobeze extra functionalitati care sa fie fezabile pentru sistemele de invatamant la distanta. Pentru a putea realiza acest aspect a fost necesar un studiu asupra platformelor de invatamant la distanta si un studiu al literaturii.
Algoritmul obtinut este integrat intr-un tool ce este dependent doar de fisierul de invatare( dataset) si poate fi usor integrat intr-o gama larga de platforme de invatamant la distanta. Practic in cazul in care se doreste analiza altor studenti care isi desfasoara activitatea in astfel de platforme este necesar sa existe un tool capabil sa extraga datele necesare pentru clasificare si sa genereze fisierul de invatare pentru ca mai apoi acesta sa consittuie date de intrare pentru toolul dezvoltat in cadrul acestui proiect.
Ca lucru in continuare consider ca algoritmul poate fi extins cu alte functionalitati si, de asemenea, acest algoritm poate fi extins pentru lucrul cu alte tipuri de date. Unul din tipurile de date care poate fi necesar uneori si se afla in weka este cel de tip date. Acest tip de date poate completa atributele alocate anumitor studenti pentru studiul temportal referitor la felul cum se incadreaza in termene.
Bibliografie
[POP12] Popescu Paul Stefan, „Complexitatea arborilor de decizie”, disciplina Complexitatea Calculului, Referat Master IS, an1, sem1, coordonator D. D. Burdescu
[POP14] Paul Stefan Popescu, Cristian Mihaescu, Mihai Mocanu, Dumitru Dan Burdescu, Building an Advanced Dense Classifier, 5th International Conference on Information, Intelligence, Systems and Applications, Chania, Crete, July 2014
[MOC 2013] Mihai Mocanu, Paul-Stefan Popescu, Dumitru Dan Burdescu, Marian Cristian Mihaescu Advanced Messaging System for On-Line Educational Environments Sesimbra, Portugal, 26-28 June 2013
[BUR 06] D.D. Burdescu, ,M.C. Mihăescu. Tesys: e-Learning Application Built on a Web Platform. Proceedings of International Joint Conference on e-Business and Telecommunications. Setubal, Portugal, pp. 315-318. 2006
[BUH02] Harry Buhrman, Ronald de Wolf, Complexity measures and decision tree complexity: a survey, Theoretical Computer Science 288 (2002) 21–43;
[ARO07] Sanjeev Arora and Boaz Barak, Computational Complexity: A Modern Approach, Draft of a book: Dated January 2007
[CHI] Igor Chikalov, Average Time Complexity of Decision Trees, Springer
[ARO07] Sanjeev Arora and Boaz Barak, Computational Complexity: A Modern Approach, 2007
[SHA] Shalev Ben-David, Decision-Tree Complexity
[BAD] Laviniu Aurelian Badulescu, Arborii de decizie o provocare pentru clasificarea si luarea deciziilor in economie
[MIL03] Ec. Valentin MILITARU Studiu comparat asupra tehnicilor de data mining utilizate în rezolvarea problemelor de regresie si clasificare Revista Informatica Economica, nr. 3(27)/2003
[QUI86]J.R.Quinlan, “Induction of Decision Trees”, Machine Learning 1, 81-106. 1986
[WIT99] Witten, Ian H.; Frank, Eibe; Trigg, Leonard E.; Hall, Mark A.; Holmes, Georey; Cunningham, Sally Jo. ‘Weka: Practical machine learning tools and techniques with Java implementations’, University of Waikato, Department of Computer Science. 1999.
[IAW11] T. Iwata, T. Tanaka, T. Yamada, N. Ueda, “Improving Classifier Performance using Data with Different Taxonomies”, Knowledge and Data Engineering, IEEE Transactions on Volume:23 , Issue: 11 , 2011
[FUX09] A. Fuxman, A. Kannan,A. B. Goldberg,R.Agrawal,P. Tsaparas,and J. Shafer, “Improving classification accuracy using automatically extracted training data,”, KDD '09 Proceedings of the 15th ACM SIGKDD international conference on Knowledge discovery and data mining, 2009
[JOS01] Joshi, M.V. Thomas J. Watson Kumar, V. ; Agarwal, Ramesh C., Evaluating boosting algorithms to classify rare classes: comparison and improvements, Data Mining, 2001. ICDM 2001, Proceedings IEEE International Conference.
[BRY03] R. Bryll, R. Gutierrez-Osuna,F. Quek, “Attribute bagging: improving accuracy of classifier ensembles by using random feature subsets”, Pattern Recognition Volume 36, Issue 6, June 2003, pp 1291–1302
[MIN03] B. Minaei-Bidgoli, D.A. Kashy, G. Kortemeyer, “Predicting student performance: an application of data mining methods with an educational Web-based system”, ; Punch, W.F. Frontiers in Education, 2003. FIE 2003 33rd Annual (Volume:1 )
[JAC63] I.S. Jacobs and C.P. Bean, “Fine particles, thin films and exchange anisotropy,” in Magnetism, Volume III, G.T. Rado and H. Suhl, Eds. New York: Academic, 1963, pp. 271-350.
[BAR11] B.K. Baradwaj, S. Pal, “Mining Educational Data to Analyze Students Performance “ (IJACSA) International Journal of Advanced Computer Science and Applications, Volume 2, No. 6, 2011.
[MAR13] C. Márquez-Vera, A. Cano, C. Romero, and S. Ventura. Predicting student failure at school using genetic programming and different data mining approaches with high dimensional and imbalanced data. Applied Intelligence, 38 (3), pp. 315-330, 2013.
[WEI08] Wei-Yin Loh,”Classication and Regression Tree Methods”. Wiley, 2008.
[QUI93] J. R. Quinlan. “C4.5: Programs for Machine Learning”. San Mateo, CA, 1993.
[BAH] A. Bahety, „Extension and Evaluation of ID3 Decision Tree Algorithm”, University of Maryland, College Park.
[HOL02] G. Holmes, B. Pfahringer, R. Kirkby, E. Frank and M. Hall;” Multiclass Alternating Decision Trees”, Lecture Notes in Computer Science Volume 2430, 2002, pp 161-172
[FON03] M. J. Fonseca , J. A. Jorge. “NB-Tree: An Indexing Structure for Content-Based Retrieval in Large Databases”, IEEE Computer Society (2003)
[BOH02] C. Bohm, F. Krebs, “High performance data mining using the nearest neighbor join”, Data Mining, 2002. ICDM 2003. Proceedings. 2002 IEEE International Conference on
[PAG93] B.U. Pagel, H. W. Six, H. Toben, P. Widmayer, “Towards an analysis of range query performance in spatial data structures”, PODS '93 Proceedings of the twelfth ACM SIGACT-SIGMOD-SIGART symposium on Principles of database systems, pp. 214-221
[CFC]-Curs practic de Java, Cristian Frasinaru,Editura Matrixrom
[DMDT:08]-Data Mining with Decision Trees: Theory and Applications de Lior Rokach, Oded Z. Maimon, World Scientific Publishing Co.2008
Bibliografie
[POP12] Popescu Paul Stefan, „Complexitatea arborilor de decizie”, disciplina Complexitatea Calculului, Referat Master IS, an1, sem1, coordonator D. D. Burdescu
[POP14] Paul Stefan Popescu, Cristian Mihaescu, Mihai Mocanu, Dumitru Dan Burdescu, Building an Advanced Dense Classifier, 5th International Conference on Information, Intelligence, Systems and Applications, Chania, Crete, July 2014
[MOC 2013] Mihai Mocanu, Paul-Stefan Popescu, Dumitru Dan Burdescu, Marian Cristian Mihaescu Advanced Messaging System for On-Line Educational Environments Sesimbra, Portugal, 26-28 June 2013
[BUR 06] D.D. Burdescu, ,M.C. Mihăescu. Tesys: e-Learning Application Built on a Web Platform. Proceedings of International Joint Conference on e-Business and Telecommunications. Setubal, Portugal, pp. 315-318. 2006
[BUH02] Harry Buhrman, Ronald de Wolf, Complexity measures and decision tree complexity: a survey, Theoretical Computer Science 288 (2002) 21–43;
[ARO07] Sanjeev Arora and Boaz Barak, Computational Complexity: A Modern Approach, Draft of a book: Dated January 2007
[CHI] Igor Chikalov, Average Time Complexity of Decision Trees, Springer
[ARO07] Sanjeev Arora and Boaz Barak, Computational Complexity: A Modern Approach, 2007
[SHA] Shalev Ben-David, Decision-Tree Complexity
[BAD] Laviniu Aurelian Badulescu, Arborii de decizie o provocare pentru clasificarea si luarea deciziilor in economie
[MIL03] Ec. Valentin MILITARU Studiu comparat asupra tehnicilor de data mining utilizate în rezolvarea problemelor de regresie si clasificare Revista Informatica Economica, nr. 3(27)/2003
[QUI86]J.R.Quinlan, “Induction of Decision Trees”, Machine Learning 1, 81-106. 1986
[WIT99] Witten, Ian H.; Frank, Eibe; Trigg, Leonard E.; Hall, Mark A.; Holmes, Georey; Cunningham, Sally Jo. ‘Weka: Practical machine learning tools and techniques with Java implementations’, University of Waikato, Department of Computer Science. 1999.
[IAW11] T. Iwata, T. Tanaka, T. Yamada, N. Ueda, “Improving Classifier Performance using Data with Different Taxonomies”, Knowledge and Data Engineering, IEEE Transactions on Volume:23 , Issue: 11 , 2011
[FUX09] A. Fuxman, A. Kannan,A. B. Goldberg,R.Agrawal,P. Tsaparas,and J. Shafer, “Improving classification accuracy using automatically extracted training data,”, KDD '09 Proceedings of the 15th ACM SIGKDD international conference on Knowledge discovery and data mining, 2009
[JOS01] Joshi, M.V. Thomas J. Watson Kumar, V. ; Agarwal, Ramesh C., Evaluating boosting algorithms to classify rare classes: comparison and improvements, Data Mining, 2001. ICDM 2001, Proceedings IEEE International Conference.
[BRY03] R. Bryll, R. Gutierrez-Osuna,F. Quek, “Attribute bagging: improving accuracy of classifier ensembles by using random feature subsets”, Pattern Recognition Volume 36, Issue 6, June 2003, pp 1291–1302
[MIN03] B. Minaei-Bidgoli, D.A. Kashy, G. Kortemeyer, “Predicting student performance: an application of data mining methods with an educational Web-based system”, ; Punch, W.F. Frontiers in Education, 2003. FIE 2003 33rd Annual (Volume:1 )
[JAC63] I.S. Jacobs and C.P. Bean, “Fine particles, thin films and exchange anisotropy,” in Magnetism, Volume III, G.T. Rado and H. Suhl, Eds. New York: Academic, 1963, pp. 271-350.
[BAR11] B.K. Baradwaj, S. Pal, “Mining Educational Data to Analyze Students Performance “ (IJACSA) International Journal of Advanced Computer Science and Applications, Volume 2, No. 6, 2011.
[MAR13] C. Márquez-Vera, A. Cano, C. Romero, and S. Ventura. Predicting student failure at school using genetic programming and different data mining approaches with high dimensional and imbalanced data. Applied Intelligence, 38 (3), pp. 315-330, 2013.
[WEI08] Wei-Yin Loh,”Classication and Regression Tree Methods”. Wiley, 2008.
[QUI93] J. R. Quinlan. “C4.5: Programs for Machine Learning”. San Mateo, CA, 1993.
[BAH] A. Bahety, „Extension and Evaluation of ID3 Decision Tree Algorithm”, University of Maryland, College Park.
[HOL02] G. Holmes, B. Pfahringer, R. Kirkby, E. Frank and M. Hall;” Multiclass Alternating Decision Trees”, Lecture Notes in Computer Science Volume 2430, 2002, pp 161-172
[FON03] M. J. Fonseca , J. A. Jorge. “NB-Tree: An Indexing Structure for Content-Based Retrieval in Large Databases”, IEEE Computer Society (2003)
[BOH02] C. Bohm, F. Krebs, “High performance data mining using the nearest neighbor join”, Data Mining, 2002. ICDM 2003. Proceedings. 2002 IEEE International Conference on
[PAG93] B.U. Pagel, H. W. Six, H. Toben, P. Widmayer, “Towards an analysis of range query performance in spatial data structures”, PODS '93 Proceedings of the twelfth ACM SIGACT-SIGMOD-SIGART symposium on Principles of database systems, pp. 214-221
[CFC]-Curs practic de Java, Cristian Frasinaru,Editura Matrixrom
[DMDT:08]-Data Mining with Decision Trees: Theory and Applications de Lior Rokach, Oded Z. Maimon, World Scientific Publishing Co.2008
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Utilizarea Algoritmilor de Clasificare Pentru Imbunatatirea Interactiunii Dintre Profesori Si Studenti (ID: 150739)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
