[머신러닝] 데이터분석 프로세스

yeji·2024년 11월 20일

Python

목록 보기
22/36

데이터 수집

  • 회사 내 데이터가 존재한다면 SQL 혹은 Python 을 통해 데이터 마트를 생성
  • 회사 내 Data가 없다면 CSV, EXCEL 파일 다운로드 or API를 이용한 데이터 수집 or Data Crawling

탐색적 데이터 분석(EDA)

  • 데이터의 시각화, 기술통계 등의 방법을 통해 데이터를 이해하고 탐구하는 과정
  • 데이터에 대한 정보를 얻을 수도 있고, 적절한 모델링에 대한 정보도 얻을 수 있음

기술통계

  • tips.describe(), include='all' 옵션을 통해 범주형 데이터도 확인 가능
# 라이브러리
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd 

# 데이터프레임 가져오기
tips_df = sns.load_dataset('tips')

# 데이터 확인
tips_df.describe(include = 'all')

시각화

  • countplot : 범주형 데이터의 각 카테고리별 빈도수
    -x축 : 범주형, y축 : 빈도수
# countplot: x축 범주형, y축 관측치
sns.countplot(data = tips_df, x = 'day')
  • barplot : 범주형 데이터의 . 각카테고리에 따른 수치 데이터 평균 비교
    -x축 : 범주형, y축 : 연속형
# barplot: X축이 범주형, Y축이 연속형 값
sns.barplot(data = tips_df, x = 'sex', y = 'tip', estimator = 'mean')
  • boxplot : 데이터의 분포, 중앙값, 사분위 수, 이상치 등을 한눈에 표현
    -x축 : 수치형&범주형, y축 : 수치형
sns.boxplot(data = tips_df, x = 'time',y = 'total_bill')
  • histogram : 연속형 분포를 나타내고 싶을 때 데이터가 몰려있는 구간을 파악하기 쉬움
    -x축 : 수치형, y축 : 빈도수
sns.histplot(data = tips_df, x = 'total_bill')

# 동일한 그래프 표현
tips_df['total_bill'].hist()
tips_df['total_bill'].plot.hist()
  • scatterplot : 두 연속형 변수간의 관계를 시각적으로 파악
    -x축 : 수치형, y축 : 수치형
sns.scatterplot(data = tips_df, x = 'total_bill', y = 'tip')
  • pairplot : 한 번에 여러 개의 변수를 동시에 시각화하고 싶을 때
    -x축 : 범주형&수치형, y축 : 범주형&수치형
sns.pairplot(data = tips_df)

데이터 전처리

이상치

  • 관측된 데이터 범위에서 많이 벗어난 아주 작은 값 혹은 큰 값
  • 도메인과 비즈니스 맥락에 따라 기준이 달라지며, 데이터 삭제 시 품질은 좋아질 . 수있지만 정보 손실을 동반하기에 주의해야 함
  • ESD(Extreme Studentized Deviation) : 데이터가 정규분포를 따른다고 가정할 때 평균에서 표준편차의 3배 이상 떨어진 값
    -데이터가 크게 비대칭이거나 샘플 크기가 작을 경우 제한됨
# 라이브러리
import numpy as np

# 평균, 표준편차 확인
mean = np.mean(tips_df['total_bill'])
std = np.std(tips_df['total_bill'])

# 기준 설정
upper_limit = mean + 3*std
lower_limit = mean - 3*std

# 이상치 따로 담기
cond = (tips_df['total_bill'] > upper_limit)
  • IQR(Inter Quantile Range) : box plot 활용
    -데이터가 크게 비대칭이거나 샘플 크기가 작을 경우 제한됨
# 라이브러리
import seaborn as sns

# box plot 확인
sns.boxplot(tips_df['total_bill'])

# 기준 설정
q1 = tips_df['total_bill'].quantile(0.25)
q3 = tips_df['total_bill'].quantile(0.75)
iqr = q3 - q1 
upper_limit2 = q3 + 1.5*iqr
lower_limit2 = q1 - 1.5*iqr

# 이상치 따로 담기
cond2 = (tips_df['total_bill'] > upper_limit2)

결측치

  • 존재하지 않는 데이터
  • 수치형 데이터 : 평균값 대치(대표적), 중앙값 대치(이상치가 많아 평균값이 대표성이 없을 때)
  • 범주형 데이터 : 최빈값 대치
  • 사용 함수
    -df.dropna(axis = 0) : 행 삭제
    -df.dropna(axis = 1) : 열 삭제
    -Boolean Indexing
    -df.fillna(value) : 특정 값으로 대치(평균, 중앙, 최빈값)
