L4: Analiza eksploracyjna zbioru danych#

Exploratory data analysis (EDA)#


Przed rozpoczęciem rozwiązywania problemu przy użyciu metod uczenia maszynowego, w szczególności przed rozpoczęciem budowania modelu, konieczne jest sprawdzenie, z jakimi danymi przyszło się nam mierzyć.

Wśród podstawowych kwestii, które powinniśmy sprawdzić, są:

  • ile mamy cech?

  • które spośród nich to cechy kategoryczne, a które numeryczne?

  • jakie wartości przyjmują poszczególne cechy?

  • czy wśród danych są brakujące wartości?

  • czy istnieje i jak wygląda etykieta? (w szczególności - czy mierzymy się z zadaniem klasyfikacji, regresji czy klasteryzacji?)

  • czy dane są zbalansowane względem danej wyjściowej?

Dla małych i prostych zbiorów do nauki (tzw. toy tasks), zazwyczaj wystarczające jest ręczne przejrzenie pliku z danymi, by potrafić odpowiedzieć na w/w pytania. Niemniej przy bardziej ambitnych zadaniach, z pomocą przychodzą narzędzia automatyzujące pracę.

Przykładowy zbiór danych#

Przeanalizujmy klasyczny zbiór danych dotyczący wina (opublikowany przez Forina, M. et al, PARVUS - An Extendible Package for Data Exploration, Classification and Correlation. Institute of Pharmaceutical and Food Analysis and Technologies, Via Brigata Salerno, 16147 Genoa, Italy, więcej informacji tutaj)

Zbiór zawiera właściwości fizykochemiczne różnych próbek wina pobranych z jednego z regionów słonecznej Italii, jednakże pochodzących od trzech różnych plantatorów. Założeniem problemu jest określenie, który z nich jest wytwórcą danej próbki.

W celu uczynienia przykładu ambitniejszym, zbiór został celowo zaszumiony - tj. usunięto losowo część wartości.

Zacznijmy od wczytania zbioru:

import pandas as pd

df = pd.read_csv(
    "../docs/lab4/wine_with_nulls.csv",
)
df.head()
alcohol malic_acid ash alcalinity_of_ash magnesium total_phenols flavanoids nonflavanoid_phenols proanthocyanins color_intensity hue od280/od315_of_diluted_wines proline target
0 14.23 1.71 2.43 15.6 127.0 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065.0 0
1 13.20 1.78 2.14 11.2 100.0 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050.0 0
2 13.16 2.36 2.67 18.6 101.0 NaN 3.24 0.30 2.81 5.68 1.03 3.17 1185.0 0
3 14.37 1.95 2.50 16.8 113.0 3.85 NaN 0.24 2.18 7.80 0.86 3.45 1480.0 0
4 13.24 2.59 NaN 21.0 118.0 2.80 2.69 0.39 1.82 4.32 1.04 2.93 735.0 0

Na pierwszy rzut oka możemy stwierdzić, że wszystkie kolumny są numeryczne, ale ich wartości różnią się dość znacząco.

Podstawowe informacje o statystykach zbioru danych możemy uzyskać przy wbudowanej w Pandas metodzie describe()

df.describe()
alcohol malic_acid ash alcalinity_of_ash magnesium total_phenols flavanoids nonflavanoid_phenols proanthocyanins color_intensity hue od280/od315_of_diluted_wines proline target
count 171.000000 170.000000 170.000000 167.000000 169.000000 171.000000 167.000000 171.000000 173.000000 170.000000 175.000000 170.000000 172.000000 178.000000
mean 13.009357 2.318059 2.360000 19.404790 100.088757 2.291988 2.019760 0.365614 1.583295 5.009529 0.959920 2.615176 756.209302 0.938202
std 0.819951 1.108406 0.275004 3.328986 14.490898 0.626310 1.006122 0.123074 0.572402 2.292621 0.228525 0.706861 315.609153 0.775035
min 11.030000 0.740000 1.360000 10.600000 70.000000 0.980000 0.340000 0.130000 0.410000 1.280000 0.480000 1.270000 278.000000 0.000000
25% 12.370000 1.575000 2.202500 17.150000 88.000000 1.730000 1.095000 0.270000 1.250000 3.220000 0.785000 1.970000 508.000000 0.000000
50% 13.050000 1.850000 2.360000 19.400000 98.000000 2.350000 2.170000 0.340000 1.540000 4.640000 0.980000 2.780000 679.000000 1.000000
75% 13.700000 3.030000 2.547500 21.500000 108.000000 2.800000 2.885000 0.445000 1.950000 6.122500 1.120000 3.177500 996.250000 2.000000
max 14.830000 5.800000 3.230000 30.000000 162.000000 3.880000 5.080000 0.660000 3.580000 13.000000 1.710000 4.000000 1680.000000 2.000000

Wykresy z użyciem metod Pandas#

Pandas udostępnia prosty interfejs rysowania wykresów Matplotlib bezpośrednio z DataFrame. Dzięki temu możemy prościej zwizualizowac wartości numeryczne i zaobserwować charakterystykę zbioru danych.

df = df[["alcohol", "ash", "total_phenols"]]

df.plot()
<Axes: >
../_images/c21c9c66b9fd5bbd4eb6248c8f90c0633cc104652b3cb054f2409eb7dbaabbe6.png
df.plot(subplots=True, figsize=(10, 5))
array([<Axes: >, <Axes: >, <Axes: >], dtype=object)
../_images/a8b7c9674152cb1ecbb415f903a43a0cb5a69190b07fdaed3ab97fbfc085fa26.png
df.plot(kind="bar", subplots=True, figsize=(10, 5))
array([<Axes: title={'center': 'alcohol'}>,
       <Axes: title={'center': 'ash'}>,
       <Axes: title={'center': 'total_phenols'}>], dtype=object)
../_images/ef5c5cc277f037c71f8c0cd06c42181c8caa87f617a05b07e0c6dd3f52957c6e.png
from pandas.plotting import scatter_matrix

scatter_matrix(df, alpha=0.5, figsize=(10, 10), diagonal="kde")
array([[<Axes: xlabel='alcohol', ylabel='alcohol'>,
        <Axes: xlabel='ash', ylabel='alcohol'>,
        <Axes: xlabel='total_phenols', ylabel='alcohol'>],
       [<Axes: xlabel='alcohol', ylabel='ash'>,
        <Axes: xlabel='ash', ylabel='ash'>,
        <Axes: xlabel='total_phenols', ylabel='ash'>],
       [<Axes: xlabel='alcohol', ylabel='total_phenols'>,
        <Axes: xlabel='ash', ylabel='total_phenols'>,
        <Axes: xlabel='total_phenols', ylabel='total_phenols'>]],
      dtype=object)
../_images/e86a6110735206ef55da20a8be5950e69e2aaf305028bbda1db2a9eab73eb0d1.png

See also

Więcej o możliwościach Pandas w kontekście generowania wykresów - w dokumentacji

Ydata-profiling#

Ydata-profiling (w przeszłości pandas-profiling) - biblioteka automatycznie analizująca zbiór danych i generujaca interaktywny raport. Alternatywnie, raport można zapisać w formacie .html

Instalacja przebiega standardowo:

pip install ydata-profiling

Użycie biblioteki jest niezwykle proste:

from ydata_profiling import ProfileReport

df = pd.read_csv(
    "../docs/lab4/wine_with_nulls.csv",
)

profile = ProfileReport(df)
profile.to_notebook_iframe()