Data Science/DATA

Python으로 배우는 데이터 전처리 이해(I) - 결측값 처리

愛林 2022. 7. 6. 19:59
반응형
결측값(Missing Value) 처리

 

데이터 정제 (Data Cleaning) 이란 데이터 전처리한 과정으로 결측값, 잡음, 이상값 등 데이터 오류를  일으킬 수 있는 요인을 삭제하고, 불일치를 해결하여 데이터의 신뢰도를 높이는 과정이다.

 

결측값 처리가 하나의 데이터 정제 과정이다.

이러한 데이터 정제과정을 해주지 않으면 분석 모델의 정확도가 떨어지고 기대하는 예측값을 얻을 수 없다.

 

데이터 오류의 원인에는 결측값 ,노이즈,이상값,모순,불일치, 중복이 있다.

노이즈는 임의적 요소로서 변수를 본래의 참값에서 벗어나게 하는 오류이고,

이상값은 데이터의 범위에서 많이 벗어난, 요소이다. (잘못 기록한 것이 아님)

 

결측값(Missing Value) 는 값이 존재하지 않고 비어있는 상태를 말한다.

NaN, Na, Inf, Null 등으로 표현한다.

 


 

결측값의 유형에는 완전 무작위 결측, 무작위 결측, 비 무작위 결측이 있다.

 

1 ) 완전 무작위 결측 : 결측값이 다른 변수들과 아무런 상관이 없는 경우

 

2) 무작위 결측 :  결측값이 다른 변수와 연관이 있어 발생되었지만 , 그 변수가 자체가 결과에 영향을 미치지 않는 경우

Ex: 여성은 나이를 공개할 가능성이 적다. => 그렇지만 여성과 나이는 관계가 없다.

 

3) 비 무작위 결측 : 결과에 영향이  있는 변수 때문에 결측값이 발생되는 경우

Ex : 키가 작은 사람은 몸무게를 공개할 가능성이 적다. => 결측값이 있는  경우키가 평균보다 작을 확률 높다.

 

데이터 결측값의 처리 절차는

결측값 식별 => 결측값 부호화 => 결측값 대체

순으로 수행된다.

 


 

■ 결측값의 처리 기법

 

1) 삭제 (Deleting) : 말 그대로 삭제. 단일값 삭제와 목록 삭제가 있다.

정보 손실이 일어날 수 있으므로 지양한다.

 

2) 대치 (Imputation) : 특정 대표값으로 혹은 회귀분석, 분류 등 여러 방법을  통해 추정된 값으로 대체한다.

일반적으로 삭제보다 대치를 많이 사용한다.

단순 대치법과 다중 대치법이 있다.

 

단순 대치법은 특정 값을 결측값으로 대치한다. 이 때 대치값은 평균값 ,최빈값 ,중앙값 등이 있다.

단순 대치법에는 또다시 완전 분석법, 단순 확률 대치법 (핫덱 대치, 콜드덱 대치, 근접 이웃 대치) 가 있다.

평균대치법 (비조건부 평균 대치, 조건부 평균대치) 도 있다.

 

다중 대치법은 결측값 추정을 여러 번 반복하여 대치된 데이터셋을 생성 후 결측값을 대치하는 방법이다.

다중 대치법을 사용할 시엔 과소추정 문제를 낮출 수 있다.

 

 


결측값 처리 실습

 

1. 결측값을 확인한다.

# 필요 라이브러리를 import 해준다.
import pandas as pd # pandas package
import numpy as np # numpy package  : np.nan 이용 결측값 생성
import matplotlib.pyplot as plt # matplotlib 시각화 패키지
import seaborn as sns # seaborn 시각화 패키지

필요한 라이브러리를 import 해주었다.

np 는 np.nan 을 이용해서 결측값을 생성해주기 위해서 불러왔다.

matplotlib 는 데이터를 시각화 해줄 수 있는 라이브러리이다.

