Klasyfikacja towaru – idealne zadanie dla sieci neuronowej

W poszukiwaniu zastosowań dla machine learning w naszych biznesach, nie zawsze trzeba myśleć o dużych, przełomowych i rozpisanych na lata projektach. Żeby cieszyć się  korzyściami, jakie daje ta technologia, dobrze jest zacząć od mniejszych prac, np. wykorzystania sztucznej inteligencji do obsługi części wybranego procesu biznesowego.

Przykładem takiego podejścia, było zbudowanie oprogramowania obsługującego jeden z etapów procesu biznesowego klienta, który wykonywany był dotychczas manualnie. Chodziło dokładnie o krok w procesie udzielania kredytu ratalnego, w którym należało przypisać branżę do sprzedawanego artykułu, np. „sofę 2 osobową rozkładaną estella” do branży meblowej a „synology RT19 router WLA” jako sprzęt komputerowy.
Ponieważ informacja o branży artykułu wiązała się z dalszymi etapami procesu kredytowego, dlatego ewentualny błąd w przypisaniu, mógł narazić firmę na straty lub inne kłopoty. A takie ryzyko istniało, bo choć lista branż była predefiniowana i niezmienna, to nazwy artykułów, które trzeba było do nich przypisać, pochodziły z systemów różnych sklepów i nie miały wspólnego formatu.

Tworzone oprogramowanie, miało więc z zautomatyzować tę czynność i jednocześnie wyeliminować ryzyko popełnienia błędu. Do spełnienia tych założeń, wykorzystaliśmy machine learning, a dokładnie zaprojektowaliśmy mechanizm przekształcenia z przestrzeni nazw na przestrzeń branż.

Mechanizm ten miał spełniać kilka istotnych kryteriów. Jednym z nich było kryterium trafności. Żeby ocenić naszą funkcję w sposób liczbowy posłużyliśmy się elementarną statystyką i zdefiniowaliśmy wskaźnik trafności jako stosunek liczby udanych prób wyznaczenia branży do liczby wszystkich podjętych prób. Przyjęliśmy tu założenie, że będziemy zadowoleni z naszej funkcji tylko wtedy, gdy tak zdefiniowana trafność przekroczy wartość 0,90, czyli 90%.

Kolejnym ważnym zagadnieniem była możliwość oszacowania pewności wyniku. Nasza funkcja nie będzie mieć 100% trafności. Co jakiś czas otrzymany wynik będzie niepoprawny, a automatyczny proces wydawania decyzji kredytowej nie będzie o tym wiedział. Oczywiście można by to zignorować i pogodzić się z tym, że proces kredytowy co jakiś czas będzie funkcjonował w oparciu o błędnie określoną branżę, ale o wiele lepiej byłoby wiedzieć, kiedy wyznaczona branża jest niepewna i w takiej sytuacji przekierować proces do ręcznej obsługi.
Niepewność tą będziemy interpretować poprzez prawdopodobieństwo poprawności wyniku, czyli liczbę w zakresie od 0 do 100%.

Mamy tu do czynienia z dwoma ważnymi zakresami. Prawdopodobieństwo mniejsze niż 10% oznacza de facto, że dany wynik jest prawie na pewno błędny. Z kolei prawdopodobieństwo większe niż 95% oznacza, że wynik jest prawie na pewno poprawny.
Interpretacja wartości pomiędzy 10% i 95% zależy od specyfiki zagadnienia, w jakim funkcja będzie stosowana a zwłaszcza tzw. apetytu na ryzyko. W naszym konkretnym przypadku (niski apetyt na ryzyko), branża wyznaczona z takim poziomem ufności również powinna być kierowana do ręcznej obsługi.

Poprawność wyniku i poziom ufności mogą wystąpić w różnych kombinacjach, jak na rysunku:

Klasyfikacja towaru

Możemy tu wyróżnić dwa istotne obszary. Jeden będzie obszarem pożądanym, który potwierdzi przydatność naszej funkcji, a drugi odwrotnie – spowoduje, że nasza funkcja będzie zupełnie bezużyteczna.

