본문 바로가기

Machine Learning_모델설계_Python

데이터 전처리_2

안녕하세요 배도리입니다. 데이터 전처리 이어서 설명하겠습니다.

 

2. 데이터 전처리 방법

 데이터 실수화(Data Vectorization) ▪ 범주형 자료, 텍스트 자료, 이미지 자료 등을 실수로 구성된 형태로 전환하는 것

---------------------------------여기까지 설명드렸고 이어서 아래의 방법들을 설명하겠습니다!

 

② 데이터 정제(Data Cleaning) ▪ 없는 데이터는 채우고, 잡음 데이터 제거하고, 모순 데이터를 올바른 데이터로 교정하는 것

 

 데이터 통합(Data Integration) ▪ 여러 개의 데이터 파일을 하나로 합치는 과정

 

 데이터 변환 (Data Transformation) ▪ 데이터를 정규화 하거나, 로그를 씌우거나, 평균값을 계산하여 사용하거나, 사람 나이 등을 10대, 20대, 30대 등으로 구간화 하는 작업

 

 데이터 균형 (Data Balancing) ▪ 특정 클래스의 관측치가 다른 클래스에 비해 매우 낮을 경우 샘플링을 통해 클래스 비율을 맞추는 작업

 

 

 데이터 정제(Data Cleaning) 

▪ 데이터 정제시 결측 데이터를 채워야 합니다. (Empty Values)

▪ 결측 데이터: NumPy에서 np.nan, np.NaN, None은 모두 결측치를 의미합니다.

▪ 결측 값을 채우는 방법은 평균값(mean), 중앙값(median), 최빈값(mode), 특정값으로 대체합니다.

import numpy as np
# 결측자료
x_miss=np.array([[1,2,3,np.nan],
                 [5,np.NaN,7,8],
                 [np.nan,10,11,12],
                 [1,2,15,16],
                 [13,4,15,16]])
x_miss
 
array(
[[ 1., 2., 3., nan], #nan결측값 발견!
[ 5., nan, 7., 8.],#nan결측값 발견!
[nan, 10., 11., 12.],#nan결측값 발견!
[ 1., 2., 15., 16.],
[13., 4., 15., 16.]])

 

▪ Scikit-Learn의 SimpleImputer - 입력인자(strategy)값 설정하여 특정값으로 대채하겠습니다.

from sklearn.impute import SimpleImputer
im = SimpleImputer(strategy='mean')
im.fit_transform(x_miss) #열의 평균값으로 대체
array(
[[ 1. , 2. , 3. , 13. ],
[ 5. , 4.5, 7. , 8. ],
[ 5. , 10. , 11. , 12. ],
[ 1. , 2. , 15. , 16. ],
[13. , 4. , 15. , 16. ]])
 
im = SimpleImputer(strategy='median')
im.fit_transform(x_miss) #열의 중앙값으로 대체
array(
[[ 1., 2., 3., 14.],
[ 5., 3., 7., 8.],
[ 3., 10., 11., 12.],
[ 1., 2., 15., 16.],
[13., 4., 15., 16.]])
 
im = SimpleImputer(strategy='most_frequent')
im.fit_transform(x_miss) #열의 최빈값으로 대체
array(
[[ 1., 2., 3., 16.],
[ 5., 2., 7., 8.],
[ 1., 10., 11., 12.],
[ 1., 2., 15., 16.],
[13., 4., 15., 16.]])
 
m = SimpleImputer(strategy='constant')
im.fit_transform(x_miss) #0으로 대체
array(
[[ 1., 2., 3., 0.],
[ 5., 0., 7., 8.],
[ 0., 10., 11., 12.],
[ 1., 2., 15., 16.],
[13., 4., 15., 16.]])
 
im = SimpleImputer(strategy='constant', fill_value=1)
im.fit_transform(x_miss) #1로 대체
array(
[[ 1., 2., 3., 1.],
[ 5., 1., 7., 8.],
[ 1., 10., 11., 12.],
[ 1., 2., 15., 16.],
[13., 4., 15., 16.]])
 

 

아 그리고 이전 게시글에 설명을 드리지 못해드려 설명드립니다.

im = SimpleImputer  여기서 im은 SimpleImputer 클래스의 인스턴스입니다 인스턴스화된 im 객체는 SimpleImputer 클래스의 기능을 활용할 수 있습니다. 

