Kod scoringowy dla modeli

Ta sekcja opisuje generowanie kodu scoringowego w oparciu o modele. Zakładamy, że użytkownik zapoznał się z budową modelu (patrz rozdział AdvancedMiner w Praktyce i częścią Moduły).

Kod scoringowy jest generowany dla istniejącego modelu. Jednakże możliwe jest również, aby wygenerować kod bez modelu. W takim przypadku użytkownik musi napisać cały kod scoringowy ręcznie.

Wymagania

Jedynym wymogiem jest użycie modelu, dla którego generowanie kodu scoringowego ma być wykonane/wspierane.

Tabela 10.1. Moduły AdvancedMiner wspierając generowanie kodu scoringowego

Nazwa modułuWsparcie generowania kodu scoringowego
Drzewa Klasyfikacyjnetak
KŚrednich (KMeans)tak
Analiza Dyskryminacyjnatak
Sieci Neuronowetak
Sieci Kohonenatak
Regresja Liniowatak
Regresja Logistycznatak
Bivariatetak
Analiza Przeżycia (Survival Analysis)tak
Szeregi Czasowe (Time Series)tak
Karta Scoringowanie

Tworzenie kodu scoringowego w Java opartego na modelu krok po kroku

Ten przykład tworzenia kodu scoringowego jest oparty na modelu zbudowanym przy użyciu algorytmu grupowania KŚrednich (KMeans). Zakłada się, że użytkownik ma już zbudowany model za pomocą tego algorytmu.

W pierwszym kroku tworzone jest zadanie (task), który generuje kod scoringowy.

Rysunek 10.1. ScoringCodeBuildTask z listy dostępnych Task

ScoringCodeBuildTask z listy dostępnych Task

Następnie ustawiane są następujące właściwości:

Tabela 10.2. Właściwości ScoringCodeBuildTask

Nazwa własnościOpis
Code LanguageJęzyk programowania używany do kodu scoringowego
Can Generate With Compilation Errors Jeśli ta opcja jest ustawiona, wówczas model scoringowy zostanie utworzony mimo błędów kompilacji. Jeśli ta opcja nie jest zaznaczona, w przypadku błędów w kodzie scoringowym, kod scoringowy dla modelu nie zostanie utworzony.

Następnie ustaw następujące wartości ScoringCodeBuildTask w Repozytorium

Tabela 10.3. ScoringCodeBuildTask właściwości

Nazwa własnościOpis
Input Model Nazwa modelu wejściowego na podstawie którego ma zostać utworzony kod scoringowy. Jeśli ta właściwość jest pusta, kod scoringowy będzie składać się tylko z pustego szablonu, który musi być wypełniony ręcznie przez użytkownika.
Output Model Nazwa modelu wyjściowego. Model ten można wykorzystać do ScoringCodeApplyTask
Transformation Transformacja. Transformacja ta zostanie zawarta w kodzie scoringowym.

Rysunek 10.2. ScoringCodeBuildTask jest gotowy do wykonania

ScoringCodeBuildTask jest gotowy do wykonania

Po dostosowaniu ustawień zadanie budujące kod scoringowy może być wykonane w sposób standardowy.

Jeśli kod został oparty na modelu nie powinno być żadnych błędów kompilacji, ponieważ składnia kodu jest sprawdzany na tym etapie. Funkcjonalna poprawność nie jest weryfikowana na tym etapie.

Model utworzony w tym etapie ma następujące właściwości:

Tabela 10.4. ScoringCodeModel - właściwości

Nazwa własnościOpis
Code Body Generuje kod scoringowy. Jest to samodzielny kod klasy Java o nazwie ScoringCode. Szczegóły znajdują się w sekcji Architektura kodu scoringowego w Java .
Code Language Język używany do generowania kodu scoringowego. Ten własność nie może być modyfikowana. Powinna być ustawiona w procesie generacji.
Missing Values Supported Flaga ta jest ustawiana przez wygenerowany kod i jest używany wyłącznie w celach informacyjnych. Flaga jest ustawiona na 'true', jeśli kod scoringowy współpracuje z brakującymi wartościami, a 'false' w przeciwnym wypadku.

