Jak ocenić potencjał zbioru przed grupowaniem?

statystyka hopkinsa, segmentacja, statystyka, grupowanie, klastrowanie

Praca przy grupowaniu rozpoczyna się tak naprawdę już na etapie przygotowywania zbioru. Podczas selekcji zmiennych warto wiedzieć jak mierzyć ich wpływ na potencjał naszej ABT.

Z tego artykułu dowiesz się:
1. Jak ocenić potencjał zbioru przed grupowaniem? :)
2. Jak przygotować zbiór do grupowania?

W grupowaniu jak w wielu innych problemach rozwiązywanych przez algorytmy uczenia maszynowego przygotowanie zbioru jest kwestią kluczową. Od niego zależą wyniki końcowej całej pracy. Jak zatem podejść do tego problemu? Odpowiedź poniżej.

Przede wszystkim należy zaczynać z wizją końca. Mieć na uwadze problem, który chcemy grupowaniem rozwiązać. Jestem wielkim fanem zwinnego podejścia zarówno do modelowania, jak i prowadzenia projektów. Zaczynamy od MVP i stopniowo w sposób iteracyjny rozwijamy produkt do czasu osiągnięcia warunku stopu (końca zasobów lub osiągnięcia zadowalającej jakości).

Przykładowo, jeśli wykonujemy segmentację behawioralną, to zaczynamy od zbioru złożonego z kilku najistotniejszych zmiennych opisujących zachowania naszych obserwacji (klientów, pacjentów, etc.). W kolejnym kroku wykonujemy segmentację z użyciem wybranego algorytmu, a następnie iteracyjnie powtarzamy pierwsze dwie czynności udoskonalając jakość modelu (tak jakość modelu segmentacyjnego również musimy kontrolować – więcej o tym w kolejnym wpisie).

W każdej iteracji musimy wiedzieć, czy zmierzamy w odpowiednim kierunku. Jak to zrobić? Pierwszym sposobem jest wyznaczenie statystyk dotyczących powstałych grup/segmentów i opisanie ich (klienci duzi/mali, z wysokim potencjałem zakupowym, aktywni/pasywni, etc.). Drugim sposobem, który wykonujemy jeszcze przed segmentacją jest ocena potencjału zbioru, w określeniu której pomoże nam bohater dzisiejszego wpisu: statystyka Hopkinsa.

Statystyka Hopkinsa jest w gruncie rzeczy testem zbudowaną przez Briana Hopkinsa i Johna Gordona Skellama. Jego hipoteza zerowa mówi o tym, że analizowane dane nie posiadają potencjału informacyjnego i ich rozkład jest w dużej mierze losowy. Przekładając to na liczby mamy kolejno:

  • wynik bliski 1 oznacza zbiór o wysokim potencjale do grupowania,
  • wynik w okolicy 0.5 oznacza zbiór o losowo dobranych wartościach,
  • wynik bliski 0 opisuje zbiór o rozkładzie jednostajnym i niskim potencjale segmentacyjnym.

Statystyka Hopkinsa była już przeze mnie krótko opisywana na łamach bloga we wpisie: Grupowanie zmiennych ciągłych: k-średnich vs k-modes. Badałem z jej pomocą jakość zbioru po różnych przekształceniach: standaryzacja, usuwanie skośności i dwie metody dyskretyzacji.

Niestety nie jest ona dostępna w żadnej znanej mi bibliotece Python-a. Na szczęście ktoś udostępnił jej implementację na GitHub, a kolejna osoba udoskonaliła ją i opublikowała na swoim blogu. Poniżej znajduje się jej poprawiona wersja, z której korzystam.

from sklearn.neighbors import NearestNeighbors
from random import sample
from numpy.random import uniform
import numpy as np
from math import isnan

def hopkins(X):
    d = X.shape[1]
    n = len(X)
    m = int(0.1 * n)
    nbrs = NearestNeighbors(n_neighbors=1).fit(X.values)
 
    rand_X = sample(range(0, n, 1), m)
 
    ujd = []
    wjd = []
    for j in range(0, m):
        u_dist, _ = nbrs.kneighbors(uniform(np.amin(X,axis=0),np.amax(X,axis=0),d).reshape(1, -1), 2, return_distance=True)
        ujd.append(u_dist[0][1])
        w_dist, _ = nbrs.kneighbors(X.iloc[rand_X[j]].values.reshape(1, -1), 2, return_distance=True)
        wjd.append(w_dist[0][1])
 
    H = sum(ujd) / (sum(ujd) + sum(wjd))
    if isnan(H):
        print(ujd, wjd)
        H = 0
    return H

Mam nadzieję, że ten krótki wpis przypadł Ci do gustu i sama statystyka Hopkinsa okaże się dla Ciebie przydatna w pracach analitycznych. 🙂

Źródła:

photo: pixabay.com (Ichigo121212)

Podobał Ci się ten artykuł?

Jeśli tak, to zarejestruj się, by otrzymywać informacje o nowych wpisach. Dodatkowo w prezencie wyślę Ci bezpłatny poradnik 🙂

2 Komentarze

  1. tutaj chyba literówka, bo mamy podwójny nawias kwadratowy zamykający.

    w_dist, _ = nbrs.kneighbors(X.iloc[rand_X[j]].values.reshape(1, -1), 2, return_distance=True)

Dodaj komentarz

Twój adres email nie zostanie opublikowany.


*