im.fit_transform(x_miss)   fit_transform() 메서드를 호출하여 x_miss 데이터에 대해 결측값을 처리하고 대체된 값을 반환할 수 있습니다.  fit() 메서드와 transform() 메서드를 결합한 것으로, 학습과 변환을 한 번에 수행합니다. 즉, x_miss 데이터를 im 객체를 사용하여 학습하고, 결측값을 대체한 후 변환된 데이터를 반환한다. 라고 생각하시면 될것 같습니다.

 

 

 데이터 통합(Data Integration) 

▪ 여러 개의 데이터 파일을 하나로 합치는 과정으로 Pandas의 merge() 함수 사용합니다.

연습을 위해 예제를 통해 보여드리겠습니다. https://www.kaggle.com/c/rossmann-store-sales/data 데이터는 여기서 다운 받으시면됩니다.

Data에 들어가셔서 스크롤 내리셔서 Download All을 클릭!

 

 

다운받았다면 데이터들을 파이썬에서 판다스를 통해 살펴보겠습니다.

train데이터 입니다.

import pandas as pd
df1=pd.read_csv("train.csv",engine='python')
print(df1.shape)
type(df1)
 
(1017209, 9)  #행은 1017209개, 열은 9개 확인
pandas.core.frame.DataFrame

 

df1.head() #상위 5개행 확인 

 

 

store데이터 입니다.

df2=pd.read_csv("store.csv",engine='python')
df2.shape
 
(1115, 10)

 

df2.head()

 

둘다 1열에 store가 있네요 합쳐보고 싶어졌습니다.

df=pd.merge(df1,df2,on='Store')
df.shape
 
(1017209, 18)

 

통합된 df에서 변수의 자료 유형을 확인하겠습니다.

df.dtypes

 

이후 'Store'과 Date'열의 고유한 값들의 개수를 출력합니다

print(len(df['Store'].unique()))
#'Store' 열의 고유한 값들의 개수를 출력합니다. 이는 데이터프레임에 있는 다른 매장 수를 나타냅니다.
print(len(df['Date'].unique()))
#Date' 열의 고유한 값들의 개수를 출력합니다. 이는 데이터프레임에 포함된 고유한 날짜 수를 나타냅니다.
 
1115
942

len() 함수는 시퀀스(리스트, 튜플, 문자열 등)의 길이를 반환합니다. 이를통해 고유한 값의 개수를 확인할수 있습니다. 예를 들어, .df['Store']열에는 [1, 2, 3, 1, 2, 3, 4]와 같은 값들이 있다고 가정해봅시다. df['Store'].unique()를 호출하면 [1, 2, 3, 4]와 같은 고유한 값들을 얻게 됩니다. 그리고 len(df['Store'].unique())를 호출하면 4라는 결과를 얻게 됩니다.

 

 

이번에는 'DayOfWook'를 확인해보겠습니다.

print(df['DayOfWeek'].value_counts())
 
5 145845
4 145845
3 145665
2 145664
1 144730
7 144730
6 144730
Name: DayOfWeek, dtype: int64

'DayOfWeek' 열의 각 값들의 빈도를 출력합니다. 이는 데이터프레임에 포함된 각 요일별 레코드 개수를 나타냅니다. value_counts()함수는 Pandas 시리즈에서 각 값의 발생 빈도를 계산합니다. 이 함수는 주로 범주형 데이터나 이산형 데이터의 분포를 파악할 때 사용됩니다.value_counts() 함수를 호출하면, 해 시리즈의 고유한 값과 해당 값이 시리즈에서 발생하는 횟수를 반환합니다. 결과는 내림차순으로 정렬되어 반환되기 때문에, 가장 빈번하게 등장하는 값부터 확인할 수 있습니다.

 

 

df 'Date' 열에서 여러 파생 변수를 생성하여 통합하고 싶어졌습니다. 

import numpy as np
df['Date']=pd.to_datetime(df['Date'],infer_datetime_format=True)
#열의 데이터를 datetime 객체로 변환합니다. datetime 객체는 날짜를 년도, 월, 일 등으로 분류할 때 사용됩니다. infer_datetime_format 매개변수를 True로 설정하여 날짜 형식을 자동으로 추론하게 합니다. 이렇게 한다면 날짜변수 분류작업 속도 높입니다.
 
