03-05) Feature Engineering

slow_starter·2025년 7월 13일
0

모두의연구소-DS4기

목록 보기
26/30
post-thumbnail

재취업하고 예전에 공부했던 것들(github에도 정리는 되어있긴 하다.)
다시 복습해보니 감회가 새롭긴 하다.
첫 번째 회사에서는 주로 R을 다뤘고, 두 번째 회사에서 Python, SQL
다룬 경험이 있지만 머신러닝 모델 몇 개 만져본 정도니까.

01. 컬럼이름 변경/결측치 처리

  • 컬럼 분석 목적에 맞게 변경
  • 결측치 제거하기
import pandas as pd
import numpy as np
import seaborn as sns
# dating_df 이름으로 data/dating.csv 불러오기
dating_df =pd.read_csv('data/dating.csv')
# 6가지 평가항목에 대해 아래와 같이 컬럼이름 변경 (평가항목: attractive, sincere, intelligence, funny, ambitious, shared_interests)
# 예: "pref_o_attractive" --> "o_important_attractive"
#     "attractive_o" --> "o_score_attractive"
#     "attractive_important" --> "i_important_attractive"
#     "attractive_partner" --> "i_score_attractive"

new_cols = []

for i in dating_df.columns:
    #[[your code]]
    if i.startswith('pref_o'):
        i = i.replace('pref_o','o_important')
    elif i.endswith('_o'):
        i = 'o_score_' + i.replace('_o','')
    elif i.endswith('_important'):
        i = 'i_important_' + i.replace('_important'+'')
    elif i.endswith('_partner'):
        i = 'i_score_'+i.replace('_partner','')
    new_cols.append(i)

dating_df.columns = new_cols
# 6가지 평가 항목 이외의 컬럼이름이 변경된 경우, 기존 이름으로 변경
# o_score_age, o_score_race, o_age, o_race로 변
dating_df = dating_df.rename({'o_score_race': 'race_o', 'o_score_age': 'age_o'}, axis=1)
# "o_important_"와 "i_important_"로 시작되는 컬럼이름을 drop_cols라는 이름의 리스트에 모으기
drop_cols = []

for i in dating_df.columns:
    #[[your code]]
    if i.startswith('i_important_'):
        drop_cols.append(i)
    elif i.startswith('o_important_'):
        drop_cols.append(i)

# drop_cols
# drop_cols에 속해있는 변수들의 결측치 행들을 제거하고 dating_df로 저장   
dating_df = dating_df = dating_df.dropna(subset = drop_cols)
# 나머지 결측치를 -99로 채우고 dating_df로 저장
# dating_df = #[[your code]]
dating_df = dating_df.fillna(-99)

02. 이상치 처리

# "o_score_", "i_score_"로 시작되는 변수 중, 10점 이상인 값은 10으로 대체(lambda 함수 활용하기)

# dating_df['o_score_attractive'] = dating_df['o_score_attractive'].apply(lambda x: 10  if x > 10  else x )
# dating_df['o_score_funny'] = dating_df['o_score_funny'].apply(lambda x: 10  if x > 10  else x )

dating_df['o_score_attractive'] = dating_df['o_score_attractive'].apply(lambda x:10 if x>10 else x) 
dating_df['o_score_funny'] = dating_df['o_score_funny'].apply(lambda x:10 if x>10 else x)
# "o_important_", "i_important"로 시작되는 각각의 6항목의 합은 100이 되어야한다. 
# 합이 100이 아닌 행들을 찾아 가중치를 부여하여 합이 100이 되도록 만들어보자.

# o_important로 시작하는 변수 모으기
o_imp = []

for i in dating_df.columns:
    #[[your code]]
    if i.startswith('o_important'):
        o_imp.append(i)

# o_important로 시작하는 변수들의 합 구하기           
dating_df['o_imp_sum'] = dating_df[o_imp].sum(axis=1) #[[your code]]

# i_important로 시작하는 변수 모으기
i_imp = []

# o_important로 시작하는 변수들의 합 구하기 
for i in dating_df.columns:
     #[[your code]]
     if i.startswith('i_important'):
         i_imp.append(i)
        
dating_df['i_imp_sum'] = dating_df[i_imp].sum(axis=1) #[[your code]]

# 가중치 부여하여 업데이트하기
dating_df[o_imp] = dating_df.apply(lambda x: (100 / x['o_imp_sum']) * x[o_imp], axis = 1) #[[your code]]
dating_df[i_imp] = dating_df.apply(lambda x: (100 / x['i_imp_sum']) * x[i_imp], axis = 1) #[[your code]]

# 불필요 컬럼 제거
dating_df.drop(['o_imp_sum','i_imp_sum'], axis=1, inplace = True)

03. Feature engineering

