środa, 8 maja 2024

EDA: Czyszczenie danych - usuwanie duplikatów, obsługa wartości brakujących

Ten wpis, podobnie jak cała zawartość bloga, odzwierciedla moje zainteresowania rozwojem w dziedzinie informatyki. Główne cele tego przedsięwzięcia to dzielenie się wiedzą, demonstracja moich umiejętności oraz chęć poznawania nowych zagadnień, co może zainteresować potencjalnych współpracowników zarówno w sferze zawodowej, jak i poza nią. Blog ten jest również okazją do samodzielnego przetwarzania zdobytej wiedzy i tworzenia osobistych notatek. Jako że sam jestem w trakcie nauki, zachęcam do niezależnego myślenia i, jeśli tematyka wpisów wpisuje się w zakres Twoich zainteresowań, do dalszej eksploracji i weryfikacji podanych przeze mnie informacji.

1. Usuwanie duplikatów:

Duplikaty danych powinny być usuwane, ponieważ każdy niepotrzebnie powielony rekord wpływa na statystyczne analizy danych. Taki duplikat jest traktowany przez model jako oddzielny, pełnoprawny rekord, co może zakłócić wyniki analizy i zmniejszyć skuteczność modeli.

Nieusunięte duplikaty w zbiorze danych przeznaczonym do trenowania modelu mogą prowadzić do jego przeuczenia. Jeżeli występuje ich nadmiar, model może stracić zdolność do generalizacji i będzie efektywnie klasyfikował tylko te przypadki, które bezpośrednio odpowiadają danym treningowym.

Dodatkowo, usunięcie duplikatów przynosi korzyści w postaci odciążenia zasobów obliczeniowych komputerów lub serwerów używanych do analizy danych.

Poniżej prezentuję kod demonstrujący proces usuwania duplikatów w zbiorze danych. Przykład zawiera prosty DataFrame składający się z trzech wierszy danych, gdzie pierwszy i ostatni wiersz są identyczne. Usunięcie duplikatów pokazuje, jak zmniejsza się liczba wierszy w ramce danych po zastosowaniu metody drop_duplicates(). Co warto wiedzieć, to df.shape[0] zwraca liczbę wierszy, a gdybyśmy użyli df.shape[1], to zwróciłoby nam liczbę kolumn.

import pandas as pd

data = [
    [1,2,3,4],
    [2,5,6,3],
    [1,2,3,4]
]

df = pd.DataFrame(data)

# Using shape[0] to display the number of rows
print("Before removing:", df.shape[0])

# Using drop_duplicates() to remove duplicate rows
data_cleaned = df.drop_duplicates()

print("After removing duplicates:", data_cleaned.shape[0])

2. Obsługa wartości brakujących:

Najpierw powiedzmy sobie o typach brakujących danych:
- MCAR (Missing Completely At Random) - Brakujące dane są całkowicie losowe i nie są powiązane z żadnymi innymi dostępnymi cechami w zestawie danych.
Przykład:
Załóżmy, że przeprowadzamy badania psychologiczne, w których uczestnicy mają się podzielić pewnymi informacjami osobistymi. Jeżeli osoba wypełniająca ankiety została przypadkowo rozproszona przez inną osobę i przez to zapomniała uzupełnić niektóre odpowiedzi, to taki brak danych jest całkowicie losowy. Brakujące informacje nie wynikają z żadnej właściwości samej osoby czy innych zmiennych w danych, ale są efektem zewnętrznego zakłócenia.

- MAR (Missing At Random) - Brakujące dane są związane z innymi zmiennymi dostępnymi w zestawie danych, jednak nie zależą bezpośrednio od wartości brakującej zmiennej.
Przykład:
Załóżmy, że kwestionariusz pyta respondentów o ilość snu. Część z nich uznała to pytanie za zbyt intymne lub prywatne, dotyczące ich zdrowia i snu, i postanowiła je pominąć. Jednak zauważono, że respondenci, którzy pozytywnie wyrazili się o swoim ogólnym zadowoleniu z życia, częściej podawali wartości odpowiadające optymalnej długości snu, sugerującej zdrowy sen. Z kolei w przypadkach, gdy odpowiedzi na pytanie o zadowolenie z życia były negatywne, częściej odnotowywano brak odpowiedzi na pytanie o długość snu.

- MNAR (Missing Not At Random) - Brak danych jest bezpośrednio powiązany z wartością, której brakuje, co oznacza, że przyczyny braków w danych są systematycznie związane z samą zmienną brakującą.
Przykład:
Kontynuując przykład z badań psychologicznych, załóżmy, że niektóre pytania w ankiecie dotyczą bardzo osobistych aspektów, gdzie przeszkodą do odpowiedzi na takie pytania może być skłonność do introwertyzmu lub inne bliżej nieznane obawy przed dzieleniem się pewnymi informacjami. Osoby o wyższym poziomie introwertyzmu mogą czuć się niekomfortowo, odpowiadając na takie pytania, co prowadzi do selektywnego pomijania ich przez te osoby. Brak odpowiedzi jest w tym przypadku bezpośrednio związany z naturą pytania, co jest charakterystyczne dla sytuacji MNAR, gdzie brak danych wynika z treści pytania lub cech respondentów.

W jaki sposób możemy wypełnić brakujące dane (None)? Możemy użyć do tego średniej, mediany lub mody. Poniżej kodu z ChatGPT:

import pandas as pd
import numpy as np

# Create a sample DataFrame with some missing values
data = {
    'Age': [25, 27, 29, None, 28, 30, None, 29],
    'Salary': [50000, 54000, None, 52000, 55000, None, 53000, 51000],
    'Department': ['HR', 'HR', 'IT', 'IT', 'HR', 'IT', None, 'HR']
}

df = pd.DataFrame(data)

# Display the original DataFrame
print("Original DataFrame:")
print(df)

# Filling missing values in 'Age' using the mean value of the column
# It's suitable for numerical data without extreme values
df['Age'].fillna(df['Age'].mean(), inplace=True)

# Filling missing values in 'Salary' using the median value of the column
# Median is less sensitive to outliers and often more representative for skewed data
df['Salary'].fillna(df['Salary'].median(), inplace=True)

# Filling missing values in 'Department' using the mode (the most frequent value)
# Mode is used for categorical data to fill gaps with the most common category
mode_value = df['Department'].mode()[0]  # Extract the mode value
df['Department'].fillna(mode_value, inplace=True)

# Display the DataFrame after filling missing values
print("\nDataFrame after filling missing values with Mean, Median, and Mode:")
print(df)

mode()[0] zwraca obiekt typu Series, a [0] pozwala na pobranie wartości modalnej o największej częstotliwości występowania z tej serii danych.

inplace to parametr, który może przyjąć wartość True, gdy chcemy dokonać zmian bezpośrednio na oryginalnym obiekcie DataFrame. Gdy parametr przyjmuje wartość False, co jest wartością domyślną, zmiany nie są aplikowane na oryginalnym DataFrame, lecz zwracane jako nowy obiekt, który można przypisać do nowej zmiennej.

Powyższa metoda to tylko jedna z możliwości radzenia sobie z brakującymi danymi.

Brak komentarzy:

Prześlij komentarz

Analiza sentymentów - wpisy na mediach społecznościowych (podział danych)

Ten wpis zaczniemy od stworzenia DataFrame z danymi treningowymi train_df = pd.read_csv('train.csv', encoding='ISO-8859-1')....