df['Month']=df['Date'].dt.month #변환된 'Date' 열에서 월 정보를 추출하여 새로운 'Month' 열을 생성합니다.
df['Quarter']=df['Date'].dt.quarter #'Date' 열에서 분기 정보를 추출하여 새로운 'Quarter' 열을 생성합니다.
df['Year']=df['Date'].dt.year #'Date' 열에서 연도 정보를 추출하여 새로운 'Year' 열을 생성합니다.
df['Day']=df['Date'].dt.day #Date' 열에서 일 정보를 추출하여 새로운 'Day' 열을 생성합니다.
df['Week']=df['Date'].dt.isocalendar().week #Date' 열에서 ISO 주차 정보를 추출하여 새로운 'Week' 열을 생성합니다.
df['Season']=np.where(df['Month'].isin([3,4,5]),'Spring',
                     np.where(df['Month'].isin([6,7,8]),'Summer',
                             np.where(df['Month'].isin([9,10,11]),'fall',
                                     np.where(df['Month'].isin([12,1,2]),'winter','None'))))
#월별로 계절 정보를 할당하여 새로운 'Season' 열을 생성합니다. 월 정보를 사용하여 각 월에 해당하는 계절을 할당합니다.
#3월부터 5월은 봄(Spring), 6월부터 8월은 여름(Summer), 9월부터 11월은 가을(Fall), 12월부터 2월은 겨울(Winter)입니다.
#마지막에 'None'이 사용된 이유는, 위의 모든 조건에 해당하지 않는 경우를 처리하기 위함입니다.
print(df[['Date','Year','Month','Day','Week','Quarter','Season']].head())

 

 

통합이후 시각 자료도 있으면 좋을것 같습니다. 다음은 df의 각 수치형 열에 대한 히스토그램을 생성하고 출력합니다. 히스토그램은 변수의 값 분포를 시각적으로 표현하는 도구로, 값 범위를 일정한 구간으로 나눈 뒤, 각 구간에 속하는 데이터의 개수를 막대로 표현합니다. 이를 통해 각 변수의 분포와 데이터의 형태를 쉽게 확인할 수 있습니다.

df.hist(figsize=(20,20))
figsize=(20, 20)는 생성되는 그래프의 크기를 설정합니다. 여기서 20은 가로 길이, 20은 세로 길이를 나타냅니다. 이 값은 인치 단위로 설정됩니다.

 

만들기는 했지만 처음에 저도 그래서 뭐? 라는 심정이 들긴 했습니다. 그래서 여기서 어떤것을 가볍게 확인 할 수 있는지 설명드리겠습니다.

예를들어 빨간 박스는 목적변수 Sales가 20,000 이하가 대부분임을 확인할수 있고 보라색 박스는 0 또는 1의 값만 갖는 이항변수임을 확인 할 수 있습니다.

 

 

추가적으로 자료의 결측 정도를 확인할수 있습니다.

▪ 10% 이하: 결측치 대체 노력이 필요합니다.

▪ 30% 이상: 해당변수를 제거하는 것이 모형의 bias(편향)를 피할 수 있습니다.

코드로 데이터프레임 df에서 각 열별 결측값의 비율을 계산하여 반환하겠습니다.

df.isnull().sum()/df.shape[0]*100
 
#df.isnull(): 데이터프레임 df의 각 값이 결측값인지 아닌지를 판별하고, 결과를 True(결측값) 또는 False(결측값이 아닌 값)로 반환합니다.
#df.isnull().sum(): 각 열의 결측값 수를 계산합니다. True는 1, False는 0으로 취급되므로, 이를 합산하면 결측값의 개수를 얻을 수 있습니다.
#df.shape[0]: 데이터프레임의 행 개수를 반환합니다. (행,열)구조기 때문이라 0은 행 1은 열
#df.isnull().sum() / df.shape[0]: 각 열의 결측값 수를 전체 행 개수로 나누어 결측값의 비율을 계산합니다.
#결측값 비율을 퍼센트로 변환하기 위해 100을 곱합니다.
#결과적으로, 이 코드는 각 열별 결측값의 비율을 퍼센트로 나타내는 Pandas 시리즈를 반환합니다.
 

CompetitionOpenSinceMonth 31.787764

CompetitionOpenSinceYear 31.787764

Promo2SinceWeek 49.943620

Promo2SinceYear 49.943620

PromoInterval 49.943620 

이 친구들은 결측치가 30%이상이니 안타깝지만 모형의 bias를 피하기 위해 제.거. 해야겠습니다.

 

다음에는 데이터 전처리 방법 중 변환과 균형으로 돌아오겠습니다.

'Machine Learning_모델설계_Python' 카테고리의 다른 글

기계학습(Machine Learning) 방법론  (2) 2023.05.08
데이터 전처리_3  (0) 2023.05.07
데이터 전처리_1  (3) 2023.05.04
Pandas_3 그룹별 집계  (2) 2023.05.03
Pandas_2 데이터 추출  (1) 2023.05.02