matplotlib.pyplot 을 사용할 것이다,

seaborn 도 데이터 시각화 패키지이다. matplotlib 패키지에 기본적으로 의존한다.

 

import os
if os.name == 'nt' :
    font_family = "Malgun Gothic"
else :
    font_family = "AplleGothic"

시각화 할 때 (?) os 에 따른 폰트 깨짐 제거를 위해서 Font 를 지정해주었다.

 

sns.set(font=font_family, rc = {"axes.unicode_minus" : False})

from sklearn.impute import SimpleImputer 
from sklearn import linear_model

값이 깨지는 문제 해결을 위해서 seaborn 에서 파라미터 값을 설정해주었다. (이거 뭔 말인지 모르겠다)

 

sklearn 은 scikit-learn 인데 , Python 을 대표하는 머신러닝 라이브러리이다.

내가 머신러닝을 한거라고 ?

 

 

2. 결측값 데이터 생성

 

결측값 데이터를 생성해준다.

temp_dict = {'A열' : [np.nan, 4, 6, 5, 5, np.nan],
             'B열' : ['a', 'a', np.nan, 'b', 'b','b'],
             'C열' : [np.nan, 3.5, -1.5, np.nan, 5.5, np.nan],
             'D열' : [1, 0, 1, 0, 1, 1]
            
            }
missing_data = pd.DataFrame(temp_dict)
missing_data

temp_dict 라는 결측값 데이터를 만들고 , 이걸 데이터 프레임으로 만들어주었다.

데이터프레임이 잘 만들어졌다.

 

 

3. 결측값 데이터 확인

 

info() 를 사용해서 데이터에 대한 전반적인 정보를 확인할 수 있다.

행과 열의 크기, 컬럼명, 컬럼을 구성하는 데이터 유형, 결측값 등을 알 수 있다.

데이터프레임 전체의 결측값을 확인하려면

df.isnull(), isnull(df), df.notnull(), notnull(df) 등을 써도 좋다.

index 는 인덱스 범위이다. count 값으로 결측값 유무를 확인한다.

총 6개인데.. A열은 2개, B열은 1개, C열은 3개의 null 값이 있는 것을 확인할 수 있다.

6개에서 비는 값을 확인한 것이다.

 

위에서 말한 isnull() 을 사용해서 결측값을 확인했다.

True 라면 결측값, False 라면 결측값이 아니다.

 

sum() 을 이용해서 결측값의 갯수도 확인했다.

 

위에서 확인했는데 솔직히 왜 다시 print를 써서 확인하는 지는 모르곘으나

아무튼 간에 결측값 갯수를 다시 확인했다.

 

결측값을 시각화하자.

- matplotlib : 파이썬에서 데이터를 차트나 plot 으로 그려주는 시각화 패키지

- seaborn : matplotlib 를 기반으로 해서 색상 테마와 통계용 차트 등의 기능을 추가한 시각화 패키지

C열의 결측치가 가장 많은 것이 시각화한 그래프로 확인되었다.

 


결측값 처리 - 삭제법

 

삭제법은 앞에서 말했듯이 , 결측값이 있는 행과 열 자체를 그냥 지워버리는 방법이다.

결측값이 80% 에 가까운 경우, 그 변수 자체를 제거하는 방식이다. 

결측값을 지우면서 데이터 자체의 편향이 생길 수 있다.

dropna() 를 사용해보자.

 

axis = 0 이면 행을 말하는 것이다.

결측값이 들어있는 행이 완전히 사라진 것을 볼 수 있다.

결측값이 하나만 있어도 그냥 냅다 drop 해버렸다.

 

쓸쓸한 D열

axis  =1 이면 열을 말하는 것이다.

결측값이 하나라도 들어있는 열은 다 날려버렸다.

위에서 확인했을 때,  결측값이 없는 열은 D열 뿐이었으니 결과가 D열만 덩그러니 남으면

맞게 나온 것이다.

 

