결측값(missing values)의 처리에 대해서 다뤄보겠습니다.
먼저 결측치를 찾아봅시다. 다음과 같이 isnull()
을 이용하거나 info()
등으로 확인 가능합니다.
isMissing = X_Train['feature'].isnull() # generate truth table about missing values existence.
Sum(isMissing) # if result > 0, there are missing values.
결측치가 있는 column확인
cols_with_missing = [col for col in X_train.column if X_train[col].isnull().any() ]
결측치가 많은 컬럼 순으로 확인
X.isnull().sum().sort_values(ascending=False)[:10]
다음과 같이 info()로 확인할 수 도 있습니다.
X_Train.info()
간혹 null이 아닌 그저 비어있는 스트링 ""이 존재하는 경우가 있는데
이는 isnull에 잡히지 않습니다.
이를 바꿔주고 다시 isnull을 해보는 것이 좋습니다.
df.replace("", float("NaN"), inplace=True)
df.isnull().values.any()
결측치를 찾았다면 이를 조치할 수 있는 방법은 크게 세가지가 있습니다.
1. Removal
2. Imputation
3. Using other learning algorithms
결측치가 많은 피처를 그냥 없애버립니다.
가장 단순하지만 상당히 효율적인 방법입니다.
강제로 impute시킨 데이터들이 오히려 bias를 만들어낼 수 있기 때문입니다.
df.drop(['feature'], axis=1)
cols_with_missing = [col for col in X_train.column if X_train[col].isnull().any() ]
reduced_X_train = X_train.drop(cols_with_missing, axis=1)
reduced_X_valid = X_valid.drop(cols_with_missing, axis=1)
데이터를 치환하는 방법입니다. 다음과 같이 통계량으로 변환하는 것이 기본적입니다.
이런 통계량 치환의 방법은 데이터가 nomalized하게 유지되기 때문에 linear model에 효과적 입니다.
아울러, 범주형의 경우 "Unknown"으로 치환하여 새로운 범주를 형성하는 것도 가능합니다. 이런 경우에는 Tree-based model이 적합합니다.
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
imp.fit(data)
imp.transform(data)
혹은 이미 scale을 했을 경우, -1이나 2로 치환하여 결측치에 대해 통상 범위에서 나타날 수 없는 outlier의 의미를 모델에게 부여해주는 것도 좋습니다.
가장 advanced한 접근이지만 개념은 간단합니다. 해당 피처의 결측치를 다른 피처들을 기반으로 Linear Regression등 알고리즘을 사용하여 예측하는 것입니다.
왕도는 없습니다.
다양한 방식을 수행해보며 가장 적절한 결측치 처리 방법을 확인해야 합니다.
[1] Abhishek Thakur, Kaggle's 30 Days Of ML (Youtube)
[2] Burkov, The hundred page machine learning