Uczenie maszynowe to nie tylko zdolność samouczenia algorytmów ale również wnioskowanie rozmyte, a więc podobne do tego w jaki sposób człowiek ocenia sytuacje i podejmuje decyzje. Jak nauczyć algorytm w MATLABie aby poprawnie rozróżniał od siebie elementy o cechach posiadających subtelne różnice? W tym wpisie poruszę ważny wątek związany z uczeniem maszynowym o nazwie logika rozmyta.
W poprzednich wpisach o uczeniu maszynowym w MATLABie (wpis 1 i wpis 2) omówiłem algorytm k-Means, który jest reprezentantem algorytmów posiadających zdolność uczenia się w celu automatycznej klasyfikacji obiektów. Jakkolwiek algorytm ten faktycznie w sposób adaptacyjny dobierał „środki” klastrów w kolejnych iteracjach, to kryterium przynależności danego elementu do klastra było „sztywne”. Mieliśmy więc tu do czynienia z logiką zero-jedynkową. Element należy do tego klastra, do którego „ma bliżej”.
Poprzednio pisałem również o tym, że takie podejście jest dalekie od idealnego i może generować błędy klasyfikacji. Przecież człowiek podejmuje decyzje intuicyjnie, ocenia szereg cech i rozróżnia subtelne różnice pomiędzy kategoriami poszczególnych elementów. Innymi słowy, w magiczny sposób potrafimy poprawnie zaklasyfikować dany element nawet jeśli obiektywne wskaźniki (np. wynikające z pomiaru) mówią coś innego.
Czy zatem da się skonstruować algorytm posiadający podobną wrażliwość, który będzie rozróżniał te subtelne różnice w cechach elementów? Tak!
Logika klasyczna, a logika rozmyta
W poniższych przykładach będę się odwoływał do poprzednich wpisów i programów, które dotyczyły automatycznej klasyfikacji pojazdów, na podstawie ich mierzalnych cech: długości i rozstawu osi.
W dziedzinie logiki klasycznej, algorytmy klasyfikacji automatycznej bazują na definicji zbioru konwencjonalnego, który można zapisać jako zbiór par:
A = {(x, fa(x) )}
gdzie:
X = {x} - jest pewnym szerszym zbiorem wartości (w tym przypadku: odległość między osiami lub długość pojazdu),
fa(x): X --> {0,1} - jest zwane klasyczną funkcją przynależności, która każdemu elementowi przestrzeni X przypisuje liczbę „0” oznaczającą nieprzynależność lub „1” - przynależność.
Innymi słowy, danej wartości mierzalnej cechy obiektu (np. odległość między osiami) jest przyporządkowywana wartość 0 lub 1, gdzie 0 oznacza, że obiekt nie należy do danego klastra, a 1, że należy.
Ale zaraz… W grupie pojazdów o tej samej liczbie osi można wyszczególnić różne typy pojazdów o zbliżonych rozstawach między osiami x1_2. Zdefiniowanie rozłącznych kryteriów klasyfikacji nie jest więc możliwe, a wnioskowanie o przynależności pojazdu do danej kategorii na bazie logiki klasycznej traci sens.. Ilustruje to rysunek:
Mamy więc problem.. Pojazd określony przez wynik pomiaru odległości między osiami x1_2 równie dobrze, może należeć do klastra pierwszego jak i drugiego. Ponieważ nie występuje tutaj bezwzględne przyporządkowanie elementu do zbioru należy posłużyć się logiką rozmytą jako miarą pojęć nieostrych, wieloznacznych i nieprecyzyjnych. Zbiór rozmyty B określony w X można przedstawić jako zbiór par:
B = { (uB(x), x) }
gdzie:
X = {x} – j.w.
uB: X --> [0,1] - jest funkcją przynależności, która każdemu elementowi z przestrzeni X przyporządkowuje stopień przynależności do danego zbioru rozmytego: od nieprzynależności (uB(x)=0) przez przynależność częściową (0<uB(x)<1) do całkowitej przynależności (uB(x)=1).
Przejście od przynależności do nieprzynależności w teorii logiki rozmytej nie ma więc charakteru skokowego, jak w logice klasycznej, ale jest stopniowe. Kształt funkcji przynależności jest uzależniony od rozpatrywanego problemu i może przyjąć postać od prostych funkcji analitycznych (funkcja trójkątna, gaussa, itp) po złożone zależności będące kombinacją wielu funkcji prostych.
Oprócz alternatywy „przynależność – nieprzynalezność” charakterystycznej dla logiki klasycznej, występują tu przypadki przynależności częściowej. Przykład trójkątnych funkcji przynależności zbioru rozmytego „odległość między osiami” - x1_2 pokazano na rysunku.
Dzięki zastosowaniu trójkątnych funkcji przynależności udało się wyeliminować niejednoznaczność charakterystyczną dla logiki klasycznej „zero-jeden”.
Otrzymane w tym przykładzie wartości funkcji przynależności u1 i u2 należy interpretować jako miarę przynależności pojazdu o rozstawie osi x1_2 do jednej z dwóch kategorii: samochód osobowy lub dostawczy. Wartość (u1(xi)=0.65) > (u2(xi)=0.25) wskazuje, iż pojazd o zmierzonym rozstawie osi xi, „lepiej” pasuje do kategorii samochodów dostawczych niż osobowych.
MATLAB posiada Fuzzy Logic Toolbox przeznaczony do budowania, analizowania i symulowania systemów bazujących na logice rozmytej. W odniesieniu do automatycznej klasyfikacji obiektów i omawianego wcześniej algorytmu k-Means, znajdziemy tutaj zestaw narzędzi o nazwie fuzzy clustering, a więc do klasyfikacji rozmytej. Tym tematem zajmę się w przyszłości, a w między czasie polecam zajrzeć do dokumentacji Fuzzy Logic Toolbox. Poniżej umieszczam program, rysujący przykładowe, rozmyte funkcje przynależności. Go fuzzy!
mf = [... fismf('trapmf',[-19 -17 -12 -7]) ... fismf('gbellmf',[3 4 -8]) ... fismf('trimf',[-9 -1 2]) ... fismf('gaussmf',[3 5]) ... fismf('gauss2mf',[3 10 5 13]) ... fismf('smf',[11 17]) ... fismf('zmf',[-18 -10]) ... fismf('psigmf',[2 -11 -5 -4]) ... fismf('dsigmf',[5 -3 1 5]) ... fismf('pimf',[0 7 11 15]) ... fismf('sigmf',[2 15]) ... ]; x = linspace(-20,20,201); y = evalmf(mf,x); subplot(2,1,1); plot(x,y(1:6,:)'); axis([min(x) max(x) 0 1.2]); text((mf(1).Parameters(2)+mf(1).Parameters(3))/2,1.1,mf(1).Type,... 'horizon','center'); text(mf(2).Parameters(3),1.1,mf(2).Type,... 'horizon','center'); text(mf(3).Parameters(2),1.1,mf(3).Type,... 'horizon','center'); text(mf(4).Parameters(2),1.1,mf(4).Type,... 'horizon','center'); text((mf(5).Parameters(2)+mf(5).Parameters(4))/2,1.1,mf(5).Type,... 'horizon','center'); text(mf(6).Parameters(2), 1.1,mf(6).Type,... 'horizon','center'); h_gca = gca; h_gca.XTick = []; subplot(2,1,2); plot(x,y(7:11,:)'); axis([min(x) max(x) 0 1.2]); text(mf(7).Parameters(1),1.1,mf(7).Type,... 'horizon','center'); text((mf(8).Parameters(2)+mf(8).Parameters(4))/2,1.1,mf(8).Type,... 'horizon','center'); text((mf(9).Parameters(2)+mf(9).Parameters(4))/2,1.1,mf(9).Type,... 'horizon','center'); text((mf(10).Parameters(2)+mf(10).Parameters(3))/2,1.1,mf(10).Type,... 'horizon','center'); text(mf(11).Parameters(2),1.1,mf(11).Type,... 'horizon','center'); h_gca = gca; h_gca.XTick = [];