Korzystanie z transformacji w kodzie scoringowym

Zazwyczaj dane pobrane z bazy danych lub hurtowni danych nie mogą być natychmiast wykorzystane w modelu. Jest to spowodowane brakującymi wartościami, wartościami nieznormalizowanymi lub innymi czynnikami. Transformacja jest stosowana do przygotowania danych do przetwarzania. Kod transformacji dodaje się do klasy ScoringCode jako metoda. Metoda ta jest wykonywana w podanej kolejności przed metodą processRow. Szczegóły są w sekcji Architektura kodu scoringowego w Java . Użytkownik musi dostarczyć dane wejściowe zgodnie z Input signature.

Mapowanie atrybutów może odbywać się na dwa sposoby. Zależy to od tego, czy kod zawiera transformacje, czy nie.

  • Pierwsza możliwość: Nie ma transformacji w kodzie. Dane są zgodne z InputSignature, który jest taki sam jak Signature.

  • Druga możliwość: Kod zawiera transformacje. Dane są odwzorowywane według InputSignature. Następnie kod transformacja jest wykonywany. Następnie dane są odwzorowywane według Signature.

Architektura kodu scoringowego w Java

Poprawny kod scoringowy składa się z klasy o nazwie ScoringCode która zawiera następujące elementy:

  • publiczna statyczna klasa InputSignature

  • publiczna statyczna klasa Signature

  • publiczna statyczna klasa OutputStructure

  • publiczna metoda prepareDataemphasis>

  • publiczna metoda processRow

  • opcjonalnie, metoda scoreData, który wykonuje prepareData i processRow.

Wszystkie te elementy są opisane w podrozdziale poniżej.

Poniżej jest przykład kodu scoringowego z transformacją opartego na modelu zbudowanym przy użyciu algorytmu grupowania KŚrednich (KMeans):

Przykład 10.1. Kod scoringowy z transformacjami oparty na algorytmie K-średnich

import java.util.HashMap;

public class ScoringCode {

        /** Tymczasowe mapowanie stosowane metodą prepareData */
        private HashMap tempInput = new HashMap();

        /** Tymczasowe mapowanie stosowane metodą prepareData */
        private HashMap tempOutput = null;

        /** Transformacja obiektu */
        private Transformation0 trans0 = new Transformation0();

        /** scoreData jest główną metodą scorowania. Dane wejściowe muszą być dostarczone w odpowiedniej kolejności.
         * Proszę zajrzeć do InputSignature aby zobaczyć, które typy danych są obsługiwane i jak zapewnić dane w odpowiedniej kolejności.
         * Transformacja (jeśli dotyczy) jest tworzona przez metodę prepareData. Metoda ta także zajmuje się kodowaniem kategorycznych zmiennych
         * @param input - zbió wejściowy do scorowania
         * @param output - OutputStructure - będzie zawierać wynik scoringu
         */
        public void scoreData(Object [] input, OutputStructure output) {
                processRow(prepareData(input), output);
        }

         /** getCategoricalValueCode - dostaje zakodowaną podwójną wartość odpowiadającą catgorical
        */
        public double getCategoricalValueCode(HashMap data, String attrName, int attrIndex) {
                double output=Double.NaN;                for(int i=0; i<Signature.INPUT_ATTRIBUTES_VALUE_SET[attrIndex].length; i++){
                        if(data.get(attrName).equals(Signature.INPUT_ATTRIBUTES_VALUE_SET[attrIndex][i])){
                                output=i;
                                break;
                        }
                }
                if( output==Double.NaN )
                        throw new RuntimeException("Value "+tempOutput.get(attrName).toString()+" is not in input attributes  value set");
                return output;
        }