# 라이브러리
import pandas as  pd

# 데이터 불러오기
titaninc_df = pd.read_csv('C:/Users/user/Documents/ML/titanic/train.csv')

# 결측치 확인
titaninc_df.info()

# 행 삭제
titaninc_df.dropna(axis = 0)

# 열 삭제 후 새로운 컬럼에 담기
cond3 = (titaninc_df['Age'].notna())
titaninc_df[cond3].info()

# fillna 이용한 대치
age_mean = titaninc_df['Age'].mean().round(2)
titaninc_df['Age_mean'] = titaninc_df['Age'].fillna(age_mean)

# 알고리즘 SimpleImputer를 이용한 대치
from sklearn.impute import SimpleImputer
si = SimpleImputer()
si.fit(titaninc_df[['Age']])
titaninc_df['Age_si_mean'] = si.transform(titaninc_df[['Age']])

범주형 데이터 인코딩

  • 인코딩 : 어떤 정보를 정해진 규칙에 따라 변환하는 것
  • 레이블 인코딩(Label Encoding) : 문자열 범주형 값을 고유한 숫자로 할당
    • 실제로는 그렇지 않은데 순서 간 크기에 의미가 부여되어 모델이 잘못 해석 할 수 있음
    • 사용 함수 : sklearn.preprocessing.LabelEncoder
    • 메소드
      • fit : 데이터 학습
      • transform : 정수형 데이터로 변환
      • fit_transform : fit과 transform을 연결하여 한번에 실행
      • inverse_transform : 인코딩된 데이터를 원래 문자열로 변환
    • 속성
      • classes_ : 인코더가 학습한 클래스(범주)
# 라이브러리
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()

# 학습
le.fit(titaninc_df[['Sex']])

# 변환 후 컬럼 추가
titaninc_df['Sex_le'] = le.transform(titaninc_df[['Sex']])
  • 원-핫 인코딩(One-Hot Encoding) : 각 범주를 이진 형식으로 변환하는 기법
    • 범주 개수가 많을 경우 차원이 크게 증가(차원의 저주)
    • 사용 함수 : pd.get_dummies, sklearn.preprocessing.OneHotEncoder
      • 메소드(LabelEncoder와 동일)
      • categories_ : 인코더가 학습한 클래스(범주)
      • get_feature_names_out() : 학습한 클래스 이름(리스트)
# 라이브러리
from sklearn.preprocessing import OneHotEncoder
oe = OneHotEncoder()

# 학습
oe.fit(titaninc_df[['Embarked']])

# 변환 후 데이터 프레임으로 제작
embarked_csr = oe.transform(titaninc_df[['Embarked']])
embarked_csr_df = pd.DataFrame(embarked_csr.toarray(), columns = oe.get_feature_names_out())

# 기존 데이터프레임에 병합(concat)
pd.concat([titaninc_df, embarked_csr_df],axis = 1)

수치형 데이터 스케일링

  • 스케일링 : 수치형 자료에 대한 전처리
  • 서로 단위 값이 다르기 때문에 이를 보정함
  • 표준화(Standardization) : 각 데이터에 평균을 빼고 표준편차를 나누어 평균을 0 표준편차를 1로 조정하는 방법
    • 이상치가 있거나 분포가 치우쳐져 있을 때 유용
    • 데이터의 최소, 최대값이 정해지지 않음
    • 함수 : sklearn.preprocessing.StandardScaler
    • 메소드
      • fit : 데이터학습(평균과 표준편차를 계산)
      • transform : 데이터 스케일링 진행
    • 속성
      • mean_ : 데이터의 평균 값
      • scale_, var_ : 데이터의 표준 편차,분산 값
      • n_features_in_ : fit 할 때 들어간 변수 개수
      • feature_names_in_ : fit 할 때 들어간 변수 이름
      • n_samples_seen_ : fit 할 때 들어간 데이터의 개수
# 라이브러리
from sklearn.preprocessing import StandardScaler
sd_sc = StandardScaler()

# 학습 후 컬럼 담기
titaninc_df['Age_mean_mm_sc'] = mm_sc.fit_transform(titaninc_df[['Age_mean']])

