혼자 공부중/NLP

[AICE] AICE Associate 샘플 문항 예제 및 정답 + 문제풀이

onnnzeoz 2025. 6. 17. 20:39

AICE에서 제공하는 샘플 문항입니다.

공식 홈페이지에서 시험과 같은 환경에서 풀어볼 수 있습니다.

https://aice.study/certi/practice

 

AICE

KT가 개발하여 한국경제신문과 함께 주관하는 인공지능 능력시험입니다.

aice.study


10번 문제부터는 문제풀이도 함께 정리했습니다.


 

1. scikit-learn 패키지는 머신러닝 교육을 위한 최고의 파이썬 패키지입니다.
scikit-learn를 별칭(alias) sk로 임포트하는 코드를 작성하고 실행하세요.
---

import sklearn as sk



2. Pandas는 데이터 분석을 위해 널리 사용되는 파이썬 라이브러리입니다.
Pandas를 사용할 수 있도록 별칭(alias)을 pd로 해서 불러오세요.
---

import pandas as pd



3. 모델링을 위해 분석 및 처리할 데이터 파일을 읽어오려고 합니다.
Pandas함수로 2개 데이터 파일을 읽고 합쳐서 1개의 데이터프레임 변수명 df에 할당하는 코드를 작성하세요.

- A0007IT.json 파일을 읽어 데이터 프레임 변수명 df_a에 할당하세요.
- signal.csv 파일을 읽어 데이터 프레임 변수명 df_b에 할당하세요.
- df_a와 df_b 데이터프레임을 판다스의 merge 함수를 활용하여 합쳐 데이터프레임 변수명 df에 저장하세요.
- 합칠때 사용하는 키(on) : 'RID'
- 합치는 방법(how) : 'inner'
---

#json과 csv 를 읽어올 땐 각각 read_json과 read_csv를 쓴다
df_a = pd.read_json("A0007IT.json")
df_b = pd.read_csv("signal.csv")
df = pd.merge(df_a,df_b,on='RID',how='inner')

#데이터 프레임 출력 명령어
df



4. Address1(주소1)에 대한 분포도를 알아 보려고 합니다.
Address1(주소1)에 대해 countplot그래프로 만드는 코드와 답안을 작성하세요.

- Seaborn을 활용하세요. 
- 첫번째, Address1(주소1)에 대해서 분포를 보여주는 countplot 그래프 그리세요.
- 두번째, 지역명이 없는 '-' 에 해당되는 row(행)을 삭제하세요.
- 출력된 그래프를 보고 해석한 것으로 옳지 않은 선택지를 아래에서 골라 '답안04' 변수에 저장하세요.(예. 답안04 = 4)
  1. Countplot 그래프에서 Address1(주소1) 분포를 확인시 '경기도' 분포가 제일 크다.
  2. Address1(주소1) 분포를 보면 '인천광역시' 보다 '서울특별시'가 더 크다.
  3. 지역명이 없는 '-' 에 해당되는 row(행)가 2개 있다.
---

import seaborn as sns

#3번 선택지를 확인하기 위해 지역명이 '-'에 해당하는 행의 갯수 반환, 출력 후 갯수 확인
count_minus = (df['Address1'] == '-').sum()
print(count_minus)

# Address1 값이 '-'가 아닌 값만 df에 다시 넣어준다 -> df에서 Address1 값이 '-'인 값 삭제
df = df[df['Address1']!='-']
sns.countplot(data=df, x='Address1')
plt.show

#3번 선택지의 정답은 2개가 아닌 3개다. 틀린 선택지이므로 3을 답안04 변수에 대입
답안04 = '3'



5. 실주행시간과 평균시속의 분포를 같이 확인하려고 합니다.
Time_Driving(실주행시간)과 Speed_Per_Hour(평균시속)을 jointplot그래프로 만드세요.

- Seaborn을 활용하세요. 
- X축에는 Time_Driving(실주행시간)을 표시하고 Y축에는 Speed_Per_Hour(평균시속)을 표시하세요.
---

import seaborn as sns
sns.jointplot(data= df, x = 'Time_Driving',y = 'Speed_Per_Hour')



6. 위의 jointplot 그래프에서 시속 300이 넘는 이상치를 발견할수 있습니다.
가이드에 따라서 전처리를 수행하고 저장하세요.