Obszar pożądany składa się z dwóch zakresów kombinacji: poprawność oraz ufność:

  •       Wynik poprawny podany z dużą ufnością
  •       Wynik niepoprawny podany z niską ufnością

Klasyfikacja towaru

Branża wyznaczona z dużą ufnością będzie procesowana automatycznie, więc to dobrze, że będzie poprawna.
Branża wyznaczona z niską ufnością zostanie odrzucona i procesowana ręcznie, więc również jest to wynik pożądany, bo i tak była wyznaczona błędnie.
Chcielibyśmy, żeby ogromna większość wyników działania naszej funkcji wpadało do tego obszaru.

Obszar niepożądany również składa się z dwóch zakresów kombinacji: poprawność, ufność:

  •       Wynik poprawny podany z małą ufnością
  •       Wynik niepoprawny, podany z dużą ufnością

Klasyfikacja towaru

Branża wyznaczona z dużą ufnością będzie procedowana automatycznie, więc byłoby źle gdyby była niepoprawna.
Branża wyznaczona z niską ufnością zostanie odrzucona i procedowana ręcznie, a szkoda, bo akurat została wyznaczona poprawnie, więc stracilibyśmy dobrą okazję.
Chcielibyśmy, żeby jak najmniej wyników działania naszej funkcji wpadało do tego obszaru.

Nasza funkcja powinna radzić sobie nie tylko z tymi nazwami, które uwzględniliśmy w analizie przy jej projektowaniu, ale także z nazwami trochę od nich odbiegającymi. Na przykład z nowymi produktami z tych samych branż albo z produktami, które pochodziły dotychczas z jednego systemu a w przyszłości mogą przychodzić z innych systemów, w których będą miały inną nazwę. Sofa może mieć w nazwie „skórzana z funkcją spania”, ale może mieć także krótką nazwę „sofa alabama”. Albo zamiast „funkcji spania” może być tylko skrót „span”.

Z drugiej strony nie będziemy od naszej funkcji wymagać, aby poprawnie wskazywała branżę dla zupełnie nowych produktów, na przykład dla nowego rodzaju mebla, który być może powstanie w przyszłości.

Potrzeba generalizacji w tym konkretnym projekcie była mniejsza niż zazwyczaj, bo różnorodność nazw artykułów, które mogą być sprzedawane w trybie ratalnym jest ograniczona w porównaniu np. do zbioru możliwych treści maili, artykułów, postów społecznościowych itp.

 

Rozwiązania algorytmiczne

Jednym ze sposobów budowania naszej funkcji mogłoby być typowe podejście algorytmiczne, w  którym zatrudniamy dobrego analityka do przyjrzenia się naszym danym, przeanalizowania ich i wymyślenia, w jaki sposób można na ich podstawie wskazać branżę.

Zauważy on z pewnością, że na przykład wystąpienie słowa „Sofa” w nazwie artykułu gwarantuje, że będzie to branża meblowa. Podobnie gdybyśmy tam mieli słowa takie jak: tapczan, krzesło, wersalka…

Możemy zatem zbudować listę (bazę) słów, których obecność w nazwie oznacza branżę meblową.
To oczywiście nie jest aż takie łatwe, bo co zrobić np. ze słowem „kierownica”? Czy wystąpienie tego słowa oznacza, że mamy do czynienia z branżą motoryzacyjną? Niekoniecznie. Są przecież kierownice rowerowe, a te są w branży sportowo turystycznej.

Musimy więc zbudować logikę wariantową, co nieco komplikuje naszą bazę słów kluczowych i działanie algorytmu.

Nie wspominam tu nawet o tak trywialnych kwestiach jak normalizacja wielkości liter, usunięcie znaków specjalnych i interpunkcyjnych, uwzględnienie odmiany przez przypadki i liczby oraz uwzględnienie błędów typograficznych i skrótów.

Czy to byłoby łatwe zadanie? Trudno powiedzieć, ale jest inna droga, droga na skróty.

Wskazywana do tej pory przez pracownika branża była zapisywana i aktualnie dysponujemy tablicą (około 10 tys rekordów) łączącą nazwy artykułów z odpowiednimi branżami.