         /** prepareData - przygotowuje dane dla metody processRow. 
		  * To wykonuje wszystkie niezbędne mapowanie, transformacje i kodowania 
	      * atrybutów kategorycznych.
          * @param inputData - dostarcza we właściwy sposób posortowane dane do scorowania - według InputSignature
          * @return - tablica podwójnych rezultatów
          */
        public double [] prepareData(Object [] inputData) { 

                tempInput.clear();

                //Mapowanie atrybutów wejściowych
                tempInput.put("x", inputData[0]);
                tempInput.put("y", inputData[1]);
                tempInput.put("z", inputData[2]);

                tempOutput =  trans0.transformRow(tempInput);

                //Mapowanie atrybutów wyjściowych
                double [] output = new double[3];

                //Wywołanie wyjściowej tabeli z Double.NaN's
                java.util.Arrays.fill(output, Double.NaN);

                if(tempOutput.get("x") != null )
                        if(tempOutput.get("x") instanceof Number)
                                output[0]=((Number)tempOutput.get("x")).doubleValue();
                        else
                                throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

                if(tempOutput.get("y") != null )
                        if(tempOutput.get("y") instanceof Number)
                                output[1]=((Number)tempOutput.get("y")).doubleValue();
                        else
                                throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

                if(tempOutput.get("z") != null )
                        if(tempOutput.get("z") instanceof Number)
                                output[2]=((Number)tempOutput.get("z")).doubleValue();
                        else
                                throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

                return output;
        }
        /** InputSignature zawiera sygnaturę danych, która ma być przekazana do metody scoreData.
        * Struktura ta pokazuje atrybuty w parach typu name i ich właściwej kolejności w danych wejściowych
        */
        public static class InputSignature {
                 public static Object [][] INPUT_ATTRIBUTES = new Object [][] {
                        {"x", Number.class },         // inputRow[0]
                        {"y", Number.class },         // inputRow[1]
                        {"z", Number.class }        // inputRow[2]
                };
        }

        /** Signature - klasa ta opisuje jak dane powinny być przekazywane do metody processRow 
        * przez Transformacje. Jeśli nie ma transformacji jest taki sam, jak InputSignature. 
        * Struktura ta pokazuje atrybuty w parach nazwa-typu i odpowiedniej kolejności w danych wejściowych
        *  Przedstawiono również zestaw ustawiania kategorycznych wartości:
        */
        public static class Signature {

                /** INPUT_ATTRIBUTES - tablica ta zawiera pary nazwa-typ, które opisują wejściowe atrybuty
                 * Liczba w komentarzu reprezentuje poprawną pozycję określonego atrybutu w danych wejściowych
                 */
                 public static Object [][] INPUT_ATTRIBUTES = new Object [][] {
                        {"x", double.class },         // inputRow[0]
                        {"y", double.class },         // inputRow[1]
                        {"z", double.class }        // inputRow[2]
                };


                /** INPUT_ATTRIBUTES_VALUE_SET zawiera informacje na temat kodowania atrybutów kategorycznych
                 * Kody dla wartości są przypisane według kolejności atrybutów w tablicy. Pierwszy atrybut ma kod równy 0,
                 * drugi atrybut ma kod równy 1, i tak dalej.
                 */
                 public static Object [][] INPUT_ATTRIBUTES_VALUE_SET = new Object [][] {
                        { null },         // x value set -> inputRow [0]
                        { null },         // y value set -> inputRow [1]
                        { null }        // z value set -> inputRow [2]
                };

        }


        /** OutputStructure załącza informacje o nazwach i typach, które mogą być uzyskane z metody processRow.
         * Struktura ta może zawierać następujące typy: double, int, string, double [], int [].
         * OutputStructure jest używane przez AdvancedMiner aby określić dane wyjściowe.
         */
        public static class OutputStructure
 {

                public int clusterID;
                public double[] distance = new double [3];

        }
        /////////////////////////// DATA TAKEN FROM AdvancedMiner MODEL //////////////////////////////////////
        public final int clustersCount = 3;
        public final int clustersCoordinatesCount = 3;
        protected double clustersCoordinates[][] = new double[clustersCount][clustersCoordinatesCount];

