코드스테이츠 AI 부트캠프/Section 1

AIB_112_복습정리 : Feature Engineering

yourhm 2021. 9. 15. 22:44

Feature Engineering (특성 공학)

도메인 지식과 창의성을 바탕으로 데이터셋에 존재하는 feature들을 재조합하여 특정 어플리케이션에 가장 적합한 feature를 찾아내는 것. 구간을 분할하거나 통합할 수도 있고, 스케일을 조정할 수도 있고, 여러 특성을 조합하거나 연산을 적용해서 새로운 특성을 만들 수도 있다. 예를 들어 데이터셋에 '몸무게'와 '키' 라는 특성이 있는데, 이 두개의 특성을 재조합하여 새로운 특성으로 'BMI지수' 를 만드는 것은 feature engineering이라고 할 수 있다.

 

 

DataFrame (데이터 프레임)

Pandas의 DataFrame은 그냥 테이블 형태의 데이터다 정도로만 이해하기 (지금 내 수준에선,,)

 

• Row(행)에는 observation data

• Column(열)에는 feature 

 

 

💡파이썬에서 결측치를 나타나는 다른 표현들의 차이 알아보기

 

Na 아직 정해지지 않은 값
NaN 아직 정해지지 않은 값
Null 아직 정해지지 않은 값
None 비어있는 값, 비존재
0 정수 0

 

- NaN : 파이썬 > 판다스에서는 결측치를 NaN(Not a Number)으로 표현하고, NaN은 프로그래밍상 float(실수)라는 type을 갖는다. 따라서 어떤 피쳐에 NaN이 하나라도 존재한다면, 해당 피쳐에 int(정수)가 존재하더라도 해당 피처의 타입은 어쩔 수 없이  float(실수)로 type cast된다.

 

 

[참고자료]

데이터 프레임 이해하기

https://digital-play.tistory.com/32

 

 


파이썬 코딩 연습하기💬

 

🔽 데이터 타입 확인하기

# to get Data types of columns in Dataframe
Dataframe.dtypes

# to get Data types of Dataframe columns as dictionary
dict(Dataframe.dtypes)

# to get the Data type of a single column in Dataframe
Dataframe.dtypes['컬럼이름']

# to check if Data type of a column is object i.e. string in Dataframe
if Dataframe.dtypes['컬럼이름'] == np.object:
    print("Data type of column '컬럼이름' is object")
    
# to get list of pandas dataframe column names based on data type
filtered_Columns = Dataframe.dtypes[Dataframe.dtypes == np.object]
list(filtered_Columns.index)

 

 

🔽 object / Not object(숫자형) 데이터 타입을 구분해서 호출해주는 함수: select_dtypes()

# 컬럼의 데이터 타입이 object인 데이터만 호출하기
dataframe.select_dtypes(include = object)

# 컬럼의 데이터 타입이 object가 아닌 데이터만 호출하기
dataframe.select_dtypes(exclude = object)

# 컬럼의 데이터 터입이 object인 데이터의 columns 출력하기
dataframe.select_dtypes(include = object).columns

 

[참고] 학습에 참고한 블로그

https://growthj.link/python-select_dtypes-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0object%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A7%8C-%ED%98%B8%EC%B6%9C%ED%95%98%EA%B8%B0/

 

 

🔽 csv 데이터셋 불러오면서 특정 값으로 헤더 지정하기: names = ['a', 'b', 'c', ... ]

data_url= 'https://~~~.csv'
headers = ['쿼터', '매출액', '영업이익']

import pandas as pd
df = pd.read_csv(data_url, names=headers) # names을 통해 사용할 column name(=header)목록을 지정할 수 있음.
df

 

 

🔽 영업이익률 계산하여 새로운 특성 생성하기. (Feature Engneering 진행)

 

STEP 1. 전체 데이터셋 column type 출력하여 해당 컬럼이 계산 가능한지 먼저 확인한다.

df.dtypes

 

STEP 2. 데이터 타입이 숫자가 아닌 문자열인 경우, 계산이 가능하도록 숫자로 형변환 처리를 해준다.

# 콤마 제거한뒤 integer로 변환하는 함수 정의
def toint(string):
  return int(string.replace(',',''))

# 해당 column 전체 값에 적용되도록 apply 사용하여 계산
# 영업이익률 = (영업이익/매출액)*100

df['영업이익률계산'] = (df['영업이익'].apply(toint)/df['매출액'].apply(toint))*100
df['영업이익률계산']

 

🔽 데이터프레임 직접 새로 생성하기

  연도 상품번호 상품금액 판매개수 판매총액
0 2019년 101 100,000 1520 152000000
1 2019년 102 50,000 1900 95000000

 