Zamiast projektować ten algorytm w zaciszu własnej analitycznej głowy możemy  wykorzystać uczenie maszynowe.

 

Machine Learning – Multiclass Neural Network

Naszą funkcję moglibyśmy aproksymować poprzez kilka różnych algorytmów uczenia maszynowego. Najlepsze efekty uzyskaliśmy jednak korzystając z dostępnej na platformie Microsoft Azure ML Studio, sieci neuronowej typu multiclass neural network.

Składa się ona z pewnej liczby neuronów wejściowych, do których w naszym przypadku podłączymy nazwy artykułów, warstwy neuronów wewnętrznych oraz warstwy neuronów wyjściowych. Każdy neuron wyjściowy odpowiada za konkretną branżę.

Tu pojawia się pierwszy problem do rozwiązania. Mianowicie sieć neuronowa ma na swoim wejściu określoną, stałą liczbę neuronów. Tymczasem nazwa artykułu może mieć różną ilość słów czy znaków. Zatem jak zamienić coś o różnej długości na coś o ustalonej długości?

Z pomocą przychodzi koncepcja przestrzeni słów (eng. bag of words). Dla ilustracji, weźmy kilka wybranych nazw artykułów, podzielmy je na pojedyncze słowa i usuńmy powtórzenia. Powstanie po tej operacji lista składająca z takich słów jak: sofa, osobowa, rozkładana, estella, Portland, ekspres, delonghi, lodówka… Są to wymiary naszej przestrzeni nazw.
Nazwa artykułu zawiera w sobie słowo z powyższej listy pewną określoną liczbę razy: zero, jeden lub więcej.  Możemy, więc przypisać nazwie artykułu konkretny punkt w przestrzeni nazw.

[su_table]

WymiarWartość
Sofa1
osobowa1
rozkładana1
estella1
portland1
ekspres0
delonghi0
Lodówka0

[/su_table]

Przykładowo nazwie: „Sofa osobowa rozkładana ESTELLA Portland” odpowiadałby punkt (1,1,1,1,1,0,0,0).

Moglibyśmy zatem każdemu słowu z przestrzeni słów dedykować jeden konkretny neuron wejściowy. Mielibyśmy wtedy tyle neuronów wejściowych, ile pozycji w przestrzeni słów.

Uczenie maszynowe

„Sofa osobowa rozkładana ESTELLA Portland” podłączona do neuronów wejściowych powoduje, że pierwszy neuron dostanie wartość 1, podobnie następne, aż do piątego a pozostałe dostaną zera.

Czy to rozwiązuje nasz problem?
Choć wydaje się że tak, to jednak nie rozwiązuje.

W praktyce, w nazwach może być bardzo dużo (dziesiątki tysięcy) różnych słów, więc nasz zbiór słów, a co za tym idzie liczba neuronów wejściowych miałaby taką właśnie liczebność, czyli wciąż zbyt dużo jak na możliwości technologii. Poza tym to marnowanie zasobów, bo do tego zadania można podejść dużo sprytniej.

Mam na myśli wykorzystanie techniki zwanej hash’owaniem. W największym uproszczeniu jest to algorytm zamieniający ciąg znaków dowolnej długości na liczbę w ustalonym zakresie.
W tym projekcie wykorzystaliśmy jeden z rodzajów hashowania bitowego, gdzie wynikiem operacji jest liczba w zakresie od 1 do 1024.

Na potrzeby ilustracji załóżmy, że słowo „sofa” po zahashowaniu staje się liczbą 345, a słowo „osobowa” liczbą 719 i tak dla każdego słowa. Oznacza to, że dowolna nazwa może być zamieniona na zbiór liczb.

Sztuczna inteligencja

Podobnie jak wcześniej, tyle że teraz zamiast zbioru o liczebności równej liczbie możliwych słów (rzędu kilkudziesięciu tysięcy) mamy zbiór o liczebności równej liczbie słów w danej nazwie (kilka, kilkanaście).

