Większość modeli w programie AdvancedMiner po utworzeniu z wykorzystaniem danych treningowych może być zastosowana do innych zbiorów danych.
MiningApplyTask to specjalny obiekt, który wykorzystuje wcześniej utworzony model ekstrakcji danych w celu uzyskania pewnych informacji wynikowych dla danych wejściowych. Stosowanie modeli przebiega według stałego schematu, są jednak pewne różnice pomiędzy konkretnymi rodzajami modeli. W tym rozdziale opisana jest ogólna procedura stosowania modeli.
Zastosowanie modelu polega na wczytaniu zbioru danych wejściowych i wygenerowaniu zbioru danych wynikowych. Każdemu wierszowi w tabeli wejściowej odpowiada jeden wiersz w tabeli wynikowej. Wiersze tabeli wynikowej są generowane w trakcie wykonywania zadania zastosowania modelu, a wartości w wierszach wynikowych są obliczane przez algorytm, który jest określony przez bazowy model ekstrakcji danych.
Zarówno dane wejściowe jak i wynikowe mają postać tabel w bazie danych. Tabela z danymi wejściowymi musi istnieć przed zastosowaniem modelu, tabela z danymi wynikowymi jest tworzona w trakcie wykonywania zadania stosowania modelu.
Struktura tabeli wynikowej może być dowolnie określona przez użytkownika. Obiekt ApplyOutput zawiera metadane ze specyfikacją tabeli wynikowej.
Zgodnie z ogólnym schematem występującym w programie AdvancedMiner, w przypadku stosowania modelu na algorytm ekstrakcji danych nakładana jest dodatkowa warstwa abstrakcji w postaci funkcji ekstrakcji danych (ang. mining function). Dzięki temu stosowanie algorytmów wykorzystujących taką samą funkcję ekstrakcji danych odbywa się w ten sami sposób.
Dane wynikowe będą zawierać dokładnie tyle atrybutów, ile zostanie określonych przez użytkownika. Atrybuty wynikowe są przypisane do ustawień directMapping bądź applyOutput. Pierwsze z nich odpowiada za atrybuty, które są po prostu kopiowane z danych wejściowych do danych wynikowych. Drugie gromadzi atrybuty generowane przez model dla każdej obserwacji.
Architektura stosowania modeli została zaprojektowana w celu zapewnienia użytkownikowi maksymalnej swobody. Częścią tego schematu jest obiekt ApplyOutputItem.
Pojedynczy obiekt ApplyOutputItem opisuje jeden atrybut w tabeli wynikowej. Są cztery główne rodzaje tych obiektów: Category (Kategoria), Cluster (Skupisko), Rank (Rząd) i Source (Źródło).
Utworzona zostanie wartość wynikowa dla określonej kategorii, zob. podrozdział klasyfikacja.
Utworzona zostanie wartość wynikowa dla określonego skupiska, zob. podrozdział analiza skupień.
Wartości wynikowe zostaną przypisane kolejno do pierwszej, drugiej, ..., n-tej predykcji. Ten typ elementu wynikowego może być wykorzystany przez modele klasyfikacyjne oraz modele oparte na analizie skupień .
Atrybut danych wynikowych zawiera wartości przekopiowane bezpośrednio z danych wejściowych, zob. podrozdział Odwzorowanie bezpośrednie.
Istnieją też dwa dodatkowe typy elementów wynikowych związane z modelami regresji logistycznej i regresji liniowej, które są opisane w odpowiednich rozdziałach.
Z każdym elementem danych wynikowych związany jest określony typ wyniku, który określa dokładny typ wartości danego elementu. Na przykład w przypadku pojedynczej decyzji klasyfikatora wartością wyniku może być prawdopodobieństwo danej decyzji lub identyfikator obiektu powiązanego z daną decyzją. Jako inny przykład, model oparty na analizie skupień może zwrócić następujące rodzaje wyników opisujące najlepsze skupisko dla danej obserwacji: identyfikator skupiska (clusterId), prawdopodobieństwo (probability) lub odległość (distance). Więcej przykładów można znaleźć w rozdziałach poświęconym poszczególnym modułom.
Zadanie zastosowania modelu można tak skonfigurować, aby wybrane wartości z tabeli wejściowej zostały przekopiowane bezpośrednio do tabeli wynikowej, bez wykonywania jakichkolwiek transformacji danych.
Aby określić, które atrybuty zostaną odwzorowane, należy do listy directMapping dodać obiekty ApplySourceItem. Każdy obiekt ApplySourceItem ma następujące parametry:
nazwa atrybutu (zmiennej) w danych wejściowych
nazwa atrybutu w danych wynikowych
Każdy model ekstrakcji danych posiada sygnaturę z logicznymi atrybutami wykorzystywanymi w danym procesie ekstrakcji danych. Zadanie zastosowania wykorzystując model oblicza wiersze wynikowe na podstawie atrybutów zawartych w wierszach wejściowych. Należy określić w jaki sposób model ma wykorzystywać atrybuty z danych wejściowych.
Przypisanie modelu do zadania określa w jaki sposób atrybuty z danych wejściowych są odwzorowywane na sygnaturę modelu.
W przypadku gdy nie zostanie określone żadne odwzorowanie, stosowane jest odwzorowanie domyślne. Program stara się przyporządkować atrybuty z danych wejściowych do atrybutów z sygnatury modelu na podstawie ich nazw.
Oznacza to, że w przypadku, gdy dane, do których model ma być zastosowany, mają taką samą sygnaturę (czyli nazwy zmiennych) jak dane treningowe modelu, model zostanie zastosowany prawidłowo bez określania sposobu odwzorowania atrybutów.
Może zajść sytuacja, w której pewne atrybuty zapisane w sygnaturze modelu nie mają swoich odpowiedników (odwzorowywanych domyślnie lub na podstawie odwzorowania wprowadzonego przez użytkownika) w danych wejściowych. W takim przypadku atrybut nie będzie odwzorowywany i każda wartość wejściowa dla tego atrybutu będzie traktowana jako dana brakująca (NULL). Skutki takiej sytuacji mogą zależeć od rodzaju algorytmu stosowanego w modelu. Niektóre algorytmy są w stanie sobie poradzić z brakującymi danymi, podczas gdy inne zgłoszą błąd i przerwą wykonywanie.
Zazwyczaj zadanie zastosowania modelu oczekuje, że tabela wynikowa o określonej nazwie nie istnieje w bazie danych. Wówczas tworzona jest nowa tabela z kolumnami określonymi na podstawie specyfikacji podanej przez użytkownika.
Jeżeli tabela wynikowa istnieje, zadanie zastosowania modelu stara się dopisać do niej nowe wiersze. To jest możliwe, jeżeli tabela ma sygnaturę zgodną ze specyfikacją danych wynikowych. Jeżeli ten warunek nie jest spełniony, zgłaszany jest błąd.
Działanie tego mechanizmu można zmienić tak, aby tabela z nowymi danymi wynikowymi zastąpiła w całości już istniejącą tabelę. W tym celu należy ustawić opcję replaceExistingData na TRUE.
Poniżej przedstawione są kroki niezbędne do skonfigurowania podstawowego zadania zastosowania modelu:
Utworzenie obiektu MiningApplyTask.
Ustawienie we właściwości model nazwy modelu (zgodnej z nazwą widniejącą w repozytorium).
Ustawienie danych wejściowych i wynikowych poprzez wskazanie odpowiednich obiektów PhysicalData we właściwościach sourceData (dane wejściowe) i targetData (dane wynikowe).
Utworzenie i przypisanie obiektu wynikowego ApplyOutput odpowiedniego typu, odpowiedniego do stosowanego modelu:
ApproximationApplyOutput
ClusteringApplyOutput
ClassificationApplyOutput
SurvivalApplyOutput
TimeSeriesApplyOutput
Należy ustawić przynajmniej jeden obiekt wynikowy.
W tym podrozdziale przedstawione są informacje dotyczące stosowania modeli, które zależą od rodzaju wykorzystywanej funkcji ekstrakcji danych.
klasy: ClassificationOutputType, ClassificationCategoryItem, ClassificationRankItem
Tabela 3.9. klasyfikacja - kombinacje elementów i typów wynikowych
typ wyniku | typ elementu wynikowego | opis |
---|---|---|
prawdopodobieństwo (probability) | rząd (rank) | zwraca prawdopodobieństwo n-tej najlepszej kategorii |
prawdopodobieństwo (probability) | kategoria (category) | zwraca prawdopodobieństwo zaklasyfikowania obserwacji do danej kategorii |
predictedCategory | rząd (rank) | zwraca n-tą najlepszą kategorię |
predictedCategory | kategoria (category) | niedostępne |
nodeId | rząd (rank) | zwraca identyfikator struktury, do której została przypisana dana obserwacja. Czym dokładnie jest "struktura" zależy od wykorzystywanego algorytmu; niektóre algorytmy nie dają możliwości przypisywania obserwacji do struktur. Bardziej szczegółowe informacje można znaleźć w rozdziale opisującym dany algorytm/moduł |
nodeId | kategoria (category) | niedostępne |
leverage, pearsonResidual, devianceResidual, dfbetas, c, cBar, deltaDev, deltaChiSq | regresja logistyczna (logistic regression) | zwraca statystykę obliczaną przez algorytm regresji logistycznej |
klasy: ApproximationOutputType
Tabela 3.10. Aproksymacja - kombinacje elementów i typów wynikowych
typ wyniku | typ elementu wynikowego | opis |
---|---|---|
predictedValue | aprox | zwraca przewidywaną wartość wyznaczoną przez model |
confidence | aprox | zwraca prawdopodobieństwo, że aproksymowana wartość jest poprawna; sposób obliczenia prawdopodobieństwa zależy od zastosowanego algorytmu; więcej informacji można znaleźć w rozdziale poświęconym danemu algorytmowi/modułowi |
cookDistance, covRatio, dfbetas, dffits, leverage, press, rstudentResidual, studentResidual | regresja liniowa | zwraca statystykę obliczaną przez algorytm regresji liniowej |
klasy: ClusterIdItem, ClusteringRankItem, ClusteringOutputType
Tabela 3.11. Analiza skupień - kombinacje elementów i typów wynikowych
typ wyniku | typ elementu wynikowego | opis |
---|---|---|
prawdopodobieństwo (probability) | rząd (rank) | zwraca prawdopodobieństwo n-tego najlepszego skupiska |
prawdopodobieństwo (probability) | clusterId | zwraca prawdopodobieństwo, że dana obserwacja należy do wskazanego skupiska |
clusterId | rząd (rank) | zwraca clusterId n-tego najlepszego skupiska |
clusterId | clusterId | zwraca identyfikator skupiska, do którego została przypisana dana obserwacja |
W przypadku tworzenia zadania zastosowania modelu przeżycia nie ma potrzeby dodawania żadnych elementów wynikowych. Wszystkie elementy wynikowe są określone poprzez ustawienie odpowiednich właściwości obiektu SurvivalApplyOutput. Są to:
Dolna granica przedziału czasowego, w którym będą obliczane wartości funkcji przeżycia.
Górna granica przedziału czasowego, w którym będą obliczane wartości funkcji przeżycia.
Liczba punktów czasowych pomiędzy pierwszy i ostatnim, w których będą obliczane wartości funkcji przeżycia.
Przedrostek, który zostanie dodany do nazw kolumn w tabeli wynikowej.
Tabela wynikowa będzie zawierała X kolumn o nazwach od prefix_0 do prefix_X-1, gdzie X jest równe ilości punktów czasowych (numberOfTimePoints).
W przypadku stosowania modeli przeżycia wykorzystywane jest także odwzorowywanie bezpośrednie atrybutów.
W przypadku tworzenia zadania zastosowania modelu opartego na szeregach czasowych nie ma potrzeby dodawania żadnych elementów wynikowych. Wszystkie elementy wynikowe są określone poprzez ustawienie odpowiednich właściwości obiektu TimeSeriesApplyOutput. Są to:
Przedrostek, który zostanie dodany do nazw kolumn w tabeli wynikowej.
ilość kolejnych punktów czasowych wykorzystanych do obliczenia prognozy.
Tabela wynikowa będzie zawierała następujące kolumny:
X kolumn o nazwach prefix_0 do prefix_X-1, gdzie X jest równe ilości punktów czasowych (numberOfTimePoints). Te zmienne zawierają przewidywane wariancje w kolejnych punktach czasowych.
regressed_mean - średnia dla liniowej składowej modelu obliczona na podstawie zmiennych niezależnych:
forecast_lowerbound/upperbound - dolna/górna granica przedziału ufności dla średniej i wariancji
W przypadku stosowania szeregów czasowych wykorzystywane jest także odwzorowywanie bezpośrednie atrybutów.
W tym podrozdziale przedstawione są przykłady stosowania modeli do danych w programie AdvancedMiner.
Poniższy skrypt tworzy model, który jest wykorzystywany przez kolejne przykłady. Dane są sztuczne i dotyczą hipotetycznego zagadnienia segmentacji zbioru klientów na grupę interesującą i nie interesującą na podstawie wartości atrybutów przypisanych każdemu klientowi.
Przykład 3.2. Prosty przykład zastosowania modelu
# sztuczne dane trenujace table 'dane_trenujace': id_klienta wiek region aktywa interesujacy 1 18 'A' 1500 'nie' 2 34 'A' 200 'nie' 3 15 'A' 100 'nie' 4 24 'A' 20000 'tak' 5 21 'A' 10000 'tak' 6 54 'B' 30000 'tak' 7 14 'B' 20000 'tak' 8 13 'B' 1200 'tak' 9 15 'B' 100 'tak' pd = PhysicalData('dane_trenujace') fs = ClassificationFunctionSettings() fs.logicalData = LogicalData(pd) fs.algorithmSettings = TreeSettings() # wykluczenie atrybutu id_klienta z budowy modelu att = fs.attributeUsageSet.getAttribute('id_klienta') att.setUsage(UsageOption.inactive) fs.targetAttributeName = 'interesujacy' bt = MiningBuildTask( 'pd', 'fs', 'model' ) save('bt', bt) save('fs', fs) save('pd', pd) execute('bt') model = load('model') for leaf in model.modelStatistics.allLeaves: # wyświetlenie kilku statystyk print "**Wezel %d, ilosc: %g" % (leaf.nodeID, leaf.count) print 'REGULA:' print leaf.nodeRule print 'Przewidywana wartosc:' print leaf.getPredictedValue() print '---'
Wynik:
**Wezel 1, ilosc: 4 REGULA: region IN ('B') Przewidywana wartosc: tak --- **Wezel 3, ilosc: 3 REGULA: region IN ('A') AND aktywa < 5 750.000 Przewidywana wartosc: nie --- **Wezel 4, ilosc: 2 REGULA: region IN ('A') AND aktywa >= 5 750.000 Przewidywana wartosc: tak ---
Kolejny skrypt tworzy i wykonuje zadania zastosowania modelu, który zwraca predykcję kategorii wynikowej dla każdej obserwacji.
Przykład 3.3. Podstawowy przykład modelu klasyfikacyjnego, przypisującego decyzę do wektora danych wejściowych
# sztuczne dane trenujące: table 'dane_trenujace': id_klienta wiek region aktywa interesujacy 1 18 'A' 1500 'nie' 2 34 'A' 200 'nie' 3 15 'A' 100 'nie' 4 24 'A' 20000 'tak' 5 21 'A' 10000 'tak' 6 54 'B' 30000 'tak' 7 14 'B' 20000 'tak' 8 13 'B' 1200 'tak' 9 15 'B' 100 'tak' pd = PhysicalData('dane_trenujace') fs = ClassificationFunctionSettings() fs.logicalData = LogicalData(pd) fs.algorithmSettings = TreeSettings() # pomiń atrybut id_klienta budując model att = fs.attributeUsageSet.getAttribute('id_klienta') att.setUsage(UsageOption.inactive) fs.targetAttributeName = 'interesujacy' bt = MiningBuildTask( 'pd', 'fs', 'model' ) save('bt', bt) save('fs', fs) save('pd', pd) execute('bt') #---------------------------------------------------- # przygotwanie i wykonanie zadania zastosowania # modelu przewidującego kategorię każdej # obserwacji #---------------------------------------------------- table 'nowi_klienci': wiek region aktywa 14 'A' 400 23 'B' 6500 78 'A' 500 24 'B' 10000 15 'B' 600 14 'B' 200 # klasyfikacyjny model ekstrakcji danych działający # na danych podobnych do tych ze zbioru data_to_apply classifierName = 'model' inputTableName = 'nowi_klienci' outputTableName = 'decyzje' save(inputTableName, PhysicalData(inputTableName) ) save(outputTableName, PhysicalData(outputTableName) ) task = MiningApplyTask() task.setReplaceExistingData(TRUE) task.applyOutput = ClassificationApplyOutput() # będzie jeden atrybut wynikowy dla każdej decyzji klasyfikatora, # zawierający kategorie target uznane przez algorytm jako # najlepsze (pierwszego rzędu) predictedItem = ClassificationRankItem('decyzja', ClassificationOutputType.predictedCategory, 0) task.applyOutput.item.add(predictedItem) task.modelName = classifierName task.sourceDataName = inputTableName task.targetDataName = outputTableName save('apply', task) # zapisz zadanie zastosowania modelu... execute('apply') # i je wykonaj # wyświetlenie wyników: print 'wynik' print 20*'_' trans None <- outputTableName: print '%s' % decyzja
Output:
wynik ____________________ nie tak nie tak tak tak
Skrypt poniżej pokazuje jak za pomocą modelu przetrwania wyznaczyć prawdopodobieństwo, że dane zdarzenie wystąpi w następnym punkcie czasowym.
Skrypt poniżej rozbudowuje poprzedni poprzez dodanie identyfikatora klienta i wykorzystanie odwzorowania atrybutów.
Przykład 3.5. Stosowanie modelu z odwzorowywaniem zmiennych
# sztuczne dane trenujace table 'dane_trenujace': id_klienta wiek region aktywa interesujacy 1 18 'A' 1500 'no' 2 34 'A' 200 'no' 3 15 'A' 100 'no' 4 24 'A' 20000 'yes' 5 21 'A' 10000 'yes' 6 54 'B' 30000 'yes' 7 14 'B' 20000 'yes' 8 13 'B' 1200 'yes' 9 15 'B' 100 'yes' pd = PhysicalData('dane_trenujace') fs = ClassificationFunctionSettings() fs.logicalData = LogicalData(pd) fs.algorithmSettings = TreeSettings() # excluding id attribute from model building att = fs.attributeUsageSet.getAttribute('id_klienta') att.setUsage(UsageOption.inactive) fs.targetAttributeName = 'interesujacy' bt = MiningBuildTask( 'pd', 'fs', 'model' ) save('bt', bt) save('fs', fs) save('pd', pd) execute('bt') #-------------------------------------------------- # przygotwanie i wykonanie zadania zastosowania # modelu przewidującego kategorię każdej # obserwacji #-------------------------------------------------- table 'nowi_klienci': id_klienta age kod_regionu aktywa_2 12 14 'A' 400 18 23 'B' 6500 11 78 'A' 500 16 24 'B' 10000 19 15 'B' 600 17 14 'B' 200 # model klasyfikacyjny ekstrakcji danych oparty na # zbiorze danych podobnyego do zbioru data_to_apply classifierName = 'model' inputTableName = 'nowi_klienci' outputTableName = 'decisions_table' save(inputTableName, PhysicalData(inputTableName) ) save(outputTableName, PhysicalData(outputTableName) ) task = MiningApplyTask() # Zmienna wynikowa 'id' będzie kopią zmiennej wejściowej # 'id_klienta', dzięki czemu będzie możliwe porównywanie # odpowiednich wierszy w tabeli wejściowej i wynikowej task.directMapping.add( ApplySourceItem('id_klienta', 'id') ) # Dwie kolumny w tabeli wynikowej 'nowi_klienci' maja inne nazwy # od podanych w sygnaturze modelu. Jesli nie zostanie określone # odwzorowanie, zmienne te przyjmą wartości NULL task.modelAssignment.assignment.add( SignatureAssignment( 'kod_regionu', 'region' ) ) task.modelAssignment.assignment.add( SignatureAssignment( 'aktywa_2', 'aktywa' ) ) task.applyOutput = ClassificationApplyOutput() task.setReplaceExistingData(TRUE) # Jeden atrybut będzie zawierał decyzję klasyfikatora: kategorie # zmiennej 'target' wybrane przez algorytm jako najlepsze # (pierwszego rzędu) predictedItem = ClassificationRankItem('decyzja', ClassificationOutputType.\ predictedCategory, 0) task.applyOutput.item.add( predictedItem ) task.modelName = classifierName task.sourceDataName = inputTableName task.targetDataName = outputTableName save( 'apply', task ) execute( 'apply' ) # wyświetlenie wyników print 'id\tdecyzja' print 20*'_' trans None <- outputTableName: print '%d\t%s' % (id, decyzja)
Wynik:
id decyzja ____________________ 12 no 18 yes 11 no 16 yes 19 yes 17 yes
Ten skrypt pokazuje jak zmienić pozytywny (dobry) próg klasyfikacji na 0.3
Przykład 3.6. Changing the classification threshold
# Ten skrypt nie jest kompletny. Wymagane są tabela z danymi # i zadanie ao = ClassificationApplyOutput() ao.item.add( ClassificationRankItem( 'prawd_dobrej_kat', ClassificationOutputType.\ probability, 0) ) trans 'wynik' <- 'tabela_wynikow': drop out prawd_dobrej_kat if prawd_dobrej_kat > 0.3: target = 'dobry' else: target = 'zly'
W skrypcie poniżej przykładowy system ekspercki proponuje alternatywną decyzję (tzn. drugą w kolejności) w przypadku, gdy prawdopodobieństwo pierwszej decyzji jest zbyt niskie (mniejsze lub równe 0.7).
Przykład 3.7. An advice system with secondary decision suggestion
# Ten skrypt nie jest kompletny. Wymagane są tabela z danymi # i zadanie ao = ClassificationApplyOutput() ao.item.add( ClassificationRankItem('pierwsza_decyzja', ClassificationOutputType.\ predictedCategory, 0) ) ao.item.add( ClassificationRankItem('pierwsza_decyzja_prob', ClassificationOutputType.\ probability, 0) ) ao.item.add( ClassificationRankItem('druga_decyzja', ClassificationOutputType.\ predictedCategory, 1) ) trans 'wynik' <- 'tabela_wynikow': drop out pierwsza_decyzja_prob if pierwsza_decyzja_prob > 0.7: druga_decyzja = None