        /////////////////////////////////////  SCORING CODE ////////////////////////////////////////////
        /** calculateDistance - metoda ta jest stosowana do obliczenia odległości między
         * sampleCoordinates i klastrem określonym przez clusterID
         * @param sampleCoordinates - tablica sampleCoordinates
         * @param clusterID - klaster okreslony przez clusterID
         * zwraca odległość
         */
        protected double calculateDistance(double [] sampleCoordinates, int clusterID) {
                double distance=0;
                for(int i=0; i<clustersCoordinatesCount; i++) {
                        double dx = sampleCoordinates[i]-clustersCoordinates[clusterID][i];
                        distance+=(dx*dx);
                }
                return Math.sqrt(distance);
        }

        /** processRow - współpracuje z pojedynczym wierszem danych.
         * Dane zwracane przez metodę processRow są umieszczony na wyjściu OutputStructure
         * <b>Uwagi:<b>
	     * Nie należy używać tej funkcji, wykorzystuje odwzorowane i koduje wartości w podwójnej tablicy. Lepiej użyć metody scoreData.
         * @param input - tablica danych
         * @param output - struktura ta będzie wynikiem scoringu
         */
        public void processRow(double [] input, OutputStructure output) {
                //Input data checking
                for(int i=0; i<input.length; i++){
                        if(input[i]==Double.NaN)
                                throw new RuntimeException("Non numerical input data not supported");
                }
                if(input.length != clustersCoordinatesCount)
                        throw new RuntimeException("Input array size doesn't match clusters count ("+clustersCount+")");
                //Computing distances between input data and cluster coordinates
                double minDistance = 0;
                int bestClusterID = 0;
                for(int i=0; i<clustersCount; i++) {
                        double distance = calculateDistance(input, i);
                        if(i == 0)
                                minDistance = distance;
                        else
                                if(distance < minDistance) {
                                         minDistance = distance;
                                        bestClusterID = i;
                                }
                        output.distance[i]=distance;
                }
                //Calculated best cluster identifier is assigned to output
                output.clusterID = bestClusterID;
        }
        ///////////////////////////////////  END OF SCORING CODE //////////////////////////////////////////
        /**Transformation0 - transformacja.
         * Transformacja używa HashMaps więc mapowanie atrybutów nie jest potrzebne.
         */
        public static class Transformation0 {
                public Transformation0(){}

                /** transformRow - przekształca jeden wiersz danych
                 * @param inputRow - wejściowy wiersz danych w HashMap
                 * @zwraca mapowany wiersz danych w HashMap
                 */
                public HashMap transformRow(HashMap inputRow) {
                        HashMap outputRow = new HashMap();

                        outputRow.putAll(inputRow);

if (inputRow.get("z") == null) {
         outputRow.put("z", new Double(7.6));
}
else
        outputRow.put("z", inputRow.get("z"));

if (inputRow.get("y") == null) {
         outputRow.put("y", new Double(6.6));
}
else
        outputRow.put("y", inputRow.get("y"));

if (inputRow.get("x") == null) {
         outputRow.put("x", new Double(7.4));
}
else
        outputRow.put("x", inputRow.get("x"));

                        return outputRow;
                }
        }
        public ScoringCode() {
                clustersCoordinates[0][0] = 5.666666666666667;
                clustersCoordinates[0][1] = 3.3333333333333335;
                clustersCoordinates[0][2] = 4.333333333333333;
                clustersCoordinates[1][0] = 10.877564619118836;
                clustersCoordinates[1][1] = 9.53952535719102;
                clustersCoordinates[1][2] = 7.950674407041298;
                clustersCoordinates[2][0] = 10.0;
                clustersCoordinates[2][1] = 11.5;
                clustersCoordinates[2][2] = 12.5;
        }
}
    

Sygnatury danych

