Recent am avut de lucru la un sistem nesupravegheat de clasificare. Foloseam metode statistice de clustering (covarianța empirică în principal) și OCSVM(One Class Support Vector Machine), dar care aveau rezultate foarte proaste deși peste 99% din date formau un cluster bine definit(eliptic). Problema era cu o serie de outlieri foarte îndepărtați, care făceau foarte problematică găsirea unei varianțe medii corespunzătoare. Cu această ocazie, voi descrie repede ce vreau să spun prin asta:
Fie că este vorba de covarianță empirică sau covarianță robustă și chiar ceva total diferit precum OCSVM, toate aceste metode sunt sensibile la scalarea datelor. În cazul meu, acei outlieri foarte îndepărtați afectau masiv media în algoritmii de clustering statistici și parametrul gamma la OCSVM. De ce…
\text{Fie media unei trasaturi corupte: }\mu = \frac{1}{n}\sum\limits_{i=0}^{n}x_i. \\ \text{Presupunem ca } \exists x_j \text{ corupt a.i. } x_j \approx k*\mu' ,\ \text{ unde: } \\ \mu' = \frac{1}{n-1}\sum\limits_{\substack{i=0 \\ i \neq j}}^{n}x_i \Rightarrow \mu = \frac{1}{n}(\sum\limits_{\substack{i=0 \\ i \neq j}}^{n}x_i + k\mu') = \\ \frac{1}{n}(\sum\limits_{\substack{i=0 \\ i \neq j}}^{n}x_i + k \frac{1}{n-1}\sum\limits_{\substack{i=0 \\ i \neq j}}^{n}x_i) = \frac{k+n-1}{n(n-1)}\sum\limits_{\substack{i=0 \\ i \neq j}}^{n}x_i. \\ \text{Pentru } k \approx n \text{ si } n \text{ foarte mare }(n \approx n-1) \quad \mu \approx 2 \mu\prime
Micul calcul de mai sus ne arată cât de sensibilă poate fi și o trăsătură grosieră precum media, daca există și o singură valoare coruptă. În astfel de situații, datele trebuie analizate serios și filtrate manual (setându-se ceva limite tari, chiar la nivelul codului sursă).
După acest pas se pot face normalizările de orice fel fiindcă se vor obține clustere mult mai relevante. De asemenea, eliminând acele valori supărătoare se va elimina și problema unei varianțe foarte mici în jurul clusterului principal. Demonstrația e un pic mai lungă ca la medie, dar este aceeasi idee: outlierii îndepărtați contribuie foarte mult la varianța finală făcând-o foarte mare. În proces, varianța la nivelul clusterului principal scade și astfel apar o mulțime de probleme.
Tipuri de scalare:
1. MinMax Scaler: cea mai simplă scalare este normalizarea datelor între 0 și 1. Pentru asta e suficient să transformăm datele după:
x' = \frac{x-x_{min}}{x_{max} - x_{min}}
Problema în cazul acestei scalări este sensibilitatea la outlierii îndepărtați, iar motivul este simplu. Acel x_{max}[\katex] poate fi foarte mare și deci clusterul convențional va ajunge să fie comprimat într-o regiune foarte compactă din [0, 1].
2. Scalarea standard: Folosind sklearn, putem face o scalare standard a datelor, prin două metode, fit()
și transform()
. Scalarea standard este metoda prin care eliminăm componenta medie a datelor și aducem totul la varianța unitară:
\forall x, x' = \frac{x-\mu}{\sigma}
import numpy as np
from sklearn.preprocessing import StandardScaler
# generarea setului de date
mean = [10, 15]
cov = [[2, 1], [4, 3]]
data = np.random.multivariante_random(mean, cov, 2000)
# centrare in 0 si varianta identitate
std_scale = StandardScaler().fit(data)
df_std = std_scale.transform(data)
Ca și la scalarea MinMax și această metodă este sensibilă la outlieri îndepărtați. Nu în aceeași măsură, dar totuși suficient de mult pentru a da peste cap algoritmii statistici de aproximare.
3. Robust scaler: O scalare robustă este, precum ne sugerează și numele, un procedeu mai rigid de scalare și mai puțin sensibil la outlieri sau la devieri ale distribuției reale față de distribuția model. Matematic, e un procedeu un pic mai complicat și nu este chiar o formulă de facto ca la metodele prezentate mai sus. Totuși, dacă citiți cu atenție prima parte, veți vedea că am amintit de acele limite tari. Altfel spus, ce e peste limită nu mai e luat în calcul.
Metodele robuste urmăresc la modul general ideea de mai sus și anume: pe măsură ce ne îndepărtăm de cluster, vectorii contribuie diferit la medie și covarianță. Aici intră clasa de funcții Hibs sau orice tip de transformare a spațiului de date(aplicând anumiți kerneli sau funcții psi) care includ modificarea contribuției vectorilor.