thresh 파라미터를 이용해서 결측값이 있는 열을 날려보자.

결측값 제외 후 행이 5개 미만인 열은 A,C열 이므로 날아갔다.

thresh = 5 이므로 결측값을 날렸을 때 행이 5개 미만인 열들은 다 날아갔다.

B는 결측값을 날려도 5개의 데이터가 남아있어서 날아가지 않았다.

 

B열에 null값이 존재하는 raw 를 날렸다.

B열에는 2 행에 (세번째 열) 결측값이 있었기 때문에 날아갔다.

 

 

결측값 처리 - 대치법(Imputation)

- fillna()  : DataFrame 에서 결측값을 원하는 값으로 변경하는 함수

- SimpleImputer () : sklearn 의 열의 평균이나 중앙값, 최빈으로 대체하게 해 주는 클래스

- linear_model() : sklearn 선형 회귀법을 이용하여 값을 대체 (조건부 평균 대치법)

결측값을 다시 확인한다. 

 


 

1 )  fillna() 

DataFrame 에서 결측값을 원하는 값으로 변경하는 함수

특정값으로 채울 수 있다. 특정값, 평균 : mean , 최소값 : min 등

method : ffill(이전 값으로 채우기), bfill(이후 값으로 채우기)

 

0으로 채워보자.

1열에 있던 결측값이 0.0 으로 바뀌었다.

missing_data["A열"] = missing_data["A열"].fillna(0)

이 명령어를 치면 값이 업데이트 된다.

 

이전값으로 대치해주는 ffill 을 사용해보자.

a로 대치되었다. 이전  값이 a였기 때문이다.

 

이후값으로 대치해주는 bfill 을 사용해보자.

method = 'bfill'

 

이전에는 a 였던 값이 b가 된 것을 확인할 수 있다.

 

평균으로 

연속형 데이터들만 해당된다.

숫자형 데이터였던 열들은 다 평균으로 대치되었다.

B열은 숫자형이 아니라 문자형이기 때문에 평균계산이 되지 않아 아직도 Null값이다.

 

 


 

2 ) Simplemputer() 

 

sklearn 의 열 평균이나 중앙값, 최빈으로 대체하게 해주는 클래스이다. 

strategy (most_frequent : 최빈값 , mean : 평균값, median : 중앙값)

A열의 최빈값을 결측값에 대체한다.

나머지 열의 결측값을 모두 최빈값으로 대체한다.

이거 왜 저렇게 되는 지 아시는분 ..

 


 

3) linear_model()

 

sklearn 의 선형 회귀법을 이용해서 값을 대체한다.

sklearn 에 대해서는 ...나중에 따로 또 알아보자 ..

실습 데이터를 불러왔다.

 

data = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data",
                   header = None,
                   names = ['sex', 'length', 'diameter', 'height', 
                               'whole_weight', 'shucked_weight',
                               'viscera_weight', 'shell_weight', 'rings']
                  
                  )

20개의 테스트 데이터만 저장하고,

결측값 데이터를 생성했다.

whole_weight 의 0~4까지결측값데이터가 생겼다. NaN .

학습 데이터를 생성한다. X,Y 에 결측값을 삭제한다.

 

X로 y 를 결정하는 회귀..

 

 

선형회귀 모형을 만들었다. (lin_reg) 

모델에 X 와 y를 피팅하여 선형회귀 모델을 구성했다 . (lin_reg_model)

 

선형회귀 모델로 whole_weight 추정값을 계산했다.

diameter ,height, shell_weight 를 사용했다.

 

이렇게 예측해온 whole_weight 예측값을 결측값에 대체한다.

아까 배운 fillna() 를 이용할 것이다.

 

whole_weight 열을 보면 위에서 나온 예측값들이 잘 반영된 것을 알 수 있다.

 


 ※ 저의 모든 데이터 분석 자료는 모두 공공 빅데이터 청년 인턴 교재들을 참고합니다.