- 대상 데이터프레임 : df
- jointplot 그래프를 보고 시속 300 이상되는 이상치를 찾아 해당 행(Row)을 삭제하세요.
- 불필요한 'RID' 컬럼을 삭제 하세요.
- 전처리 반영 후에 새로운 데이터프레임 변수명 df_temp 에 저장하세요.
---

#'Speed_Per_Hour'가 300보다 적은 값만 df_temp에 할당
#안전하게 .copy() 해서 저장하기
df_temp= df[df['Speed_Per_Hour'] < 300].copy()

#컬럼 삭제를 원할 땐
#데이터프레임.drop(columns=['컬럼명'])
df_temp = df_temp.drop(columns=['RID'])

df_temp



7. 모델링 성능을 제대로 얻기 위해서 결측치 처리는 필수입니다.
아래 가이드를 따라 결측치 처리하세요.

- 대상 데이터프레임 : df_temp
- 결측치를 확인하는 코드를 작성하세요.
- 결측치가 있는 행(row)를 삭제 하세요.
- 전처리 반영된 결과를 새로운 데이터프레임 변수명 df_na 에 저장하세요.
- 결측치 개수를 '답안07' 변수에 저장하세요.(예. 답안07 = 5)
---

#결측치 확인하는 코드
답안07 = df_temp.isnull().sum().sum()

#sum()을 2번 해주는 이유
#isnull() 함수는 DataFrame 전체를 True/False로 바꿔줌. NaN이면 True, 아니면 False
#처음 sum()을 하면 열단위로 true 의 갯수를 셈
#두번째 sum()을 했을 때 한 번 더 열 단위로 숫자들의 합계를 구함

#결측치가 있는 행 삭제 하면서 바로 df_na에 넣어줘야 함
df_na = df_temp.dropna()



8. 모델링 성능을 제대로 얻기 위해서 불필요한 변수는 삭제해야 합니다.
아래 가이드를 따라 불필요 데이터를 삭제 처리하세요.

- 대상 데이터프레임 : df_na
- 'Time_Departure', 'Time_Arrival' 2개 컬럼을 삭제하세요.
- 전처리 반영된 결과를 새로운 데이터프레임 변수명 df_del 에 저장하세요.
---

df_del = df_na.drop(columns=['Time_Departure', 'Time_Arrival'])

 

 

9. 원-핫 인코딩(One-hot encoding)은 범주형 변수를 1과 0의 이진형 벡터로 변환하기 위하여 사용하는 방법입니다.
원-핫 인코딩으로 아래 조건에 해당하는 컬럼 데이터를 변환하세요.

- 대상 데이터프레임 : df_del
- 원-핫 인코딩 대상 : object 타입의 전체 컬럼
- 활용 함수: Pandas의 get_dummies
- 해당 전처리가 반영된 결과를 데이터프레임 변수 df_preset에 저장해 주세요.
---

df_preset = pd.get_dummies(df_del, df_del.select_dtypes('object').columns)



10. 훈련과 검증 각각에 사용할 데이터셋을 분리하려고 합니다.
Time_Driving(실주행시간) 컬럼을 label값 y로, 나머지 컬럼을 feature값 X로 할당한 후 훈련데이터셋과 검증데이터셋으로 분리하세요.
추가로,  가이드 따라서 훈련데이터셋과 검증데이터셋에 스케일링을 수행하세요.

- 대상 데이터프레임 : df_preset
- 훈련과 검증 데이터셋 분리
  - 훈련 데이터셋 label : y_train, 훈련 데이터셋 Feature: X_train
  - 검증 데이터셋 label : y_valid, 검증 데이터셋 Feature: X_valid
  - 훈련 데이터셋과 검증데이터셋 비율은 80:20
  - random_state : 42
  - Scikit-learn의 train_test_split 함수를 활용하세요.
- RobustScaler 스케일링 수행
  - sklearn.preprocessing의 RobustScaler 함수 사용
  - 훈련데이터셋의 Feature는 RobustScaler의 fit_transform 함수를 활용하여 X_train 변수로 할당
  - 검증데이터셋의 Feature는 RobustScaler의 transform 함수를 활용하여 X_valid 변수로 할당
---

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import RobustScaler 

# 1. label(y)와 feature(X) 분리
y = df_preset['Time_Driving']
X = df_preset.drop(columns=['Time_Driving'])

# 2. 훈련/검증 데이터셋 분리 (80:20, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=42)

# 3. RobustScaler로 스케일링
scaler = RobustScaler()
X_train = scaler.fit_transform(X_train)  # 훈련 데이터 학습 + 변환
X_valid = scaler.transform(X_valid)      # 검증 데이터 변환만

 

알아두면 좋은 지식⬇️

 

1. 데이터 전처리에서 스케일링이란?

데이터 값을 일정하게 맞추는 작업.

예를 들어 키(cm)나 몸무게(kg)처럼 단위나 범위가 다른 데이터가 있으면 머신러닝 모델이 잘못 학습할 수 있기 때문에 스케일링으로 맞춰준다.

 

2. RobustScaler란?
RobustScaler는 이상치(outlier)에 강한 스케일러.
데이터의 중앙값(median)과 사분위수(IQR)를 기준으로 데이터를 변환.

 

3. RobustScaler 의 fit_transform() 함수 의미?

fit : 데이터의 분포(평균, 표준편차 등)를 학습합니다.

transfrom : 앞서 학습한 기준으로 데이터 변환

fit_transform : fit과 transfrom을 한 번에 수행

 

==> 훈련 데이터가 모델이 처음 보는 데이터 이므로 fit_transform() 으로 학습 후 변환까지 해주고

       검증 데이터에서는 변환만 해주면 됨

 



  11. Time_Driving(실주행시간)을 예측하는 머신러닝 모델을 만들려고 합니다. 
  의사결정나무(decision tree)와 랜덤포레스트(RandomForest)는 여러 가지 규칙을 순차적으로 적용하면서
독립 변수 공간을 분할하는 모형으로 분류(classification)와 회귀 분석(regression)에 모두 사용될 수 있습니다.
  아래 가이드에 따라 의사결정나무(decision tree)와 랜덤포레스트(RandomForest) 모델 만들고 학습을 진행하세요.

- 의사결정나무(decision tree)
  - 트리의 최대 깊이 : 5로 설정
  - 노드를 분할하기 위한 최소한의 샘플 데이터수(min_samples_split) : 3로 설정
  - random_state : 120로 설정
  - 의사결정나무(decision tree) 모델을 dt 변수에 저장해 주세요.
- 랜덤포레스트(RandomForest)
  - 트리의 최대 깊이 : 5로 설정
  - 노드를 분할하기 위한 최소한의 샘플 데이터수(min_samples_split) : 3로 설정
  - random_state : 120로 설정
  - 랜덤포레스트(RandomForest) 모델을 rf 변수에 저장해 주세요.
- 위의 2개의 모델에 대해 fit을 활용해 모델을 학습해 주세요. 학습 시 훈련데이터 셋을 활용해 주세요.
---

from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor

dt = DecisionTreeRegressor(max_depth=5, min_samples_split=3, random_state  = 120)
rf = RandomForestRegressor(max_depth=5, min_samples_split=3, random_state  = 120)

# 훈련 데이터로 모델 학습
dt.fit(X_train, y_train)
rf.fit(X_train, y_train)

 

알아두면 좋은 지식⬇️


max_depth=5: 트리가 너무 복잡해지는 것을 방지합니다.
min_samples_split=3: 노드 분할 시 최소 3개의 샘플이 있어야 합니다.
random_state=120: 동일한 결과를 보장합니다.

 

X_train: 스케일링된 훈련용 특성(feature) 데이터
y_train: 훈련용 레이블(label) 데이터



12. 위 의사결정나무(decision tree)와 랜덤포레스트(RandomForest) 모델의 성능을 평가하려고 합니다.
아래 가이드에 따라 예측 결과의 mae(Mean Absolute Error)를 구하고 평가하세요. 

- 성능 평가는 검증 데이터셋을 활용하세요.
- 11번 문제에서 만든 의사결정나무(decision tree) 모델로 y값을 예측(predict)하여 y_pred_dt에 저장하세요.
- 검증 정답(y_valid)과 예측값(y_pred_dt)의 mae(Mean Absolute Error)를 구하고 dt_mae 변수에 저장하세요.
- 11번 문제에서 만든 랜덤포레스트(RandomForest) 모델로 y값을 예측(predict)하여 y_pred_rf에 저장하세요.
- 검증 정답(y_valid)과 예측값(y_pred_rf)의 mae(Mean Absolute Error)를 구하고 rf_mae 변수에 저장하세요.
- 2개의 모델에 대한 mae 성능평가 결과을 확인하여 성능좋은 모델 이름을 '답안12' 변수에 저장하세요.
  - 예) 답안12 = 'decisiontree' 혹은 답안12 = 'randomforest' 