Kod scoringowy zawiera dwie wejściowe sygnatury:

  • InputSignature jest sygnaturą dla wejściowych danych. Opisuje kolejność i typy danych, które są w danych wejściowych określonych dla metody scoreData (zestaw danych jest w tabeli Java Objects, może to być również jako dane wejściowe dla metody prepareData w przypadku, gdy metoda ta jest wykonywana z API).

  • Signature opisuje kolejność i typy danych wejściowych dla metody processRow. Metoda processRow odwzorowuje dane i koduje kategoryczne atrybuty.

Klasa InputSignature

Klasa InputSignature zawiera publiczną statyczną dwuwymiarową tabelę o nazwie INPUT_ATTRIBUTES. Zawiera ona informacje na temat nazw i typów wszystkich atrybutów. Komentarze w kodzie zawierają informacje o właściwej kolejności atrybutów wejściowych.

public static class InputSignature {
    public static Object [][] INPUT_ATTRIBUTES = new Object [][] {
        {"x", Number.class },         // inputRow[0]
        {"y", Number.class },         // inputRow[1]
        {"z", Number.class }          // inputRow[2]
        };
    }
                        

Pierwszy element w każdym wierszu tabeli INPUT_ATTRIBUTES jest nazwą atrybutu. Wartość ta jest zawarta w obiekcie String. Drugi element w wierszu jest nazwą klasy, który reprezentuje typ atrybutu. Rodzaj atrybutu zależy od danych wejściowych w modelu lub transformacji.

Jeśli są transformacje w kodzie scoringowym, InputSignature opisuje podpisanie pierwszej transformacji.

Klasa Signature

Klasa Signature zawiera co najmniej dwie dwuwymiarowe tablice. Pierwsza jest nazwana INPUT_ATTRIBUTES i opisuje kolejność i typy atrybutów w danych wejściowych. Ta tabela jest podobna do tabeli INPUT_ATTRIBUTES w klasie InputSignature .

Typy atrybutów mają dokładniejszy sposób reprezentacji (przykład double.class).Kolejność atrybutów jest inna niż w InputSignature.

Druga tabela w Signature jest nazywana INPUT_ATTRIBUTES_VALUE_SET. Ta tabela jest publiczną statyczną dwuwymiarową tabelą. Jeden wiersz w tej tabeli odpowiada za jeden atrybut. W źródłowym kodzie scoringowym każdy wiersz tej tabeli jest skomentowany. Komentarze zawierają informacje o atrybucie, który dotyczy zestawu danych.

W przypadku atrybutów numerycznych będą wartości NULL w INPUT_ATTRIBUTES_VALUE_SET. W przypadku kategorycznych atrybutów będzie zawierać wszystkie możliwe wartości atrybutu. Indeksy tych wartości są wykorzystywane do kodowania tego atrybutu w metodzie prepareData. To znaczy dla zbioru {"Alpha", "Beta", "Theta"}, "Alpha" będzie kodowany jako 0, "Beta" jako 1 i tak dalej.

public static class Signature {

    /** INPUT_ATTRIBUTES - ta tablica zawiera nazwy-typy par, które opisują atrybuty wejściowe
     * Liczba w komentarzu reprezentuje poprawną pozycję określonego atrybutu w danych wejściowych
     */
     public static Object [][] INPUT_ATTRIBUTES = new Object [][] {
            {"x", double.class },         // inputRow[0]
            {"y", double.class },         // inputRow[1]
            {"z", double.class }          // inputRow[2]
    };


    /** INPUT_ATTRIBUTES_VALUE_SET - zawiera informacje na temat kodowania atrybutów kategorycznych
     * Kody dla wartości są przypisane według kolejności atrybutów w tablicy. Pierwszy atrybut ma kod równy 0,
     * drugi atrybut ma kod równy 1, i tak dalej.
     */
     public static Object [][] INPUT_ATTRIBUTES_VALUE_SET = new Object [][] {
            { null },         // x value set -> inputRow [0]
            { null },         // y value set -> inputRow [1]
            { null }        // z value set -> inputRow [2]
    };

 }
                    

Ta konstrukcja 'input signature' gromadzi informacje o sposobie automatycznego przygotowywania danych wejściowych.

Klasa OutputStructure

OutputSturcture zawiera specyfikację wyniku modelu. Może zawierać typy proste lub tablice typów prostych. Ciąg tablic obiektów nie może być stosowany.

  
/** OutputStructure załącza informacje o nazwach i typach, które mogą być uzyskane z metody processRow.
    * Struktura ta może zawierać następujące typy: double, int, string, double [], int [].
    * OutputStructure jest używane przez AdvancedMiner aby określić dane wyjściowe.
    */
public static class OutputStructure
{

    public int clusterID;
    public double[] distance = new double [3];

}
                

Metoda scoreData

Scoring dzieli się na dwa etapy. Pierwszym etap to przygotowanie danych wejściowych (na przykład kodowanie atrybutów kategorycznych, realizacja szeregu transformacji (to jest dodatkowe)). Drugi etap to przetwarzanie danych. Wszystkie te czynności są zawarte w metodzie scoreData Metoda ta jest wywoływana dla każdego wiersza danych.

/** scoreData jest to główna metoda scoringu. Dane wejściowe muszą być dostarczone w odpowiedniej kolejności.
 * Sprawdź InputSignature aby zobaczyć, które typy danych są obsługiwane i jak dostarczyć dane w odpowiedniej kolejności.
 * Transformacje (jeśli dotyczy) są wykonywane w metodzie prepareData. Metoda PrepareData zajmuje się również kodowaniem danych
 * @param input - dane wejściowe do scorowania
 * @param output - OutputStructure - zawiera scoring output
 */
public void scoreData(Object [] input, OutputStructure output) {
        processRow(prepareData(input), output);
}
                

Początek nazywa się prepareData, dalsza część nazywa się processRow.

Metoda scoreData pobiera dane wejściowe jako tabele obiektów. Rodzaje obiektów i kolejność jest w zgodzie z InputSignature.

Dane wyjściowe dla każdego wiersza są zwracana w OutputStructure.

Metoda prepareData

Metoda prepareData jest odpowiedzialna za wstępne przetwarzanie danych i przekazywanie danych w odpowiedniej formie do metody processRow. Przykład poniżej ilustruje metodę prepareData z ciągiem transformacji

Pierwszym krokiem jest mapowanie danych zgodnie z InputSignature i wykonanie łańcucha transformacji.

Po transformacji danych jest ponowne mapowanie danych, tym razem według Signature. Wreszcie tabela podwójnych wartości jest zwracana.

 
/** prepareData - przygotowuje dane dla metody processRow. 
    * To wykonuje wszystkie niezbędne mapowanie, transformacje i kodowania 
	* atrybutów kategorycznych.
    * @param inputData - dostarcza we właściwy sposób posortowane dane do scorowania - według InputSignature
    * @return - tablica podwójnych rezultatów
    */
public double [] prepareData(Object [] inputData) { 

        tempInput.clear();

        //Mapowanie atrybutów wejściowych
        tempInput.put("x", inputData[0]);
        tempInput.put("y", inputData[1]);
        tempInput.put("z", inputData[2]);

        tempOutput =  trans0.transformRow(tempInput);

        //Mapowanie atrybutów wyjściowych
        double [] output = new double[3];

        //Wywołanie wyjściowej tabeli z Double.NaN's
        java.util.Arrays.fill(output, Double.NaN);

        if(tempOutput.get("x") != null )
                if(tempOutput.get("x") instanceof Number)
                        output[0]=((Number)tempOutput.get("x")).doubleValue();
                else
                        throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

        if(tempOutput.get("y") != null )
                if(tempOutput.get("y") instanceof Number)
                        output[1]=((Number)tempOutput.get("y")).doubleValue();
                else
                        throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

        if(tempOutput.get("z") != null )
                if(tempOutput.get("z") instanceof Number)
                        output[2]=((Number)tempOutput.get("z")).doubleValue();
                else
                        throw new RuntimeException("Data type doesn't match to data type specified in inputSignature. Can't continue. ");

        return output;
}
                

