Dziś chciałem się napisać parę słów o tym o czym stosunkowo rzadko piszę, a mianowicie o eksploracji danych aka. Data Miningu. Obecnie pojęcie to niejako “przycichło” zagłuszone przez nowe slogany w stylu “Data Science” czy “Machine Learning” ale czy przestało być aktualne? Z całą pewnością nie ponieważ wszystkie te terminy mają coś ze sobą wspólnego, a stare dobre algorytmy eksploracyjne mają się bardzo dobrze. Bohaterem dzisiejszego wpisu jest jeden z najprostszych algorytmów dostępnych w Analysis Services tj. Naiwny klasyfikator Bayesa – zapraszam do lektury! Przy okazji chciałbym wspomnieć o tym, iż nie będę zbytnio zagłębiał się w matematyczną strukturę algorytmu (o której możecie przeczytać tutaj) – przyjmijmy, iż teoria ta będzie przez nas traktowana jako czarna skrzynka – jednakże polecam się z nią zapoznać gdyż nie jest taka straszna jak może się wydawać, a pozwala dokładnie zrozumieć opisywany algorytm.
Na początku zastanówmy się nad nazwą algorytmu – po pierwsze występuje w nim słowo klasyfikator tak więc służy do klasyfikacji na podstawie cech danego przypadku, po drugie Bayesa ponieważ opiera się na teorii Bayesa, po trzecie naiwny ponieważ zakłada niezależność cech danego przypadku. Upraszczając niezależność cech polega na tym że np. w przypadku gdy klasyfikujemy osoby do poszczególnych zawodów to osoba która ma dużą masę mięśniową i dużo ćwiczy na siłowni może być uznana z dużym prawdopodobieństwem za kulturystę. Przy czym w klasyfikatorze Bayesa obie te cechy zwiększają prawdopodobieństwo mimo, iż jedna może wynikać z drugiej – dlatego też algorytm ten nazywa się naiwnym. Tak więc nasz algorytm przypisuje czy też klasyfikuje przypadki do predefiniowanych grup. Aby go uruchomić musimy mu dostarczyć tzw. zbiór treningowy aby później przełożyć zależności wykryte w zbiorze treningowym na nowe niezaklasyfikowane jeszcze przypadki.
Przejdźmy do praktyki – stwórzmy nowy projekt w Data Tools wybierając typ Analysis Services Multidimensional and Data Mining tak jak zostało to przedstawione na poniższym zrzucie ekranowym.
Następnie stwórzmy sobie nowe źródło danych klikając prawym przyciskiem myszy na Data Sources i z menu kontekstowego wybierając New Data Source. Naszym oczom powinien ukazać się prosty kreator gdzie musimy po prostu wybrać New i zdefiniować połączenie do naszej źródłowej bazy danych (standardowo wykorzystamy AdventureWorksDW2014).
Następnie należy wskazać sposób uwierzytelnienia do źródła (preferowaną opcją jest to aby konto na którym działa usługa miało uprawnienia do źródłowej bazy danych):
Po stworzeniu źródła danych należy stworzyć Data Source View, który będzie zawierał tylko jeden obiekt tj. widok vTargetMail dostępny w naszej źródłowej bazie.
W kolejnym kroku nie tworzymy nowej kostki wielowymiarowej – nie jest ona obligatoryjna dla projektów eksploracyjnych – stwórzmy Mining Structure czyli nic innego jak kontener na modele data miningowe(czyli konkretne implementacje algorytmów eksploracyjnych), który definiuje połączenie do Data Source View oraz atrybuty, które będą dostępne dla modelu. Ponadto to w strukturze miningowej możemy zdefiniować to jaki procent danych ma być przeznaczony na tzw. training set czyli zestaw danych przeznaczony do nauki algorytmu.
Stwórzmy sobie zatem nową strukturę klikając prawym przyciskiem na Mining Structure i wybierając z menu kontekstowego New Mining Structure – naszym oczom powinien ukazać się ekran powitalny kreatora z krótkim opisem tego do czego on służy:
Po kliknięciu Next możemy zdefiniować czy nasza struktura ma się opierać na danych zawartych w kostce wielowymiarowej czy też bezpośrednio na źródle – wybierzmy dostęp bezpośrednio do bazy danych.
Dalej przechodzimy do wyboru algorytmu eksploracji danych – do wyboru mamy 9 wbudowanych w SSAS algorytmów. Możemy również stworzyć strukturę bez żadnych modeli wewnątrz jednakże na ten moment wybierzmy Naiwny klasyfikator Bayesa i przejdźmy dalej.
Dalej możemy wybrać źródłowy Data Source View i oznaczyć go jako zbiór danych dla algorytmu eksploracyjnego:
Następnie możemy wybrać atrybuty – jako Key oznaczamy atrybut, który w unikalny sposób rozróżnia każdy wiersz – w naszym przypadku jest to CustomerAlternateKey. Jako input wybieramy atrybuty służące do zaklasyfikowania do grupy tj. Age, CommuteDistance,Gender, HouseOwnerFlag, NumberChildrenAtHome oraz YearlyIncome. Tak jak już wspomniałem grupy muszą być predefiniowane tak więc w naszym zbiorze musimy mieć takowe posiadać – w opisywanym zbiorze odpowiada za to BikeBuyer, który zawiera 1 jeżeli ktoś kupił rower oraz 0 jeżeli tego roweru nie zakupił. W przypadku gdy nie wiemy co wybrać możemy użyć przycisku Suggest – jednakże z mojego punktu widzenia jeżeli nie znamy zestawu danych na tyle aby nie wiedzieć co tu wybrać to nie powinniśmy tworzyć modelu data mining 🙂
Naiwny klasyfikator Bayesa wymaga aby atrybuty na których działa były dyskretne, a nie ciągłe. Ogólnie rzecz biorąc atrybutem dyskretnym będzie każdy atrybut o skończonej liczbie wartości pomiędzy którymi nie może wystąpić żadna ciągłość np. płeć czy wiek. Atrybut ciągły z kolei to atrybut, który posiada wartość numeryczną której skala może zapewnić ciągłość czyli np. temperatura, wartość itp. Ważne jest to, że atrybuty ciągłe mogą podlegać dyskretyzacji czyli podziałowi na grupy np. pensja zamiast konkretnej wartości może znajdować się w zakresie (Bucket) dla przykładu od 1000 do 2000, od 2000 do 3000 itd. Takie zakresy możemy tworzyć ręcznie lub też SSAS może zrobić to dla nas bazując na właściwościach Bucket Count oraz Discretization Method o których powiemy w dalszej części niniejszego artykułu. Tak więc w kolejnym kroku możemy ustawić typy wartości każdego atrybutu – zaznaczmy wszędzie Discrete oprócz klucza (Key) i Yearly Income, którego chcemy poddać dyskretyzacji. Ekran powinien przypominać poniższe okno konfiguracyjne:
Dalej możemy ustawić jaka część naszego zbioru danych ma być próbką na której algorytm będzie się uczył. Domyślnie SSAS zasugeruje nam 30% danych testowych (czyli 70% przeznaczonych do nauki) – uważam, że to dobry wybór (przynajmniej dla naszych celów ćwiczeniowych):
Ostatnie okno jest standardowym podsumowaniem działania kreatora – klikamy Finish.
Przejdźmy następnie do okna naszej struktury Data Miningowej. Na zakładce Mining Structure zaznaczmy nasz atrybut Yearly Income i we właściwościach odnajdźmy DiscretizationBucketCount, która pozwala na ustalenie liczby przedziałów, które należy stworzyć dla wartości ciągłej podlegającej dyskretyzacji. Następnie wybierzmy DiscretizationMethod, która pozwala wybrać algorytm dyskretyzacji – na ten moment wybierzmy Clusters. Następnie kliknijmy prawym przyciskiem myszy na Columns i dodajmy do naszej struktury kolumny Region oraz TotalChildren – upewnijmy się, że ich zawartość ma ustawioną właściwość na Discrete.
Na zakładce Mining Models możemy zobaczyć jaki model został stworzony w ramach struktury oraz jakie atrybuty pełnią jaką rolę w ramach danego modelu.
Kliknijmy prawym przyciskiem myszy na nasz model i z menu kontekstowego wybierzmy Set Algorithm Parameters. Naszym oczom powinno ukazać się okno z parametrami możliwymi do ustawienia dla wybranego przez nas algorytmu tj:
- MAXIMUM_INPUT_ATTRIBUTES – maksymalna ilość atrybutów na wejściu
- MAXIMUM_OUTPUT_ATTRIBUTES – maksymalna ilość atrybutów na wyjściu
- MAXIMUM_STATES
- MINIMUM_DEPENDENCY_PROBABILITY – atrybut służący do ustalenia minimalnej wartości prawdopodobieństwa zależności pomiędzy atrybutami tzn. im większą wartość ustawimy tym mniej atrybutów będzie zawierał model (czyli tylko mocne zależności będą ukazane).
Zostawmy ustawienia na domyślnych wartościach. Następnie musimy przeprocesować naszą strukturę – po tym przejdźmy na zakładkę Mining Model Viewer. W tym oknie możemy zapoznać się z pierwszymi wynikami działania naszego algorytmu na próbce testowej:
Jak widać według algorytmu na to czy ktoś zakupi rower czy też nie największy wpływ mają atrybuty mówiąc o liczbie dzieci, liczbie dzieci w domu, Regionie zamieszkania oraz dystansu jaki dany klient musi dojeżdżać do pracy. Pasek po lewej stronie umożliwia nam sprawdzenie, które atrybuty mają większy wpływ na atrybut oznaczony jako Predict, a które mniejszy. Jak widać największy wpływ na to czy ktoś kupił rower czy nie miał dystans do pokonania do pracy:
Wiedza ta już jest wartością dodaną gdyż w naprawdę łatwy sposób można wyszukać wzorce w naszych danych. Dopełnieniem tej wiedzy jest zakładka Attribute Profiles, która pokazuje nam rozkład atrybutów w stosunku do tego czy rower został kupiony czy nie. Jest to zakładka dająca całkiem dobry pogląd na to jak rozkładają się wartości atrybutów wejściowych w stosunku do atrybutu objaśnianego. Dodatkowo możemy sterować liczbą opcji w każdej z kolumn tak by zobaczyć jak ma się zestaw trzech najpopularniejszych wartości do całości – służy do tego przełącznik Histogram bars:
Zakładka Attribute Characteristics pokazuje wartości atrybutów wejściowych, które z największym prawdopodobieństwem mówią o tym czy ktoś kupi rower czy też nie. Dla przykładu na poniższym zrzucie ekranowym można zauważyć, że największy wpływ na to, że ktoś kupił rower (czyli Attribute: Bike Buyer Value:1) ma liczba dzieci w domu (Number Children At Home) równa 0. Oczywiście możemy również testować w drugą stronę jaka wartość którego atrybutu miała największy wpływ na to, że ktoś nie kupił roweru.
Ostatnia zakładka w Mining Model Viewer o nazwie Attribute Discrimination daje nam możliwość wizualizacji tego, które wartości atrybutów wejściowych wskazują na którą wartość atrybutu wyjściowego. Jak widać poniżej na to, że ktoś nie kupił roweru największy wpływ miała odległość od pracy większa niż 10 mil.
Przechodząc już do zakładki Mining Accuracy Chart możemy zbadać efektywność naszego algorytmu (lub algorytmów jeśli zbudowaliśmy ich więcej w danej strukturze). W sekcji Input Selection możemy wybrać przede wszystkim to o jaką kombinacją wartości nam chodzi badając efektywność. Dla przykładu poniżej można zauważyć, że badamy efektywność predykcji tych przypadków gdzie rower został kupiony. Dodatkowo w dolnej części ekranu można założyć filtr, który ograniczy zestaw danych według określonych kryteriów. Może to być dobra opcja gdy np. chcemy sprawdzić skuteczność algorytmu w przypadku gdy rower został kupiony wśród ludzi w wieku powyżej 50 lat. Jeszcze jedną ważną opcją w tej części ekranu jest wybór skąd mają pochodzić dane dla Lift Chart – w większości przypadków interesują nas dane zawarte w modelu data mining.
Przechodzimy do najważniejszej sekcji tej zakładki, a mianowicie Lift Chart. Pokazuje on mam w tym wypadku trzy linie – pierwsza z nich tj. Ideal Model to idealny model klasyfikujący z kolei Random Guess to linia obrazująca przypadkowe trafienie, v Target Mail to nasz model eksploracyjny. Na wykresie dostępna jest również pionowa szara linia która po kliknięciu na wybrany obszar zostanie przeniesiona w to właśnie miejsce. Jak więc interpretować ten wykres? Na osi Y mamy procentową wartość poprawnie prognozowanych przypadków – na osi X z kolei mamy procent całej populacji. Na poniższym obrazie widzimy, iż pionowa oś jest ustawiona na 50% i tyle też wynosi skuteczność przypadkowych “strzałów” w stosunku do tego czy rower zostanie kupiony. Można również zauważyć, że idealny model potrzebuje jedynie 50% przypadków aby poprawnie sklasyfikować całą populację.Nasz model oznaczony czerwoną linią charakteryzuje się 62% poprawnością predykcji przy czym jako osoba która chce kupić rower została zaklasyfikowana osoba której prawdopodobieństwo zakupu wyniosło około 50%.
Oczywiście możemy sprawdzić skuteczność naszego modelu na mniejszej próbce i dopasować do określonych przez nas warunków. Kolejnym narzędziem dostępnym w tej sekcji jest tak zwany Profit Chart, który można wybrać z menu rozwijanego dostępnego w lewej górnej części okna o nazwie Chart Type. Wykres ten pozwala przeliczyć teoretyczny zysk/stratę gdybyśmy chcieli np. przeprowadzić kampanię marketingową bazując na naszym modelu. Po wybraniu tego wykresu naszym oczom ukaże się następujące okno konfiguracyjne:
W Population musimy wpisać np. liczbę osób do której chcemy wysłać ofertę reklamową, Fixed Cost – to stały koszt kampanii, który musimy zapłacić bez względu na wielkość populacji czyli np. koszt graficznego opracowania naszej oferty. Individual Cost to koszt związany np. z dostarczeniem oferty do konkretnej jednostki. Revenue per individual – to potencjalny zysk w momencie gdy osoba zdecyduje się na zakup roweru.
Tak więc wykres ten pozwala na obliczenie teoretycznego zysku gdybyśmy dokonali decyzji bazując na stworzonym modelu eksploracyjnym. Ostatnim oknem o jakim chciałbym powiedzieć w ramach tego artykułu jest Classification Matrix, która pozwala na zapoznanie się z dobrymi i błędnymi predykcjami na naszym zbiorze testowym.
Interpretacja tego zestawienia jest bardzo prosta – w kolumnie Predicted mamy wartości jakie przyjmuje nasza zmienna objaśniana. 0(Actual) pokazuje ile w rzeczywistości było wartości 0, 1 (Actual) to ile w rzeczywistości było wartości 1.
Dlatego też:
- 1716 jest to tzw. True Negatives czyli liczba poprawnie zaklasyfikowanych wartości 0, które w rzeczywistości były równe 0.
- 998 jest to tzw. False Negatives czyli liczba negatywnie zaklasyfikowanych wartości 0, które w rzeczywistości były równe 1.
- 1058 jest to tzw. False Positives czyli liczba negatywnie zaklasyfikowanych wartości 1, które w rzeczywistości były równe 0.
- 1773 jest to tzw. True Positives czyli liczba pozytywnie zaklasyfikowanych wartości 1, które w rzeczywistości były równe 1.
Sumując True Negatives i True Positives otrzymamy liczbę poprawnie zaklasyfikowanych przypadków. Suma False Negatives i False Positives daje nam liczbę źle zaklasyfikowanych przypadków. Możemy też obliczyć tzw. dokładność modelu (ang. Accuracy) korzystając dzieląc liczbę poprawnie zaklasyfikowanych przypadków w stosunku do wszystkich przypadków.
Tak więc wiemy już jak stworzyć wykorzystać prosty algorytm eksploracyjny z wykorzystaniem SSAS – w następnej części powiemy sobie jak tak model wykorzystać w celu klasyfikacji danych w narzędziach klienckich – stay tuned!
- Avoiding Issues: Monitoring Query Pushdowns in Databricks Federated Queries - October 27, 2024
- Microsoft Fabric: Using Workspace Identity for Authentication - September 25, 2024
- Executing SQL queries from Azure DevOps using Service Connection credentials - August 28, 2024
Fajnie powiedziane, slogany w stylu “Data Science” czy “Machine Learning”. Tak to jest, że co kilka lat kolejne rzeczy stają się modne. Do nich dorzuciłbym też hasła “NoSQL” oraz “Big Data”. Oczywiście można się sprzeczać, czy chodzi wyłącznie o modę, czy jest to faktyczny bum, wynikający z potrzeby współczesnych czasów.
To prawda – są zauważalne pewne trendy 🙂 Czy wynikają one z potrzeb? Myślę, że bywa różnie – jeżeli jakiś rodzaj oprogramowania staje się na tyle dojrzałe, że w praktyce większość ludzi wie co i jak, istnieje więc potrzeba stworzenia nowych pojęć. Mamy Data Mining zastąpiony przez Machine Learning czy też ogólnie Data Science – takie przykłady można by mnożyć. Oczywiście bazy NoSQL mają swoje specyficzne zastosowanie i w niektórych aspektach przewyższają bazy relacyjne – jednakże nigdy nie pokusiłbym się o stwierdzenie, że je zastąpią 🙂
Dobrze powiedziane, specyficzne zastosowanie. Był czas, gdy wieszczono im na tyle świetlaną przyszłość, że miały zastąpić bazy relacyjne. Potem złagodzono stanowisko, twierdząc że te dwa typy baz będą się wzajemnie uzupełniać. I to jest chyba całkiem słuszne podejście. A ostatnio coraz częściej znajduję w internecie artykuły, w których autorzy pokazują, że jednak bazy NoSQL nie są wcale takim super rozwiązaniem jak wcześniej zakładano. I twierdzą że obecnie usiłuje się wpleść do ich mechanizmu działania elementy SQL-a, bo okazuje się że jednak bez niego nie da się żyć w świecie danych i ich analizy. Szczególnie analizy.
Trochę nie na temat, ale interesuje mnie zagadnienie testowania oprogramowania. Czy w swojej pracy robisz jakieś testy baz danych? A jeżeli tak, to jakie? Testy jednostkowe? Wydajnościowe? Czy używasz jakiś narzędzi do automatyzowania tych testów?
Jeśli chodzi o testy baz danych to oczywiście muszę testować to co udało mi się stworzyć jednakże nie jest to działanie takie jak wykonują typowi testerzy. Same testy znacznie się od siebie różnią patrząc na to czy testujemy poprawność danych czy struktury. W swojej pracy spotkałem się z narzędziami do pisania testów czy też całym frameworkiem (tsqlt) – być może uda mi się coś napisać w przyszłości na ten temat.
Jeśli chodzi o testy wydajnościowe to w bazach danych są one procesem ciągłym i sprowadzają się do wielu czynności sprawdzających szereg różnych metryk – rozwiązania zaimplementowane przez nas staramy się monitorować i w razie wystąpienia problemu zareagować.
Czyli nie używacie jakiś typowych programów do pomiaru wydajności, lecz stosujecie własne rozwiązania?
Jeśli chodzi o testy wydajnościowe stosujemy dostępne obiekty systemowe bazy danych (DMV) czy chociażby performance monitor.