Cała ta operacja podziału na słowa, utworzenia słownika słów i ich zamiana na hash nazywa się feature hashing.

Teraz wystarczy nam sieć neuronowa mająca tylko 1024 neurony wejściowe. Każdy neuron dedykowany do jednej z możliwych wartości hasha.

Sieci neuronowe

Na następnym obrazku widać, w jaki sposób do naszej warstwy wejściowej zostanie podłączona nazwa „Sofa osobowa rozkładana ESTELLA”.

Machine learning

Wszystkie 1024 neurony otrzymają wartość zero za wyjątkiem tych, których numery odpowiadają hash’om słów znajdujących się w nazwie.

Po podłączeniu nazwy do warstwy wejściowej neurony wykonają swoje obliczenia i w warstwie wyjściowej pokażą się pewne wartości liczbowe. Te liczby mówią nam jakie według sieci jest prawdopodobieństwo, że podłączona nazwa jest z danej branży.

Będą to zazwyczaj bardzo małe liczby za wyjątkiem jednego neuronu, który będzie miał wartość prawie równą jeden.

 Inżynieria oprogramowania

Na przykład neuron pierwszy od góry twierdzi, że z prawdopodobieństwem jedna tysięczna to branża o kodzie, 1 czyli „artykuły RTV”. Drugi neuron przekazuje informację, że to jednak branża „AGD”, tyle że szansa na to jest równa 0.0002. Neuron nr 3 jest za to bardzo pewny siebie. Daje nam szansę 99,94 % że mamy do czynienia z meblem. Pozostałe neurony proponują nam błędne branże, ale są tego bardzo niepewne.

Co do zasady bierzemy zawsze neuron, który ma największy poziom ufności i na tej podstawie określamy, jaką branżę typuje sieć, a więc i nasza funkcja, którą zbudujemy na jej bazie.

 

Prototyp

To tyle, jeśli chodzi o rozważania teoretyczne. W praktyce wykorzystaliśmy środowisko Azure Machine Learning Studio.

Modele buduje się tu wygodnie metodą graficzną, poprzez dokładanie i manipulowanie określonymi node’ami obliczeniowymi.

Klasyfikacja towaru

Zaczynamy od kroku wczytującego dane wejściowe. Następnie wykonujemy trochę operacji porządkujących dane. Są one ukryte w Edit Metadata i Preprocess Text. Split Data powoduje, że część danych (w tym wypadku 80%) pobiegnie wzdłuż lewej odnogi, a pozostała część wzdłuż prawej.

Klasyfikacja towaru

Dane wychodzące z Split Data poddajemy operacji feature hashing. Dane z lewej odnogi trafiają potem do najważniejszego elementu, czyli do elementu trenującego Train Model. Podłączamy do niego z drugiej strony niewytrenowaną jeszcze sieć neuronową.

Score Model uruchomi się dopiero po zakończeniu trenowania sieci. Bierze dane, które wyszły prawą odnogą (a więc dane, które nie brały udziału w trenowaniu sieci); sprawdza, jaką branżę wyznaczy im sieć i porównuje z branżą prawidłową. Na tej podstawie określa czy sieć się pomyliła czy nie.

Evaluate Model konsumuje informacje o poprawnych i błędnych wyliczeniach. Podsumowuje statystycznie i wylicza wskaźniki pokazujące silne i słabe strony wytrenowanej sieci.

Klasyfikacja towaru

Precision to szansa, że przypadkowo wybrany wynik działania sieci jest prawidłowy. Jest to liczba poprawnych wyznaczeń danej branży do liczby wszystkich wyznaczeń tej branży. Np. jeśli sieć uznała 1000 nazw za powiązane z branżą meblową ale 10 z nich było pomyłką, to precyzja = 990/1000.

Recall to szansa, że przypadkowo wybrana dana wejściowa zostanie poprawnie zakwalifikowana. Jest to liczba poprawnych wyznaczeń danej branży do liczby wszystkich wystąpień tej branży w danych wejściowych. Np. jeśli w pliku było 1100 nazw z branży meblowej, ale sieć poprawnie zidentyfikowała tylko 990, to recall = 990/1100.

