Histogramy

Histogramy to jedno z najbardziej podstawowych narzędzi każdego badacza danych. Są proste w zrozumieniu, tanie w wykonaniu i niosą ze sobą bardzo przydatne informacje. Szczególnie przydatne są do zrozumienia uzyskanych wyników bądź przyglądania się zebranym danym. O histogramach zaczyna się mówić już w liceum i niestety wiele osób na tym etapie podchodzi do nich jak do czegoś strasznego i zupełnie zbędnego w życiu. Ja natomiast uważam, że nie ma się czego absolutnie bać i że warto oswoić się z histogramami. W tym artykule pokażę jak ugryźć histogramy w Pythonie przy pomocy modułu Physt.

Histogram – definicja

Czym w ogóle jest histogram? Zobaczmy co na ten temat do powiedzenia ma Wikipedia:

Histogram – jeden z graficznych sposobów przedstawiania rozkładu empirycznego cechy. Składa się z szeregu prostokątów umieszczonych na osi współrzędnych. Prostokąty te są z jednej strony wyznaczone przez przedziały klasowe (…) wartości cechy, natomiast ich wysokość jest określona przez liczebności (…) elementów wpadających do określonego przedziału klasowego.

Wincenty Okoń: Nowy słownik pedagogiczny. Warszawa: Wydawnictwo Akademickie „Żak”, 2001, s. 129. ISBN 83-88149-41-5.

Brzmi bardzo groźnie i dość niejasno. Fakt, definicja ta jest dość zwięzła i precyzyjna, żeby dobrze zdefiniować histogram, ale w praktyce nie za wiele nam daje na pierwszy rzut oka. O czym ona mówi? Ano, że mamy prostokąty. I te prostokąty umieszczone są na osi współrzędnych. Możemy więc domyślić się, że będzie to wykres składający się z prostokątów. Z jednej strony prostokątów mamy przedziały klasowe, a ich wysokość będzie odpowiadała liczebności danego przedziału. Proste nie?

Spójrzmy więc na przykładowy histogram:

Przykładowy histogram 1D
Przykładowy histogram 1D

Czy wszystko dla nas jest jasne?

Histogram – wytłumacz mi jak bym miał 5 lat

Jeśli nie wszystko na powyższym histogramie jest jasne, to zaraz będzie. Wyobraźmy sobie sytuację, że jesteśmy nauczycielem wychowania fizycznego w dużej szkole. Chcemy zorganizować zawody koszykarskie. Z naszej szkoły zgłosiło się 100 osób do zawodów. Chcielibyśmy kupić im koszulki. Koszulki takie mają rozmiar pasujący do wzrostu. Zmierzyliśmy wzrost wszystkich zapisanych osób i zapisaliśmy to sobie na liście.

Chcemy zlecić osobie odpowiedzialnej za zakupy zakupienie odpowiednich koszulek. Możemy jej dać listę wszystkich pomiarów. I pewnie spotkamy się ze spojrzeniem „Na prawdę?”. Możemy też zapytać się tej osoby, jakie wartości wzrostu wpadają w poszczególne rozmiary i podać jej konkretne liczby. Ale może okazać się, że nie mamy jeszcze żadnych ofert, więc nie wiemy, jak te przedziały będą wyglądać.

No i w tym miejscu pojawia się histogram. Decydujemy sobie „z głowy”, że chcemy mieć 10 przedziałów. Patrzymy na nasze pomiary w celu znalezienia największej i najmniejszej liczby. Widzimy, że najniższa osoba miała 160 cm wzrostu, a najwyższa 210. Różnica wynosi więc 50 cm. Jeśli podzielimy ten zakres na 10 równych kawałków, to kawałki te będą miały po 5 cm.

Nasze przedziały będą więc wyglądać tak: od 160 do 165, od 165 do 170, od 170 do 175 i tak dalej aż do przedziału od 205 do 210. Ale pozostaje tutaj pytanie, co z wartościami granicznymi. Otóż w praktyce, wartość graniczna musi wpaść w któryś przedział. W naszym przypadku pierwszy przedział będzie zawierał wartości x >= 160 i x < 165. Czyli po matematycznemu będzie to [160, 165). Problem pojawia się przy ostatnim przedziale, więc po prostu trzeba będzie go domknąć z dwóch stron: [205, 210] – co będzie oznaczać, że wpadną do niego osoby ze wzrostem pomiędzy 205 i 210, z tymi wartościami włącznie.

Skoro mamy już przedziały, już prawie zakończyliśmy rozwiązywanie naszego problemu. Teraz bierzemy listę naszych pomiarów i patrzymy na każdy z nich po kolei. Bierzemy pomiar i patrzymy, do którego przedziału wpadnie. Przy tym przedziale zaznaczamy sobie +1 i idziemy do kolejnego pomiaru. Po przejściu przez całą listę patrzymy na każdy przedział i sumujemy +1, które tam są.

W ten sposób policzyliśmy, ile osób jest w danym przedziale. Zostaje nam ostatni krok, czyli narysowanie tego, co policzyliśmy. Na dolnej osi zaznaczamy sobie kolejne przedziały i rysujemy słupki, których wysokość odpowiada ilości osób w grupie. I już.

