일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- pytorch
- Semantic Segmentation
- MySQL
- 3줄 논문
- Recsys-KR
- 큐
- DilatedNet
- Image Segmentation
- 나는 리뷰어다
- Object Detection
- 스택
- 한빛미디어
- 코딩테스트
- Segmentation
- 파이썬
- eda
- Machine Learning Advanced
- DFS
- 튜토리얼
- 프로그래머스
- 입문
- 추천시스템
- 엘리스
- 협업필터링
- 나는리뷰어다
- hackerrank
- TEAM EDA
- 알고리즘
- Python
- TEAM-EDA
- Today
- Total
TEAM EDA
결측치 처리 (Missing Value) 본문
NOTE: 대부분의 내용은 https://blog.naver.com/tjdudwo93/220976082118을 기반으로 Titanic 데이터에 실습을 적용하는 것으로 진행됩니다.
군밤고굼님의 설명에 따르면 결측치를 살펴보는 과정은 아래와 같은 과정으로 진행됩니다.
1. 결측 데이터의 종류
|
2. 결측값 유형 탐색하기 (표 만들기, 결측치간 상관관계)
|
3. 결측 데이터의 원인 및 각각의 원인에 따른 처리 방법론
|
4. 결측치 처리 방법 선택 ( 1. 합리적 접근법 )
|
5. 결측치 처리 방법 선택 ( 2. 완전제거법 )
|
6. 결측치 처리 방법 선택 ( 3. 다중대체 )
1. 결측 데이터의 종류
- 완전 무작위 결측(MCAR : Missing completely at random)
변수 상에서 발생한 결측치가 다른 변수들과 아무런 상관이 없는 경우 우리는 완전 무작위 결측(MCAR)이라고 부릅니다. 대부분의 결측치 처리 패키지가 MCAR을 가정으로 하고 있고 보통 우리가 생각하는 결측치라고 생각하시면 됩니다. 예를 들어, 데이터를 입력하는 사람이 깜빡하고 입력을 안했다든지 전산오류로 누락된 경우 등 입니다. 이러한 결측치는 보통 제거하거나 대규모 데이터 셋에서 단순 무작위 표본추출을 통해서 완벽한 데이터셋으로 만들 수 있습니다.
- 무작위 결측(MAR : Missing at random)
누락된 자료가 특정 변수와 관련되어 일어나지만, 그 변수의 결과는 관계가 없는 경우를 의미합니다. 그리고 누락이 전체 정보가 있는 변수로 설명이 될 수 있음을 의미합니다.(누락이 완전히 설명 될 수 있는 경우 발생) 예를 들어, 남성은 우울증 설문 조사에 기입 할 확률이 적지만 우울함의 정도와는 상관이 없는 경우입니다.
- 비 무작위 결측(MNAR : Missing at not random)
위의 두가지 유형이 아닌 경우를 MNAR이라고 합니다. MNAR은 누락된 값(변수의 결과)이 다른 변수와 연관 있는 경우를 의미합니다. 위의 예시를 확장해서, 만약 남성이 우울증 설문 조사에 기입하는게 우울증의 정도와 관련이 있다면 이것은 MNAR입니다.
MAR과 MNAR의 차이에 대한 다른 예시로 아래와 같은 예시가 있습니다.
-
일부 응답자가 귀하에게 체중을 말했고 다른 응답자는 체중을 말하지 않은 이유가 없습니다. 즉, Y가 누락 될 확률은 X 또는 Y와 관련이 없습니다. 이 경우 데이터가 무작위로 완전히 누락됩니다(MCAR)
-
여성은 체중을 공개 할 가능성이 적습니다. 즉, Y가 누락 될 확률은 X의 값에만 의존합니다. 이러한 데이터는 무작위 결측이라고 합니다(MAR)
-
무거운 (또는 가벼운) 사람들은 체중을 공개 할 가능성이 적습니다. 즉, Y가 누락 될 확률은 Y 자체의 관찰되지 않는 값에 달려 있습니다. 이러한 데이터는 비 무작위 결측이라고 합니다(MNAR)
출처: Ziad Taib(http://www.math.chalmers.se/Stat/Grundutb/GU/MSA650/S09/Lecture5.pdf)
더 자세한 내용은 위키피디아(https://en.wikipedia.org/wiki/Missing_data)를 참고하시기 바랍니다.
2. 결측값 유형 탐색하기
위에서 말했듯이 결측치의 종류를 확인하는것은 중요합니다. 그러한 과정을 탐색하기 위해 먼저 어떤 변수에 결측치가 있는지 부터 확인하도록 하겠습니다. 실습은 전에 했던 자료와 동일하게 Titanic으로 진행하겠습니다.
# 파이썬에서는 .isnull()을 통해서 결측치를 확인할 수 있습니다.
total = df_train.isnull().sum().sort_values(ascending=False)
percent = (df_train.isnull().sum()/df_train.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
percent_data = percent.head(20)
percent_data.plot(kind="bar", figsize = (8,6), fontsize = 10)
plt.xlabel("", fontsize = 20)
plt.ylabel("", fontsize = 20)
plt.title("Total Missing Value (%)", fontsize = 20)
위의 [그림1]은 각 변수의 결측치 비율을 확인한 자료 입니다. 결측치는 총 3개의 변수 Cabin, Age, Embarked에서 발생하고 눈으로 보기에는 결측치끼리는 아무런 관련이 없어 보입니다. 이를 확인하기 위해 결측치 끼리의 상관관계를 뽑아보면 아래 [그림2]와 같습니다.
import missingno as msno
missingdata_df = df_train.columns[df_train.isnull().any()].tolist()
msno.heatmap(df_train[missingdata_df], figsize=(8,6))
plt.title("Correlation with Missing Values", fontsize = 20)
df_train.corr()
위의 hasCabin변수는 결측치는 0, 그렇지 않으면 1로 만든 변수입니다. 이를 다른변수와의 상관관계를 그려서 확인하면 Pclass와 Fare과 높은 관계를 가지고 있는것을 확인할 수 있습니다. 하지만 hasAge의 경우는 다른 변수와의 상관성이 낮습니다.
data = pd.concat([df_train['Fare'], df_train['Embarked']], axis=1)
f, ax = plt.subplots(figsize=(8, 6))
fig = sns.boxplot(x='Embarked', y="Fare", data=data)
위의 [그림4]와 [그림5]를 보면 사물함이 결측치가 아닐수록 Pcalss가 1에 가깝습니다. Pclass가 1인 사람은 거의 Cabin이 결측치가 아니고, Pclass가 3인 사람은 거의 Cabin의 결측치 입니다. 추가적으로 Fare과도 비교해보면 Cabin이 있는 사람의 Fare이 대체로 높은것을 확인할 수 있습니다. 이렇게 다른 변수와 연관있어서 결측치인 경우 우리는 MAR 유형이라고 합니다.
Embarked의 경우 결측치가 단 두개밖에 없어서 굳이 유형을 분리할 이유가 없고 Age의 경우는 다른변수와는 관계가 없고, Age에 따라서 결측치가 생겼다고 판단하기 어렵기 때문에 둘다 MCAR으로 가정하고 결측치를 채워보도록 하겠습니다.
3. 결측 데이터의 원인 및 각각의 원인에 따른 처리 방법론
[그림1]에서 확인했듯이 결측치는 3개의 변수 Cabin, Age, Embarked에서 있었고 각각 결측치의 비율은 77%, 19.8%, 0.002% 입니다. 위에서 말했듯 Cabin의 경우 결측치가 생긴 이유는 사물함이 존재하지 않아서 일 가능성이 높고, Age와 Embarked는 MCAR 가정에 따라서 임의로 누락 되었을 가능성이 높습니다. Cabin의 경우 존재하지 않아서 결측치이니깐 위에서 hasCabin처럼 새로 변수를 만들어주는것이 좋고, Age와 Embarked의 경우는 다른 변수와의 관계를 통해서 결측치를 처리해주는것이 좋습니다.
보통 결측치를 처리할 때는 hair et al.(2006)에 따르면 아래의 표와 같이 처리해준다고 합니다.
결측치 비율 |
처리 방법 |
10% 미만 |
제거 or 어떠한 방법이든지 상관없이 Imputation |
10% 이상 20% 미만 |
hot deck , regression , model based method |
20% 이상 |
model based method , regression |
[표1] 결측치의 비율에 따른 처리 방법
위의 방법론에 따라 저희는 Age는 model based method를 이용하여 채워 넣고(다중대체 사용) Embarked는 다른 변수와의 관계을 이용하여 합리적 대체를 하겠습니다. 위의 실습자료에서는 제거의 경우는 적합하지 않아서 방법론만 설명하겠습니다.
4. 결측치 처리 방법 선택 (1. 합리적 접근법)
df_train[df_train['Embarked'].isnull()]
# 특정 행의 열을 채우는 방법
df_train.loc[61, 'Embarked'] = 'S'
df_train.loc[829, 'Embarked'] = 'S'
# 특정 열의 결측치를 채우는 방법
df_train['Embarked'] = df_train['Embarked'].fillna('S')
# 완전 제거법
# 결측치가 들어가 있는 행 제거
a = df_train.dropna(axis = 0)
# 결측치가 들어가 있는 열 제거
b = df_train.dropna(axis = 1)
# 특정 열을 대상으로 제거
c = df_train[df_train['Cabin'].notnull()]
# print(a.shape, b.shape, c.shape)
# (183, 14) (891, 11) (204, 14)
6. 결측치 처리 방법 선택 (3. 다중 대체법)
가장 어려운 대체방법으로 하나의 관측치에 2개 이상의 결측치가 존재할 경우에 잘 들어맞는 결측치 처리 방법입니다. 다중 대체법의 종류는 여러가지 있지만 대표적으로 Mice, Amelia , MissForest, Hmisc, Mi를 이용합니다. 아래의 링크에 R을 이용한 방법론이 잘 설명되었으니 참고하시기 바랍니다. (https://www.analyticsvidhya.com/blog/2016/03/tutorial-powerful-packages-imputing-missing-values/)
이번에는 가장 대표적인 예 중 하나인 Mice를 이용해서 예측해보도록 하겠습니다. Mice를 사용하는 이유는 MCAR 결측치를 가정하였을 때 적합하고 Numeric변수와 Categorical변수들이 섞여있을 때에도 잘 작동하기 때문입니다. 근데 결측치 패키지는 python보다는 R에서 잘 작동하기 때문에 이 부분은 R로 작업하였습니다.
Mice의 경우 [그림9]처럼 진행 되고 이를 더 풀어서 설명하면 아래와 같습니다.
- 누락된값은 df에 있는 다른 모든변수를 사용하여 값을 예측하여 채워 넣는다.
- 누락된 자료가 채워진 완성된 데이터 세트를 여러개 만든다. (default = 5)
- 각각의 완성된 데이터 세트에 대해 with()를 사용하여 통계 모형을 순서대로 적용한다.
- pool() 함수를 사용하여 이들 각각의 분석결과를 하나로 통합한다
코드
https://www.kaggle.com/chocozzz/titanic-tutorial-with-python?scriptVersionId=7296387
참고자료
https://blog.naver.com/tjdudwo93/220976082118
https://www.jstatsoft.org/article/view/v045i03/v45i03.pdf
http://www.math.chalmers.se/Stat/Grundutb/GU/MSA650/S09/Lecture5.pdf
'TEAM EDA > EDA 1기 ( 2018.03.01 ~ 2018.09.16 )' 카테고리의 다른 글
kaggle - Rossmann Store sales Prediction (1) (0) | 2019.09.10 |
---|---|
Decision Tree (의사결정나무) (0) | 2019.09.10 |
linear regression (선형회귀분석) with R (0) | 2019.09.10 |
EDA (Exploratory Data Analysis) 탐색적 데이터 분석 (8) | 2018.11.12 |
TEAM-EDA 1기 활동 내역 (0) | 2018.11.12 |