방법(1)

d2 = {'연도':['2019년','2019년'], '상품번호':[101,201], '상품금액':['100,000','50,000'], '판매개수':[1520,1900], '판매총액':[152000000,95000000]}
df2 = pd.DataFrame(data=d2)

 

방법(2)

col = ['연도', '상품번호', '상품금액', '판매개수', '판매총액']
d2 = [['2019년',101, '100,000', 1520, 152000000], ['2019년', 102, '50,000', 1900, 95000000]]
df2 = pd.DataFrame(data=d2, columns=col)

-  pd.DataFrame ---> D와 F 는 반드시 대문자로 표기해야함을 주의하자.

 

 

🔽 콤마가 포함된 숫자가 문자열 타입으로 표현되어 있을 때, 타입을 숫자로 변환해주는 방법

2 5 , 9 7 0

 

방법(1) replace를 사용해서 숫자가 아닌 부분(=콤마) 을 먼저 제거한 후, 문자열을 숫자로 형변환

# replace 사용방법
string_variable.replace("삭제할 글자", "대체할 글자")
teststring = '25,970' 

# STEP 1. replace사용하여 콤마를 공백으로 대체하여 제거하는 방식
teststring=teststring.replace(',', '')

# STEP 2. 정수로 형변환
int(teststring)

 

 

방법(2) 위의 단계를 함수로 작성해서 단계 축소

# 입력된 문자열에 대해 step 1(replace) & step 2(int) 한번에 처리해주는 함수 작성

def toint(string):
	return int(string.replace(',',''))
type(toint('25,970'))

OUTPUT:

int

 

 

🔽 함수를 특정 컬럼 전체에 한번에 적용하기: DataFrame.apply 

특정 컬럼에 모든 숫자가 저렇게 문자열 타입으로 되어 있는데 그 데이터의 갯수가 1000개 이상이라고 해보자. 위의 예시처럼 모든 문자열에 대해서 toint 함수를 1000번 이상 반복하여 형변환을 해줄 수 있지만 그건 너무 비효율적이다. 이런 경우 컬럼 단위로 한번에 toint 함수를 적용하려면 apply() 메서드를 사용하면 된다.

 

STEP 1. apply안에 적용할 함수를 미리 정의.

STEP 2. column에 apply 적용.

 

# SETP 1.
def toint(string):
	return int(string.replace(',',''))
    
# STEP 2. 
dataframe['컬럼이름'] = dataframe['컬럼이름'].apply(toint)

 

적용할 함수가 길지 않다면, 함수를 굳이 미리 정의할 필요없이 lambda(람다)와 함께 사용하면 된다.

dataframe['컬럼이름'] = dataframe['컬럼이름'].apply(lambda x: int(x.replace(',','')))

 

 

🔽 replace 사용하지 않고 콤마 제거하기. 그리고 문자열을 숫자로 형변환하기

 

방법(1) maketrans & translate 메서드 사용

a = "123,456"
b = "apple"

from string import maketrans

mapping1 = a.maketrans(',', '')
mapping2 = b.maketrans('aeiou', '12345')

res1 = a.translate(mapping1)  # OUTPUT: "123456"
res2 = b.translate(mapping2)  # OUTPUT: "1ppl2"

a = int(res1)

- maketrans ("기존문자열", "대체문자열")

: 기존 문자열과 대체할 새로운 문자열로 문자 매핑 변환 테이블을 만들어준다. 단, 두 문자열이 하나의 관계에 대해 길이가 같아야한다.

- translate ( )

: 생성된 문자 매핑 변환 테이블을 기반으로 문자 변환 적용하여 새로운 문자열을 만들어준다.

 

 

방법(2) 처음 csv데이터 불러올 때 thousands=',' 파라미터 옵션 사용

df = pd.read_csv(data_url, thousands=',')  #천 단위 자리수 구분 콤마 없애고 불러오기

 

* remove와 clear는 리스트에만 적용가능.

 

 

🔽 특정 컬럼을 제외한 나머지 전체 데이터에 대해 숫자로 데이터 형변환시키고, 결측치가 있다면 0으로 대체하고, 마지막으로  summary statistics 출력하기

import numpy as np

# 연도 컬럼 제외
df3 = df.loc[:,df2.columns!='연도']

# x의 type이 object면 ',' 제거한뒤 integer로 변환하고, 아니라면 x 그대로 놔둬라
new_df = df3.apply(lambda x: x.str.replace(',','').astype(int) if x.dtypes==np.object else x)

# 결측치 0으로 대체
new_df=new_df.fillna(0)

# 요약통계
new_df.describe()