I jeśli przekażemy taki histogram osobie odpowiadającej za zakupy, to nie zobaczy ona 100 liczb. Zobaczy fajny wykres, z którego od razu wydobędzie informacje. Oczywiście, zamiast wykresu, moglibyśmy jej po prostu dać liczbę uczniów, którzy wpadli w dany zakres, ale to byłoby za proste ;).

Physt

W Pythonie mamy kilka modułów, które umożliwiają wyświetlanie histogramów. Są to na przykład: matplotlib, seaborn i pandas. Dwa ostatnie wykorzystują co prawda ten pierwszy do rysowania wykresów, ale steruje się nimi w nieco inny sposób. W nieco inny sposób używa się także modułu Physt, który także korzysta z matplotlib.

Żeby zacząć korzystać z modułu Physt, musimy go zainstalować (najlepiej w środowisku wirtualnym):

pip install physt

Po szybkiej instalacji możemy od razu skorzystać z tego modułu. Odtwórzmy wykres, który umieściłem powyżej. Kod, który go stworzył, będzie wyglądał tak:

%matplotlib inline

from physt import h1
import numpy as np   

#heights = np.random.randint(160,211, size=(1, 100))
heights = np.array([[199, 168, 204, 205, 164, 168, 179, 205, 196, 194, 198, 170, 177, 183, 169, 194, 178, 205, 162,
                     190, 186, 199, 173, 179, 160, 182, 162, 206, 210, 208, 172, 181, 199, 198, 168, 204, 210, 169,
                     195, 161, 168, 180, 194, 181, 203, 187, 173, 205, 184, 164, 204, 166, 187, 174, 208, 182, 172,
                     196, 170, 205, 184, 179, 193, 179, 165, 171, 208, 203, 184, 200, 177, 192, 173, 170, 176, 176,
                     197, 202, 182, 199, 172, 207, 191, 175, 206, 183, 204, 170, 201, 200, 205, 183, 193, 178, 193,
                     167, 182, 203, 181, 182]])

hist = h1(heights)
hist.title = "Wzrost uczestników zawodów"
hist.axis_name = "Wzrost [cm]"


plot = hist.plot(show_values=True, show_stats = True)

fig = plot.get_figure()
fig.savefig("../output/016-1d.png")

Jeśli dobrze się przyjrzymy, to zauważymy, że korzystamy tylko z jednej funkcji z modułu Physt. Jest to funkcja h1, która tworzy nam obiekt odpowiadający jednowymiarowemu histogramowi. Czyli dokładnie to, co było nam potrzebne. Reszta jest już dodatkiem.

Histogram dwuwymiarowy

A co gdybyśmy chcieli wykonać histogram dwuwymiarowy? Przede wszystkim musimy mieć dane, które mają dwa wymiary. W naszym wypadku mogłaby to być np. wzrost i waga. Wtedy mamy 100 pomiarów tych dwóch wartości. Jak wyglądałby wiec taki histogram. Na jednej osi mielibyśmy przedziały jednej zmiennej a na drugiej przedziały drugiej zmiennej. Wtedy zamiast prostokątów, w których istotna jest ich długość, otrzymamy prostokąty, których kolor (i opcjonalnie wartość liczbowa wewnątrz) odpowiadają liczebności obserwacji w konkretnych przedziałach. Histogramy te będą wyglądać mniej więcej tak:

Przykładowy histogram 2D
Przykładowy histogram 2D

Kod odpowiedzialny za jego narysowanie:

from physt import h2
weights = np.array([[83, 57, 66, 63, 75, 60, 63, 53, 88, 75, 88, 66, 93, 87, 65, 65,
        62, 99, 54, 83, 52, 58, 90, 92, 73, 68, 62, 56, 87, 87, 82, 93,
        63, 70, 76, 54, 97, 79, 67, 86, 53, 99, 96, 60, 50, 50, 85, 84,
        92, 55, 63, 76, 68, 75, 80, 88, 80, 91, 63, 53, 93, 89, 99, 60,
        76, 80, 68, 79, 58, 93, 96, 54, 65, 96, 59, 62, 73, 87, 86, 54,
        84, 75, 86, 87, 56, 98, 63, 84, 96, 91, 70, 56, 66, 60, 59, 58,
        92, 96, 88, 89]])

hist2 = h2(heights.flatten(), weights.flatten(), axis_names=["Wzrost [cm]", "Waga [kg]"])

plot2 = hist2.plot(show_values = True)

fig2 = plot2.get_figure()
fig2.savefig("../output/016-2d.png")

Co dalej?

Tworzenie i interpretacja histogramów nie wymaga żadnej wiedzy tajemnej. Problemy zaczynają się, jeśli faktycznie musimy wpasować się w jakiś styl graficzny bądź mamy jakieś konkretne potrzeby. Moduł Physt powstał po to, aby umożliwić jak najwygodniejsze dopasowanie i rysowanie histogramów. Ja jednak przyznam się, że nigdy nie miałem potrzeby tworzenia histogramów poza najprostszymi, które pokazałem powyżej. Jeśli jednak Ty czytelniku masz taką potrzebę, to myślę, że nawet jeśli nie Physt, to sam matplotlib pozwoli Ci tworzyć takie histogramy, jakie sobie zamarzysz.

Jeśli zainteresował Cię bardziej moduł Physt, to polecam Ci to video, gdzie Twórca wyjaśnia, dlaczego w ogóle podjął się stworzenia kolejnego modułu Pythonowego i to tylko do histogramów: Meaningful histogramming with Physt – Jan Pipek.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *