캐글(Kaggle)에서 클론 코딩으로 공부를 하면서, 필요한 내용과 기술들을 정리하고 있습니다.
사용한 Competition의 데이터와 클론 코딩의 출처는 다음과 같습니다.
https://www.kaggle.com/c/siim-isic-melanoma-classification
https://www.kaggle.com/datafan07/analysis-of-melanoma-metadata-and-effnet-ensemble
Competition에 대해서 간단히 요약을 하자면,
피부 사진을 보고 피부암의 일종인 악성 흑색종(malignant melanoma)을 구분하는 Competition입니다.
해당 데이터와 함께 EDA의 과정 중 하나인 결측치/결측값(missing values)을 분석해보고 seaborn의 barplot을 이용해서 시각화까지 해보도록 하겠습니다.
필요한 라이브러리와 데이터 불러오기
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/test.csv')
- 데이터 분석에 필요한 pandas, numpy 그리고 데이터 시각화에 필요한 matplotlib, seaborn 라이브러리를 불러옵니다.
- 데이터는 .read_csv()를 사용하여 로컬에 저장되어 있는 데이터를 불러옵니다. train데이터와 test데이터가 구분되어 있기에 각각 불러옵니다.
데이터 확인과 가공
train.shape
(33126, 8)
- numpy의 .shpae를 사용하여 train 데이터셋의 데이터수와 특성의 수를 확인할 수 있습니다.
train.columns.tolist()
['image_name',
'patient_id',
'sex',
'age_approx',
'anatom_site_general_challenge',
'diagnosis',
'benign_malignant',
'target']
- numpy의 .tolist()를 사용하여 데이터의 특징(feature)이 어떠한 것들이 있는지 확인했습니다. 특징에 대한 설명은 다음과 같습니다.
image_name: 이미지의 이름
patient_id: 환자의 id
sex: 환자의 성별
age_approx: 환자의 나이 근사값
anatom_site_general_challenge: 신체의 해당 부위
diagnosis: 진단
benign_malignant: 악성,양성의 구분
target: 타겟값
train.columns = [
'img_name', 'id', 'sex', 'age', 'location', 'diagnosis', 'benign_malignant', 'target'
]
- 특징의 이름들을 다루기 쉽게 renaming해주는 작업입니다.
train.sample(5)
img_name | id | sex | age | location | diagnosis | benign_malignant | target | |
---|---|---|---|---|---|---|---|---|
2453 | ISIC_0832987 | IP_7792107 | male | 60.0 | torso | unknown | benign | 0 |
16386 | ISIC_5013346 | IP_3511266 | female | 15.0 | oral/genital | unknown | benign | 0 |
16243 | ISIC_4967586 | IP_7517320 | male | 60.0 | upper extremity | melanoma | malignant | 1 |
1371 | ISIC_0516183 | IP_4199752 | female | 30.0 | torso | unknown | benign | 0 |
2462 | ISIC_0835578 | IP_0139601 | female | 45.0 | lower extremity | unknown | benign | 0 |
- renaming한 결과가 잘 반영이 되었는지 .sample()를 사용하여 무작위 5개의 값으로 확인했습니다.
결측값/결측값(missing value) 찾기
train.isnull()
img_name | id | sex | age | location | diagnosis | benign_malignant | target | |
---|---|---|---|---|---|---|---|---|
0 | False | False | False | False | False | False | False | False |
1 | False | False | False | False | False | False | False | False |
2 | False | False | False | False | False | False | False | False |
3 | False | False | False | False | False | False | False | False |
4 | False | False | False | False | False | False | False | False |
... | ... | ... | ... | ... | ... | ... | ... | ... |
33121 | False | False | False | False | False | False | False | False |
33122 | False | False | False | False | False | False | False | False |
33123 | False | False | False | False | False | False | False | False |
33124 | False | False | False | False | False | False | False | False |
33125 | False | False | False | False | False | False | False | False |
33126 rows × 8 columns
- DataFrame의 .isnull() 함수를 사용합니다. 먼저, .isnull() 함수를 사용하면 위와 같이 항목별로 값의 여부를 True, False로 반환하여 보여줍니다.
train.isnull().sum()
img_name 0
id 0
sex 65
age 68
location 527
diagnosis 0
benign_malignant 0
target 0
dtype: int64
- .isnull() 함수에 합을 계산해 주는 .sum() 함수를 적용시키면 항목별로 결측값의 합이 나오게 됩니다.
train.isnull().sum().sort_values(ascending=False)
location 527
age 68
sex 65
target 0
benign_malignant 0
diagnosis 0
id 0
img_name 0
dtype: int64
- .sort_values() 함수를 사용합니다. ascending=False 옵션을 사용하여 값을 내림차순으로 정리합니다.
train.isnull().sum().sort_values(ascending=False)[train.isnull().sum().sort_values(ascending=False) != 0]
location 527
age 68
sex 65
dtype: int64
- 위의 내용들을 활용하여 0이 아닌 값들(결측치)만 가져옵니다.
total = train.isnull().sum().sort_values(ascending=False)[train.isnull().sum().sort_values(ascending=False) != 0]
percent = (train.isnull().sum().sort_values(ascending=False) / len(train) * 100) \
[(train.isnull().sum().sort_values(ascending=False) * 100) != 0]
pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
Total | Percent | |
---|---|---|
location | 527 | 1.590895 |
age | 68 | 0.205277 |
sex | 65 | 0.196220 |
missing_train = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
- 데이터 시각화를 위해 결측치 값들을 변수에 선언하여 가져오고, 결측 비율을 나타내기 위해서 데이터의 수로 나누어 퍼센트화 시켜줍니다.
- pandas의 .concat() 함수를 사용하여 가져온 변수 total과 percent를 합쳐줍니다.
결측치(missing value) 시각화 하기
fig, ax = plt.subplots(1, 2, figsize=(16,6))
- 데이터 시각화를 위해서 matplotlib 라이브러리를 활용하여 fig, ax 객체를 먼저 생성해줍니다.
fig, ax = plt.subplots(1, 2, figsize=(16,6))
sns.barplot(data=missing_train,
x=missing_train.index,
y='Percent',
ax=ax[0])
ax[0].set_title('Train Data Missing Values')
Text(0.5, 1.0, 'Train Data Missing Values')
- 생성된 객체위에 seaborn의 barplot를 사용하여 결측값들을 나타냈습니다.
- sns.barplot()의 형태로 barplot을 사용할 수 있으며 사용할 데이터, x축, y축, ax에 해당하는 옵션들을 적절한 값으로 배치해 줍니다.
- .set_title() 함수로 시각화된 데이터의 제목을 작성할 수 있습니다.
def missing_percentage(df):
total = df.isnull().sum().sort_values(\
ascending=False)[df.isnull().sum().sort_values(ascending=False) != 0]
percent = (df.isnull().sum().sort_values(ascending=False) / len(df) * \
100)[(df.isnull().sum().sort_values(ascending=False) / len(df) * \
100) != 0]
return pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
missing_train = missing_percentage(train)
missing_test = missing_percentage(test)
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
sns.barplot(x=missing_train.index,
y='Percent',
data=missing_train,
ax=ax[0])
sns.barplot(x=missing_test.index,
y='Percent',
data=missing_test,
ax=ax[1])
ax[0].set_title('Train Data Missing Values')
ax[1].set_title('Test Data Missing Values')
Text(0.5, 1.0, 'Test Data Missing Values')
- train, test 데이터셋의 결측치를 나타내기 위한 함수화된 코드입니다.
이상으로 탐색적 데이터 분석 과정 중 하나인 결측치(missing value)를 찾고 시각화 해보는 과정이었습니다. 주피터 노트북의 코드를 첨부했으며, 데이터의 용량이 너무 커 데이터는 따로 첨부하지 못한 점 양해부탁드립니다. 감사합니다.
도움이 되셨다면 아래 광고 한 번만 클릭해주세요 감사합니다!
'머신러닝 & 딥러닝 > 데이터 분석' 카테고리의 다른 글
데이터프레임 - 그룹화된 데이터 열(column) 가공하기(2) : 배열 형태의 데이터 각 column으로 정리하기 (0) | 2021.11.04 |
---|---|
데이터프레임 - 그룹화된 데이터 열(column) 가공하기(1) : .json_loads() && .from_dict() (0) | 2021.11.02 |
댓글