EDA(Exploratory Data Analysis)란?
EDA는 우리가 불러온 데이터를 전처리하고 분석을 하면서 그 안에서 유의미한 결과를 추출하는 과정을 말한다.
EDA만 잘 해도 우리가 힘들게 머신러닝이나 딥러닝을 돌리지 않아도 충분히 데이터 자체에서 유의미한 인사이트를 추출할 수 있다. 뿐만 아니라 데이터가 어떻게 생겼는지 EDA를 통해 파악함으로써, 모델을 어떻게 설계해야 할지, 전처리 전략은 어떻게 가져가야할 지 구상할 수 있다.
- EDA를 사용한 예시
- A와 B는 같은 데이터를 가지고 모델링을 해서 누가누가 더 좋은 성능을 내는지 내기를 했습니다.
- A는 EDA부터 차근차근 진행하였고, B는 EDA를 하지 않고 기본적인 전처리만 하고 모델에 넣었습니다.
- 그러나 성능은 A의 것이 훨씬 좋게 나왔습니다. 알고보니 Target Data에 몇몇 Noise가 껴있었고, A는 이를 EDA과정에서 발견하고 가공 후 모델링을 진행했던 것입니다.
- A는 그 과정에서 Target Data의 Imbalance도 발견했습니다. A는 이를 보고 loss에 weight를 다르게 주는 방법을 적용하여 B와 같은 모델을 사용했지만 모델이 데이터 불균형에 더 강건하게 학습하도록 만들었습니다.
1. EDA 기본
1-1 데이터 읽어오기
데이터 읽어오기에는 glob 모듈의 glob 함수가 있다.
# dir폴더의 모든 서브폴더 및 파일 목록
# dir : file1.txt, file2.txt, file101.txt, file102.txt, filea.txt, fileb.txt, file1.jpg, file2.jpg
# dir/subdir : subfile1.txt, subfile2.txt
import glob
# '*'는 임의 길이의 모든 문자열을 의미한다.
>>> output = glob.glob('dir/*.txt')
>>> print(output)
['dir\\file1.txt', 'dir\\file101.txt', 'dir\\file102.txt', 'dir\\file2.txt', 'dir\\filea.txt', 'dir\\fileb.txt']
# '?'는 한자리의 문자를 의미한다.
>>> output = glob.glob('dir/file?.*')
>>> print(output)
['dir\\file1.bmp', 'dir\\file1.txt', 'dir\\file2.bmp', 'dir\\file2.txt', 'dir\\filea.txt', 'dir\\fileb.txt']
# recursive=True로 설정하고 '**'를 사용하면 모든 하위 디렉토리까지 탐색한다.
# 기본값은 False이며, 파일이 너무 많을 경우에 사용하면 과도한 cost가 소모된다고 한다.
>>> output = glob.glob('dir/**', recursive=True)
>>> print(output)
['dir\\', 'dir\\file1.bmp', 'dir\\file1.txt', 'dir\\file101.txt', 'dir\\file102.txt', 'dir\\file2.bmp', 'dir\\file2.txt', 'dir\\filea.txt', 'dir\\fileb.txt', 'dir\\subdir', 'dir\\subdir\\subfile1.txt', 'dir\\subdir\\subfile2.txt']
여러 파일들 하나의 데이터 프레임으로 합치기
디렉터리에 들어있는 파일들의 리스트를 얻기 위한 코드는 다음과 같다.
import pandas as pd
from glob import glob
import warnings
warnings.filterwarnings('ignore')# 경고 메세지를 출력 안 하는 코드입니다.
base_dir = "" # 알집 풀어주신 곳 폴더를 넣으시면 됩니다.
file_lst = glob(base_dir + "*.csv")
파일명의 리스트를 구했다면 그 리스트들을 이용해서 csv파일을 데이터프레임으로 만들고 합칠 수 있다.
df = pd.DataFrame()
for i in file_lst:
data = pd.read_csv(i)
df = pd.concat([df,data])
df = df.reset_index(drop = True)#인덱스를 리셋
이중 특수한 행들 만을 구하고 싶다면 아래의 코드처럼 하면 된다. 카페만을 찾는 코드이다.
df_cafe = df[df['상권업종중분류명'] == '커피점/카페']
df_cafe
열의 정보들 중에서 특정 문자열이 포함된 행을 찾고 싶다면 str.contains() 를 활용하면 된다.
특정 문자열로 시작하는 행을 찾고싶다면 str.startswith()를 활용하면 된다.
아래의 예는 마포구에 있는 모든 스타벅스를 찾는 코드이다.
df_mp = df_cafe[df_cafe['시군구명'] == '마포구']
df_sb = df_mp[df_mp['상호명'].str.startswith('스타벅스') == True]
df_sb
pandas dataframe에서 출력 형식을 조절하는 코드는 아래와 같다.
pd.options.display.float_format = '{:.2%}'.format
matplotlib 에서 한글 폰트 깨질때 해결법은 아래의 코드를 사용하면 된다
from matplotlib import rc
rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
matplotlib에서 하나의 바만 따로 색칠하려면 Axes 객체의 patches 속성에서 set_color() 메서드를 사용하면된다. Axes 객체는 add_patch() 메서드를 통해서 다양한 요소를 추가할 수 있고, 이렇게 추가된 요소들은 patches 속성을 사용하여 접근할 수 있다.
ax.patches[0].set_color('red')
2. 마케팅 데이터 EDA 해보기
1) missingno
데이터셋을 살펴보면 여러 이유로 인하여 결측치 NaN값이 발생한다. 데이터를 분석하거나 혹은 EDA를 하는 경우에 데이터 전처리 작업을 해야한다. 이상치를 발견하고 처리하거나 결측치를 확인하고 처리하는 작업이 반드시 필요하다. 파이썬 판다스를 통해서 데이터를 처리하는 경우에 pd.info() , pd.isna().sum() 함수를 통해서 확인을 할 수도 있지만 시각화 라이브러리를 통해 더 간단하게 결측치를 확인할 수 있다. missingno는 결측데이터들을 파악하는데 직관적인 도움을 주는 패키지이다.
데이터 프레임의 컬럼값들의 유형을 알고싶으면 unique() 메서드를 활용하면 된다.
#train이라는 데이터 프레임에서 컬럼값들의 유형을 알아보는 코드
for i in range(10):
print(train[train.columns[i]].unique())
x축의 원소들의 디테일을 수정할 수 있다. fontsize로 글자 크기를, rotation으로 문자를 옆으로 뉘울 수 있다.
plt.xticks(fontsize = 7, rotation=40)
seaborn으로 그래프를 그릴때 그래프 크기를 변화시키는 코드이다.
sns.set(rc = {'figure.figsize':(15,8)})
그래프 간의 간격을 조절하는 코드이다.
plt.tight_layout()
2) heatmap
heatmap은 수치형 데이터만 있는 경우에는 정보를 처리하기 매우 쉽다. 하지만 수치형이 아니라
범주형(category) 데이터가 있는 경우에는 골치가 아파진다. 이럴때 두가지 방법으로 해결을 할 수 있다.
1. Mapping하는 방법
import seaborn as sns
import pandas as pd
# Load the Titanic dataset
titanic_df = pd.read_csv("train.csv")
# Map the 'Sex' column to numeric values
titanic_df['Sex'] = titanic_df['Sex'].map({'male': 0, 'female': 1})
# Map the 'Embarked' column to numeric values
titanic_df['Embarked'] = titanic_df['Embarked'].map({'S': 0, 'C': 1, 'Q': 2})
# Create a heatmap
sns.heatmap(titanic_df.corr(), annot=True, cmap='coolwarm')
seaborn heatmap에서 범주형 데이터에 수치를 할당하기 위해서는 범주형 데이터를 숫자로 매핑(mapping)해야 합니다.
예를 들어, Sex
열과 Embarked
열이 있는 경우, Sex
열의 범주를 male
은 0, female
은 1로 매핑하고, Embarked
열의 범주를 S
는 0, C
는 1, Q
는 2로 매핑하는 방법은 다음과 같습니다.
2. astype을 활용하는 방법
import seaborn as sns
import pandas as pd
titanic = sns.load_dataset('titanic')
titanic['gender_code'] = titanic['sex'].astype('category').cat.codes
sns.heatmap(titanic.corr(), annot=True, cmap='coolwarm')
Seaborn heatmap에서는 범주형 데이터를 수치 데이터로 자동 변환하는 기능은 제공하지 않습니다. 그러나 pandas의 astype()
메서드를 사용하여 범주형 열을 수치형 열로 변환한 다음 heatmap을 그리는 것이 가능합니다. 위 코드에서 titanic['gender_code']
라는 새로운 열을 추가하여 titanic['sex']
열의 범주형 값을 0 또는 1로 변환했습니다. 그리고 gender_code
열을 heatmap에 적용할 수 있습니다.
heatmap의 중요한 parameter
Seaborn heatmap에서 annot
매개변수를 True
로 설정하면 각 셀에 해당하는 상관계수 값을 표시할 수 있습니다. 이 값을 통해 두 변수 간의 상관관계의 정도를 직접 확인할 수 있습니다.
또한 Seaborn heatmap에서 mask
매개변수를 사용하여 특정 데이터 값을 무시하거나 표시할 수 있습니다. 예를 들어, 특정 상관관계가 특별히 중요하지 않거나 불필요한 경우 해당 값의 셀을 표시하지 않도록 할 수 있습니다.
heatmap으로 상관관계 알아보기
Seaborn heatmap에서 상관관계는 색상으로 표시됩니다. 일반적으로 높은 상관관계를 가진 쌍은 비슷한 색상을 가지며, 낮은 상관관계를 가진 쌍은 서로 다른 색상을 가집니다.
상관관계는 주어진 데이터에 대한 통계적 관계를 나타내며, -1에서 1까지의 값을 가집니다. 양의 상관관계는 값이 증가하면 함께 증가하는 변수들을 의미하며, 음의 상관관계는 값이 증가하면 함께 감소하는 변수들을 의미합니다.
상관계수는 변수들 간의 관계를 알아볼 때 유용한 개념입니다. 특정 데이터에 대한 상관관계를 볼 수 있습니다. 상관계수는 -1부터 1사이로 구성되고, 0.3부터 0.7 사이면 뚜렷한 양적 선형관계, 0.7 이상이면 강한 양적 상관관계라 할 수 있습니다.
'인공지능 > 인공지능 기초 개념' 카테고리의 다른 글
(3)-2 EDA 실습 (1) | 2024.03.15 |
---|---|
(4) EDA 필사 (0) | 2024.03.15 |
(2) 데이터 시각화 (1) | 2024.03.14 |
(1) Pandas란? (0) | 2024.03.14 |
(1) Machine Learning (0) | 2024.03.14 |