---

from sklearn.metrics import mean_absolute_error

# 1. 의사결정나무로 검증 데이터 예측
# X_valid 이 값은 예측에 사용하는 입력값, 특징 같은 것임.
# 예를 들어 속도을 구하고 싶으면 X_valid는 거리와 시간과 같은 변수임.
# 속도는 y_valid인것임.
y_pred_dt = dt.predict(X_valid)
# MAE 계산
dt_mae = mean_absolute_error(y_valid, y_pred_dt)

#랜덤포레스트로 검증데이터 예측
y_pred_rf = rf.predict(X_valid)
# MAE 계산
rf_mae = mean_absolute_error(y_valid, y_pred_rf)

# MAE 성능 평가, 낮을 수록 좋은 것
if dt_mae > rf_mae :
     답안12 =  'randomforest' 
else :
     답안12 =  'decisiontree'



13. Time_Driving(실주행시간)을 예측하는 딥러닝 모델을 만들려고 합니다.
아래 가이드에 따라 모델링하고 학습을 진행하세요.

- Tensorflow framework를 사용하여 딥러닝 모델을 만드세요.
- 히든레이어(hidden layer) 2개이상으로 모델을 구성하세요.
- dropout 비율 0.2로 Dropout 레이어 1개를 추가해 주세요.
- 손실함수는 MSE(Mean Squared Error)를 사용하세요.
- 하이퍼파라미터 epochs : 30, batch_size : 16 으로 설정해 주세요.
- 각 에포크마다 loss와 metrics 평가하기 위한 데이터로 x_valid, y_valid 사용하세요.
- 학습정보는 history 변수에 저장해 주세요.
---

# 1. 모델 아키텍처 구성
model = Sequential([
    Dense(64, activation='relu', input_shape=(X_train.shape[1],)),  # 첫 번째 히든 레이어
    Dense(64, activation='relu'),                                   # 두 번째 히든 레이어
    Dropout(0.2),                                                   # 드롭아웃 레이어
    Dense(1)                                                        # 출력 레이어 (회귀 문제)
])

# 2. 모델 컴파일
model.compile(optimizer='adam',
              loss='mse',       # MSE 손실 함수 사용
              metrics=['mse'])  # 추가 평가 지표(선택사항)

# 3. 모델 학습
history = model.fit(
    X_train, y_train,
    epochs=30,
    batch_size=16,
    validation_data=(X_valid, y_valid)  # 검증 데이터 지정
)

################################################ 아래 처럼 풀 수도 있다

