Dacon code review

코드 리뷰(데이콘, 전처리)

  1. 마감된 대회에서 데이터를 다운 받고, 코드 공유에서 간단하게 살펴 본 후 자신의 스타일이 맞는 코드(너무 어렵지 않은 코드)를 찾습니다.

  2. ppt파일로 간단하게 코드를 왜 이런식(공유된 방식)으로 짰는지 보통 설명이 되있습니다.

  3. ppt바로 아래 코드가 공유되있는데 오른쪽에 보면 다운로드가 있는데 클릭하여 다운받습니다.

  4. jupyternotebook을 이용하여 해당 파일을 열어줍니다.

  5. 일단 간단하게 왜 이런식으로 짰고, 코드 방식이 어떤식으로 흘러가는지 이해합니다.

  6. 처음부터 끝까지 코드를 안보고 비슷하게 구동될 때까지 리뷰를 합니다.


데이콘(제주도 도로 교통량 예측 AI 경진대회)

1.함수 선언에서 모르는 함수가 있는지 확인. 모르면 구글링하여 찾아보기.

2.csv to parquet(파켓)에서 파켓 파일을 왜 사용하는지 구글링 및 함수 다시 만들어보기

1
2
3
4
5
6
7
8
9
10
11
12
def csv_to_parquet(csv_path, save_name):
df = pd.read_csv(csv_path)
df.to_parquet(f'./{save_name}.parquet')
del df
gc.collect()
print(save_name, 'Done.')
# 초기 1회만 수행(csv->parquet)
csv_to_parquet('./train.csv', 'train')
csv_to_parquet('./test.csv', 'test')
# parquet불러오기
train = pd.read_parquet('./train.parquet')
test = pd.read_parquet('./test.parquet')

3.EDA는 코드 리뷰 전에 개인적으로 해보고 남들이 사용한 방식 보기.

4.시계열 데이터(datetime)을 라벨화 할 수 있게 추가 열 생성.

1
2
3
4
train['base_date'] = train['base_date'].astype('str')     
train['year'] = train['base_date'].apply(lambda x: x[:4]).astype('int')
train['month'] = train['base_date'].apply(lambda x: x[4:6]).astype('int')
train['day'] = train['base_date'].apply(lambda x: x[6:8]).astype('int')

5.이번 데이터는 train데이터(21년7월~22년7월)와 test데이터(22년8월)의 날짜 차이가 크기 때문에

1
2
test = train.query('month==7 and year==2022 and day>15').reset_index(drop=True)
train = train.query('month!=7 or year!=2022 or day<=15').reset_index(drop=True)

이런식으로 데이터를 나눈 것을 확인 (참고하여 추후에 비슷한 문제 나와도 이런 방식으로 생각해보기)

6.라벨 인코딩 할 수 있는 열들을 한 번에 인코딩하기

1
2
3
4
5
6
7
8
9
10
11
12
str_col = ['day_of_week','start_turn_restricted','end_turn_restricted',
'road_name','road_type','road_rating','start_node_name','end_node_name',
'start_latitude','end_latitude','start_longitude','end_longitude']
for i in str_col:
le = LabelEncoder()
le=le.fit(train[i])
train[i]=le.transform(train[i])

for label in np.unique(test[i]):
if label not in le.classes_:
le.classes_ = np.append(le.classes_, label)
test[i]=le.transform(test[i])

7.파생 변수 생성(Feature Engineering) - 매우 중요

제가 리뷰하는 코드를 작성한 팀은 다음과 같은 변수를 생성했음을 파악.

  • 주요 항목별 target의 train 데이터셋 평균과 표준편차를 파생변수로 생성!
  • [시간, 제한속도]별 target 평균은 별도 파생변수로 생성
  • [시간]별 targe 평균에 대한 [시간,제한속도]별 target 평균의 비율 추가
  • 파생 변수는 train 데이터셋 만으로 생성한 이후, test 데이터셋으로 merge
  • train & target을 합친 후 데이터를 구해서 어떤게 더 좋은지 파악해봐도 좋을듯함 (아마 train이 더 좋아서 train만 한듯합니다.
  • 이와 같은 파생 변수 생성은 문제들을 많이 풀어보고 경험이 축적되어야 좋은 모델을 만들 수 있을 듯합니다.
  • 일단, 제 경우는 이러한 코드들에서 이러한 변수를 어떤식으로 왜 만들었는지 분석해보고, 추후 적용할 수 있을지 파악하는 편입니다.
1
2
3
4
5
6
7
8
9
10
11
12
names = ['day_of_week', 'base_hour','road_name','start_node_name','end_node_name','maximum_speed_limit','start_latitude','end_latitude','start_longitude','end_longitude']
for name in names:
print(name)
df1 = train.groupby(name).mean().reset_index()[[name,'target']].rename(columns={'target':f'{name}_mean_target'})
train = pd.merge(train,df1,on=name,how='left')

test = pd.merge(test,df1,on=name,how='left')

df1 = train.groupby(['base_hour','maximum_speed_limit']).mean().reset_index()[[ 'base_hour','maximum_speed_limit','target']].rename(columns={'target':'whs_mean_target'})
train = pd.merge(train,df1,on=[ 'base_hour','maximum_speed_limit'],how='left')

test = pd.merge(test,df1,on=[ 'base_hour','maximum_speed_limit'],how='left')

8.null 처리, 카테고리(라벨) 처리

1
2
3
4
5
6
# null 처리 
train = train.fillna(0)
test = test.fillna(0)
# 카테고리 변수 선언
train[str_col] = train[str_col].astype('category')
test[str_col] = test[str_col].astype('category')

9.시간(hour)열 처리

1
2
3
4
5
6
# 시간 cos/sin 변환 추가
train['cos_time'] = np.cos(2*np.pi*(train['base_hour']/24))
train['sin_time'] = np.sin(2*np.pi*(train['base_hour']/24))

test['cos_time'] = np.cos(2*np.pi*(test['base_hour']/24))
test['sin_time'] = np.sin(2*np.pi*(test['base_hour']/24))
  • 여기까지 전처리 코드 리뷰였습니다.

데이터 출처 : 데이콘_코드공유

Author

InhwanCho

Posted on

2022-11-20

Updated on

2022-11-20

Licensed under

Comments