# "남자의 나이-여자의 나이" 를 구하는 함수를 age_func 이름으로 만들기 (나이에 -99가 있는 경우는 -99를 return)
def age_func(x):
    #[[your code]]
    if x['age'] == -99:
        return -99
    elif x['age_o'] == -99:
        return -99
    elif x['gender'] == 'female':
        return x['age_o'] - x['age']
    else:
        return x['age'] - x['age_o']
# dating_df를 age_func 함수에 적용시키고, 결과를 "age_gap" 이름의 새 변수로 저장
# dating_df['age_gap'] = #[[your code]]

# dating_df.apply(age_func, axis = 1) # 일단 함수 확인차 실행?
dating_df['age_gap'] = dating_df.apply(age_func, axis = 1)
# "age_gap"변수가 음수인 경우는 'negative', 양수인 경우 'positive', 0인 경우 'zero'의 값으로 "age_gap_dir"이라는 새변수로 저장
# dating_df['age_gap_dir'] = #[[your code]]
# age_gap_direction 컬럼 정의
dating_df['age_gap_dir'] = dating_df['age_gap'].apply(lambda x: 'positive' if x>0 else 'negative' if x<0 else 'zero')
# "age_gap" 변수를 절대값 처리하여 같은 이름으로 저장
dating_df['age_gap'] = abs(dating_df['age_gap']) #[[your code]]
# 양측 race 정보의 동일 여부를 비교하여, 동일할 경우 1, 다를 경우 -1로 "same_race"라는 새변수로 저장
# dating_df['same_race'] = #[[your code]]
dating_df['same_race'] = (dating_df['race'] == dating_df['race_o']).astype('int').replace({0:-1})
# "same_race"와 "importance_same_race" 변수를 곱하여 "same_race_point"라는 새변수로 저장
dating_df['same_race_point'] = dating_df['same_race'] * dating_df['importance_same_race'] #[[your code]]
# "o_important", "o_score", "i_important", "i_score"로 시작하는 변수 이름을 각각의 리스트로 저장
o_important = []
o_score = []
i_important = []
i_score = []

for i in dating_df.columns:
    #[[your code]]
    if i.startswith('o_important'):
        o_important.append(i)
    elif i.startswith('o_score'):
        o_score.append(i)
    elif i.startswith('i_important'):
        i_important.append(i)
    elif i.startswith('i_score'):
        i_score.append(i)
# "o_important", "i_important"로 시작하는 변수에서 0인 값을 -99로 변경하여 저장
dating_df[o_important] = dating_df[o_important].replace({0:-99})#[[your code]]
dating_df[i_important] = dating_df[i_important].replace({0:-99})#[[your code]]
# rating 함수 만들기: important항목과 score 항목을 곱하되, -99가 들어있는 경우는 -99가 return되도록 정의
def rating(data, important, score):
    #[[your code]]
    if data[score] == -99:
        return -99
    elif data[important] == -99:
        return -99
    else:
        return data[important] * data[score]
# 계산된 rating에 대한 컬럼 이름 설정    
o_rating = ['o_rating_attractive',
 'o_rating_sincere',
 'o_rating_intellicence',
 'o_rating_funny',
 'o_rating_ambtition',
 'o_rating_shared_interests']

i_rating = ['i_rating_attractive',
 'i_rating_sincere',
 'i_rating_intellicence',
 'i_rating_funny',
 'i_rating_ambtition',
 'i_rating_shared_interests']
# rating함수를 통해 "나"의 rating 값과 "상대"의 rating 값을 각각 계산하고 위에 정의된 이름의 변수로 저장 (for loop와 zip을 사용)
for i, j, k in zip(o_important, o_score, o_rating):
     dating_df[k] = dating_df.apply(lambda x: rating(x, i, j), axis = 1) #[[your code]]
        
for i, j, k in zip(i_important, i_score, i_rating):
     dating_df[k] = dating_df.apply(lambda x: rating(x, i, j), axis = 1) #[[your code]]

04. 회고

  • 이번 모듈(데이터 전처리)에서 python기초에 대해 많이
    복습할 수 있었음
  • 사실 현업에서 R, python 쓸 때는 전처리나, feature-engineering이
    좀 더 복잡한 경우가 많았음(특히 수천 명 이상의 재직자가 있는
    회사들이면 RDBMS가 잘 갖춰져있는데, 그게 아닌 경우는
    데이터가 적재되어 있더라도 그게 데이터 분석가, 데이터 사이언티스트를
    고려해서 적재된 데이터가 아니기 때문)
  • 보통 어느 업종, 어느 직무를 가나 '자신의 전문분야'와 '커리어'가 align이
    잘 되지 않는 경우가 꽤 많고 그런 차원에서 난 경력대비 '물경력'이긴 하다.
  • 돌이켜 보면 '모두의 연구소'에서 KDT 기초 교육을 받은 것이, 내 '물경력'을
    일정 부분 보완하는데 큰 도움이 되긴 했다.
profile
2025화이팅!

0개의 댓글