Metoda processRow

Metoda processRow wykonuje główne przetwarzanie danych. Przykładowy wykaz processRow przedstawiono poniżej. Parametrami tej metody są tabele danych dwuwartościowych i struktury w której wartości wyjściowe są zapisywane.

Metoda ta częściowo weryfikuje poprawność danych. Generator kodu scoringowego tylko musi wiedzieć, czy typ danych jest numerycznych czy porządkowy. Wartości liczbowe są przechowywane jako double i kategoryczne jako string. Kolejność atrybutów w zbiorze danych nie jest weryfikowana. Metoda processRow oczekuje atrybutów w kolejności określonej w Signature.

Nie zaleca się stosowania tej metody bezpośrednio, ponieważ wymaga danych, które mają być przygotowane w sposób szczególny. Jest to bezpieczniejsze i łatwiejsze stosowanie metody scoreData. Jeśli jest to konieczne, aby wywołać tę funkcję bezpośrednio, nalezy to zrobić metodą prepareData i jej wynik powinien być użyty jako parametr dla metody processRow.

  
/** processRow - współpracuje z pojedynczym wierszem danych.
    * Dane zwracane przez metodę processRow są umieszczony na wyjściu OutputStructure
    * <b>Uwagi:<b>
	* Nie należy używać tej funkcji, wykorzystuje odwzorowane i koduje wartości w podwójnej tablicy. Lepiej użyć metody scoreData.
    * @param input - tablica danych
    * @param output - struktura ta będzie wynikiem scoringu
    */
public void processRow(double [] input, OutputStructure output) {
        //Sprawdzanie danych wejściowych
        for(int i=0; i<input.length; i++){
                if(input[i]==Double.NaN)
                        throw new RuntimeException("Non numerical input data not supported");
        }
        if(input.length != clustersCoordinatesCount)
                throw new RuntimeException("Input array size doesn't match clusters count ("+clustersCount+")");
        //Obliczanie odległości między danymi wejściowymi i współrzędnych klastrowymi
        double minDistance = 0;
        int bestClusterID = 0;
        for(int i=0; i<clustersCount; i++) {
                double distance = calculateDistance(input, i);
                if(i == 0)
                        minDistance = distance;
                else
                        if(distance < minDistance) {
                                    minDistance = distance;
                                bestClusterID = i;
                        }
                output.distance[i]=distance;
        }
        //Obliczone najlepszego identyfikator klastra i jest przypisanie go jako wyniku
        output.clusterID = bestClusterID;
}
                

Wykonywanie kodu scoringowego dla modelu

Wykonanie scoringu danych za pomocą kodu scoringowego jest podobne do stosowanie modelu z ApplyTask. Jedyna różnica między tymi zadaniami jest taka, że w przypadku kodu scoringowego (ScoringCodeApplyTask) nie ma elementu ApplyOutput, ponieważ zestaw danych wyjściowych jest zdefiniowany w kodzie scoringowym. Struktura wyjścia/rezultatu jest określona w OutputStructure .

Tabela 10.5. Właściwości ScoringCodeApplyTask

Nazwa własnościOpis
Replace Existing Data Jeśli ta opcja jest ustawiona i Apply Target Data wskazuje na istniejąc dane, struktura danych będzie zmieniona i dane zostaną zastąpione.

Tabela 10.6. Obiekty do ustawienia w ScoringCodeApplyTask

StatusNazwaOpisTyp
includeddirectMapping obiekt, który określa, które kolumny ze scorowanego zbioru powinny pojawić się w zestawie wyników. Wybrane kolumny zostaną skopiowane do zbioru wynikowego własny
includedmodelAssignment obiekt uzywany do mapowania zmiennych na zmienne signature własny
obligatoryapplyOutput obecnie nie używany przez ScoringCodeApplyTaskwłasny
obligatorysourceDatazbiór danych do scorowania przez nazwę
obligatorytargetData zbiór, który będzie przechowywać wyniki scorowania przez nazwę
obligatorymodel model w repozytorium, utworzony jako wynik SCBT przez nazwę