model = Sequential()
model.add(Dense(128, input_shape=(X_train.shape[1],), activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(64, activation='relu'))
model.add(Dense(1))

model.compile(optimizer='adam', loss='mse', metrics='mse')
history = model.fit(X_train, y_train, epochs=30, batch_size=16, validation_data=(X_valid, y_valid))

 


알아두면 좋은 지식⬇️

Tensorflow에서 딥러닝 모델 만드는법 3가지
1. Sequential 모델 : 레이어 순차적 add
2. Functional 모델 : input layer부터 output layer까지 입력 변수 넣어줌
3. Subclassing 모델 : 모델 클래스를 생성하고 Model 모듈을 상속
이 문제에서 Sequential 모델을 사용해야하는 이유
- 히든레이어 2개 + dropout + 출력층으로 순차적인 구조
- 출력값은 Time_Driving(실주행시간) 이거 1개



🗺️모델 구조 설계

Sequential(): 레이어를 순차적으로 쌓는 모델 생성

Dense(64): 64개의 뉴런을 가진 완전연결층 (히든 레이어)

*64의 의미? 해당 레이어에 있는 뉴런(노드)의 갯수. 즉 이 레이어는 입력값을 받아 64개의 출력값으로 변환함.

  이 문제에서 Dense(128)을 하든 Dense(64)을 하든 큰 상관은 없음. 다만, 더 복잡한 문제를 풀 때 더 많은 뉴런을 사용함 근데 더 많은 뉴런을 사용하면 과적합이 올 수도 있음.


activation='relu': 활성화 함수로 ReLU 사용
*활성화 함수란? 각 뉴런이 입력값을 받아 어떤 값을 출력할지 결정하는 함수이다. 입력 신호의 총합을 변환해서 다음 층으로 전달할지, 얼마나 강하게 전달할지 정함. 활성화 함수가 없다면 신경망은 여러 층을 쌓아도 결국 하나의 선형 함수가 됨. -> 복잡한 패턴 학습 불가

*ReLU란? 가장 널리 쓰이는 활성화 함수. 입력값이 0보다 크면 그대로 출력, 0 이하면 0을 출력. 비선형 함수 -> 뉴런에 비선형성을 부여하여 복잡한 문제를 풀 수 있게함


Dropout(0.2): 20%의 뉴런을 무작위로 비활성화 (과적합 방지)

 

input_shape=(X_train.shape[1],) : 모델의 첫 번째 레이어에 입력될 데이터의 형태를 지정함. (그래서 두 번째 레이어부터는 안들어감)

예를 들어 X_train(1000,10)이면 1000은 데이터 갯수(행), 10은 데이터 특징(열) 갯수 임.

근데 이제 문제처럼 X_train.shape[1] 이렇게 되어있으면 X_train.shape[1] = 10 이 되는것임

뒤에 붙은 콤마(,)는 튜플임을 명확하게 하기 위해서 붙음. 튜플은 한 번 만들면 안의 값을 바꿀 수가 없음.

 

Dense(1) : 회귀 문제의 출력레이어는 출력값(Time_Driving)이 한 개이므로 Dense(1)을 사용한다. 


☑️모델 설정

optimizer='adam': Adam 최적화 알고리즘 사용

*가장 기본적인 옵티마이저, 회귀, 분류, 이미지, 텍스트 등 다양한 문제에 모두 잘 적용


loss='mse': 손실함수로 평균제곱오차(Mean Squared Error) 사용

* 손실함수란? 머신러닝 모델이 얼마나 잘 예측하고 있는지 수치로 평가하기 위해 사용

* MSE : 실제값과 예측값의 차이(오차)를 제곱해서 평균낸 것 -> 오차가 클 수록 손실값이 크게 증가.

주로 회귀 문제에서 많이 사

//metrics=['mae']: 추가 평가 지표로 평균절대오차 사용 (선택사)

❇️학습 과정

 

X_train, y_train : 모델이 학습할 데이터, 이 데이터를 바탕으로 예측하는 법 배우기

 

epochs=30: 전체 데이터를 30번 반복 학습

batch_size=16: 한 번에 16개 샘플씩 처리. 데이터가 1000개라면, 한번에 16개씩 묶어서 총 62.5번씩 각 epochs 마다 학습함. 

validation_data=(X_valid, y_valid) : 각 에포크 끝에 검증 데이터로 평가, 이 데이터로는 학습하지 않고 평가할 때만 사용.



14. 위 딥러닝 모델의 성능을 평가하려고 합니다.
Matplotlib 라이브러리 활용해서 학습 mse와 검증 mse를 그래프로 표시하세요.

- 1개의 그래프에 학습 mse과 검증 mse 2가지를 모두 표시하세요.
- 위 2가지 각각의 범례를 'mse', 'val_mse'로 표시하세요.
- 그래프의 타이틀은 'Model MSE'로 표시하세요.
- X축에는 'Epochs'라고 표시하고 Y축에는 'MSE'라고 표시하세요.
---


# 여기에 답안코드를 작성하세요.

import matplotlib.pyplot as plt

# 학습 곡선 시각화
plt.plot(history.history['mse'])  #각 epoch마다 훈련데이터에서 계산된 mse값의 변화를 그래프로 그림
plt.plot(history.history['val_mse']) #각 epoch마다 검증데이터에서 계산된 mse값의 변화를 그래프로 그림
plt.legend(['mse', 'val_mse']) #범례 추가
plt.title('Model MSE') #제목설정
plt.xlabel('Epochs')   #x축레이블(학습반복횟수)
plt.ylabel('MSE')      #y축레이블(평균제곱오차)
plt.show()