Jak widać wszystkie możliwe wskaźniki pokazują, że nasza sieć radzi sobie bardzo dobrze.

Ciekawym sposobem weryfikacji jak dobrze pracuje sieć jest analiza tzw. confusion matrix.
Jest to macierz, w której wiersze odpowiadają branżom rzeczywistym, a kolumny branżom wyliczonym przez sieć. W komórkach jest natomiast informacja, jaki procent nazw zostało zakwalifikowanych do danej branży. W idealnym przypadku mielibyśmy wszędzie zera, za wyjątkiem komórek na przekątnej gdzie byłyby wszędzie wartości 100%.

Górna połówka naszej confusion matrix wygląda tak:

Sztuczna inteligencja

Widać, że jest dobrze, ale nie idealnie. Przykładowo w wierszu drugim widzimy, że wprawdzie 99.8% nazw powiązanych realnie z branżą numer 2 zostało przez sieć przypisane prawidłowo do branży numer 2, ale pozostałe 0.2% zostało błędnie przypisane do branży numer 3.

W dolnej połówce macierzy widać, że mamy problem z nazwami pochodzącymi z branży numer 20.

Uczenie maszynowe

Większość z nich została przez sieć zakwalifikowana do branży numer 3. Jest to spowodowane tym, że mamy tylko 14 takich nazw w naszym pliku wejściowym, a w dodatku do trenowania użyte zostało 80% z nich, czyli tylko 11.

Jest to świetny przykład tego, co wszyscy instynktownie wiemy, że sieć neuronowa potrzebuje dużo danych żeby mogła się czegoś nauczyć.

Poprzez sztuczne rozmnożenie tych danych można w razie potrzeby poprawić wyniki, ale oczywiście w takiej sytuacji nie ma co marzyć o generalizacji, czyli o tym, że sieć rozpozna jakiś inny artykuł z tej branży.

Na bazie wytrenowanej sieci utworzona została usługa, dzięki któremu możemy korzystać z naszej sieci.

Klasyfikacja towaru

Wpisujemy nazwę artykułu, klikamy „Test request-response” i po chwili zobaczymy wyniki działania sieci – listę wszystkich branż z wyliczonym prawdopodobieństwem, że dana nazwa pasuje do danej branży.

Przykładowo, jeśli wpiszemy „telewizor 44 – 55 Philips” zobaczymy coś takiego:

Klasyfikacja towaruKlasyfikacja towaru

Pokazuję tu tylko fragment ekranu – wyciąłem cały środek pozostawiając fragment górny i dolny.  Przede wszystkim widać, że wyliczona została branża nr 1 – poprawnie. Widać też, że sieć jest jej pewna w 99.99%.
Wszystkie pozostałe branże dostały bardzo małe prawdopodobieństwa.

 

Podsumowanie

W artykule, odnosząc się do rzeczywistego przykładu, starałem się wyjaśnić podstawy teoretyczne zastosowania machine learning, proces budowy prototypu z wykorzystaniem środowiska Azure Machine Learning Studio oraz sposoby jego weryfikacji.

Ponieważ to przykład autentyczny, to warto też wspomnieć o korzyściach jakie osiągnął nasz klient. Automatyzacja części swojego procesu biznesowego, czyli klasyfikacji towaru do branży, przyśpieszyła cały proces rozpatrywania wniosku kredytowego. Szybka odpowiedź zwrotna osobom zainteresowanym kredytem, wprost przełożyła się na większą satysfakcję z obsługi.

W Altkom Software & Consulting, fascynujemy się rozwiązaniami, które pozwalają zmieniać otaczającą nas rzeczywistość. Mamy jednak świadomość, że każda zmiana, to inwestycja, która musi się zwrócić. Użycie sieci neuronowych pozwoliło nam wytworzyć rozwiązanie bardzo skuteczne i tak naprawdę dużo tańsze, niż gdybyśmy zastosowali standardowy silnik eksperckich reguł klasyfikacji.

 

Autor: Mariusz Surma, Starszy Analityk w Altkom Software & Consulting