Kiedy parametry są ustawione ScoringCodeApplyTask może być wykonany.

Podczas wykonywania ScoringCodeApplyTask kod scoringowy jest kompilowany i sprawdzany. Następujące elementy są weryfikowane podczas wykonywania:

Następnie dla każdego wiersza ze zbioru wejściowego następujące akcje są wykonane:

  1. przygotowanie danych zgodnie z InputSignature

  2. wykonanie metody prepareData (data preprocessing)

  3. petwarzanie danych z metody processRow

  4. zapisanie OutputStructure do tabeli wyjściowej

  5. zapisanie danych z DirectMapping do tabeli wyjściowej

Różnice w kodzie scoringowym dla różnych modeli

Kod scoringowy zależy od modułów na wiele sposobów. Procedury scoringowe i możliwe wyniki nie są takie same. Tabela poniżej przedstawia wyniki i ich opisy dla każdego typu modelu.

Tabela 10.7. Wyniki kodu scoringowego

ModelPole wynikoweOpis pola wyniku
Bivariatetarget1Score liniowy scor dla zmiennej target1
target2Score liniowy scor dla zmiennej target2
predictedConditionalProbability przewidywane warunkowe prawdopodobieństwo pozytywnej wartości zmiennej target1 pod warunkiem pozytywnej wartości zmiennej target2
predictedJointProbability przewidywane łączne prawdopodobieństwo pozytywnej wartości obu zmiennych target1 i target2
Model Analizy DyskryminacyjnejdiscriminantScore (double) przewidywane wartości liniowej funkcji dyskryminacyjnej. Wartość ta powinna być porównana z progiem dla uzyskania klasyfikacji przewidywania kategorii
Sieci Neuronowe output (double[]) tablica wartości wyjściowych wszystkich neuronów w warstwie wyjściowej
KŚrednichclusterID (int) najlepszy klaster zidentyfikowany (tj. dla którego odległość pomiędzy obserwacją i ciężkości klastra jest minimalna)
distance (double[]) tablica z odległościami między obserwacjami i wszystkimi środkami klastrów
Sieci KohonenaclusterID (String) Id najlepszego klastra, czyli tego o minimalnej odległości pomiędzy jego środkiem i obserwacją
distance (double) odległość pomiędzy obserwacją i najlepszym klastrem
Regresja liniowapredictedTargetValue (double) przewidywana wartość atrybutu
Regresja LogistycznapositiveCategoryProbability (double) przewidywane prawdopodobieństwo pozytywnej kategorii
Model dlaszego życia (Survival)survivalTimeProbability (double[]) przewidywane prawdopodobieństwa funkcji przeżywalność w każdym punkcie czasowym z danych treningowych (określone w tablicy timeMap).
Drzewa klasyfikacyjnepredictedTargetIndex (int) Wskaźnik przewidywanej kategorii docelowej; kolejność kategorii docelowej jest taka sama, jak w tabeli Signature.OUTPUT_TARGET_VALUES.
predictedTargetValue (TARGET_TYPE) przewidywana kategoria
nodeId (int) id najlepszego liścia dla obserwacji
probabilities (double[]) tabela z prawdopodobieństwami aposteriori dla każdej kategorii docelowej. Kolejność elementów jest taka sama jak w tabeli Signature.OUTPUT_TARGET_VALUES.
Szeregi Czasowe (Time Series)regressedMean (double) liniowy score oblicza się z części liniowej modelu GARCH
forecastedVariance (double) prognoza modelu wartości wariancji w punkcie czasowym t + 1
forecastLowerBound (double) dolna granica przedziału ufności dla prognozowanej wariancji w punkcie czasowym t + 1;
forecastUpperBound (double) górna granica przedziału ufności dla prognozowanej wariancji w punkcie czasowym t + 1;
actualValue (double) wartość targetu