# 결과 시각화
sns.histplot(titaninc_df['Fare_sd_sc'])
  • 정규화(Normalization) : 데이터를 0과 1사이 값으로 조정
    • 모든 특성의 스케일을 동일하게 맞추고 최대, 최소 범위가 명확함
    • 이상치에 영향을 많이 받을 수 있음
    • 함수 : sklearn.preprocessing.MinMaxScaler
    • 속성
      • data_min_ : 원 데이터의 최소 값
      • data_max_ : 원 데이터의 최대 값
      • data_range_ : 원 데이터의 최대-최소 범위
# 라이브러리
from sklearn.preprocessing import MinMaxScaler
mm_sc = MinMaxScaler()

# 학습 후 컬럼 담기
titaninc_df['Fare_sd_sc'] = sd_sc.fit_transform(titaninc_df[['Fare']])

# 결과 시각화
sns.histplot(titaninc_df['Age_mean_mm_sc'], bins = 100)
  • 로버스트 스케일링(Robust Scaling) : 중앙값과 IQR을 사용
    • 이상치의 영향에 덜 민감하지만 표준화와 정규화에 비해 덜 사용됨
    • 함수 : sklearn.preprocessing.RobustScaler
      • 속성 : center_ 훈련 데이터의 중앙값

데이터 분리

과(대)적합(Overfitting)

  • 데이터를 너무 과도하게 학습해 학습한 문제만 . 잘맞추고 새로운 데이터를 제대로 예측 혹은 분류하지 못하는 현상
  • 원인 : 모델의 복잡도, 충분하지 않은 데이터 양, 학습 반복이 많은 경우, 데이터 불균형이 심한 경우

테스트 데이터 분리

  • 학습 테이터(Train Data) : 모델을 학습(fit)하기 위한 테이터
  • 테스트 데이터(Test Data) : 모델을 평가하기 위한 데이터
  • 함수 : sklearn.model_selection.train_test_split
    • 파라미터
      • test_size : 테스트 데이터 세트 크기
      • train_size : 학습 데이터 세트 크기
      • shuffle : 데이터 분리 시 섞기
      • random_state : 호출할 때마다 동일한 학습/테스트 데이터를 생성하기 위한 난수 값, 수행할 때 마다 동일한 데이터 세트로 분리하기 위해 숫자를 고정 시켜야 함
    • 반환 값(순서 중요)
      • X_train, X_test, y_train, y_test
# 라이브러리
from sklearn.model_selection import train_test_split

# 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(titaninc_df[['Fare','Sex']], titaninc_df[['Survived']],
                                                    test_size = 0.3, shuffle= True, random_state= 42,stratify=titaninc_df[['Survived']])

교차검증과 GridSearch

교차검증(Cross Validation)

  • 데이터 셋을 여러 개의 하위 집합으로 나누어 돌아가면서 검증하는 방법
  • K-Fold Validation : Train Data를 K개의 하위 집합으로 나누어 모델을 학습시키고 모델을 최적화 하는 방법
  • 함수
    • skelarn.model_selection.KFold
    • sklearn.model_selection.StrifiedKFold : 불균형한 레이블(Y)를 가지고 있을 때 사용

GridSearch

  • 하이퍼 파라미터를 자동화 해주는 것
  • 하이퍼 파라미터 : 모델을 구성하는 입력 값 중 사람이 임의적으로 바꿀 수 있는 입력 값
from sklearn.model_selection import GridSearchCV

params = {'solver' : ['newton-cg','lbfgs','liblinear','sag','saga'],
          'max_iter' : [100,200]}
grid_lor = GridSearchCV(model_lor2, param_grid = params, scoring='accuracy', cv = 5)
grid_lor.fit(X_train, y_train)

print('최고의 하이퍼 파라미터',grid_lor.best_params_)
print('최고의 정확도', grid_lor.best_score_.round(3))

전체 프로세스 예시

  1. 데이터 로드 & 분리
    • train / test 데이터 분리
  2. 탐색적 데이터 분석(EDA)
    • 분포확인 & 이상치 확인
  3. 데이터 전처리
    • 결측치 처리
      • 수치형 : Age
      • 범주형 : Embarked
      • 삭제 : Cabin, Name
    • 전처리
      • 수치형 : Age, Fare, Sibsp+Parch
      • 범주형
        • 레이블 인코딩 : Pclass, Sex
        • 원- 핫 인코딩 : Embarked
  4. 모델 수립
  5. 평가
profile
👋🏻

0개의 댓글