* gemini 3를 활용하여 복기하여, 정확하지 않을 수 있습니다. 유형을 익히는 용도로 사용하시면 좋을 것 같습니다.

+ (추가)시험 결과
다행이 2유형 35점이 나와서 안전빵으로 합격하였습니다ㅜㅜ 빅분기 청산 끝~!

퇴근후 딴짓 교재로 1주일 정도는 설렁설렁 개념 익히고, 시험 일주일 전부터 벼락치기로 기출문제 연습했습니다.
유형 1
1-1.
| | f1 | f2 | f3 | ... |
|---|-----|-----|-----|-----|
| 0 | 10.5| NaN | 30.1| ... |
| 1 | NaN | 20.0| 32.2| ... |
| 2 | 12.1| 22.5| NaN | ... |
1) 데이터셋에서 결측치(NaN)가 가장 많은 컬럼을 찾아라. 해당 컬럼의 결측치를 그 컬럼의 중앙값(Median)으로 대치(Imputation)한 뒤, 대치된 컬럼의 평균(Mean)을 구하시오. (답: 25.055)
import pandas as pd
# 데이터 로드 (가정)
# df = pd.read_csv("data.csv")
# 1. 결측치가 가장 많은 컬럼 찾기
# idxmax()를 쓰면 결측치 개수(sum)가 가장 큰 인덱스(컬럼명)를 가져옵니다.
target_col = df.isnull().sum().idxmax()
# 2. 중앙값(median)으로 대치
median_val = df[target_col].median()
df[target_col] = df[target_col].fillna(median_val)
# 3. 평균값 계산 및 출력
result = df[target_col].mean()
print(result) # 25.055
난이도: 하. 기출을 한 번이라도 풀어보았으면 무조건 풀 수 있는 문제였다.
1-2.
| Country | 2001 | 2002 | ... | 2021 |
|:-------:|:----:|:----:|:---:|:----:|
| Korea | 150 | 155 | ... | 180 |
| USA | 500 | 510 | ... | 480 |
| China | 300 | 320 | ... | 600 |
1) 최다 배출국 빈도: 2001년부터 2021년까지 매년 탄소 배출량이 가장 많은 국가를 선정했을 때, 가장 많이 1위를 차지한 국가의 1위 횟수는? (답: 11회)
2) CAGR 최대값: 각 국가별로 연평균 성장률(CAGR)을 계산하시오. 수식: $(\frac{2021년 배출량}{2001년 배출량})^{0.05} - 1$ . 이 중 가장 높은 값을 구하시오. (답: 0.106)
# 1. (문제 1) 가장 많이 1위를 차지한 횟수 구하기
# 연도 컬럼만 선택 (예: '2001' ~ '2021')
year_cols = [str(y) for y in range(2001, 2022)]
# idxmax()를 이용해 각 연도(열)별로 가장 값이 큰 인덱스(국가명) 추출
# 만약 국가명이 컬럼이 아니라 인덱스에 있다면 df.loc[국가, 연도] 구조여야 함
# 여기서는 df가 'Country' 컬럼을 인덱스로 가지고 있다고 가정
top_countries = df[year_cols].idxmax()
# 빈도수 계산
count_result = top_countries.value_counts().max()
# print(top_countries.value_counts()) # 여기서 Brazil: 11, China: 10 확인 가능
print(count_result) # 11
# 2. (문제 2) CAGR 최대값 구하기
# 공식: (2021년값 / 2001년값) ** 0.05 - 1
df['CAGR'] = (df['2021'] / df['2001']) ** 0.05 - 1
max_cagr = df['CAGR'].max()
print(max_cagr) # 0.106
난이도: 중?... 연도 컬럼을 따로 빼야했던게 생각보다 귀찮았다. for문도 돌려보고 여러가지 시도를 해봤지만, 결국 연도별로 따로 max를 구하는게 가장 확실한 방법같아서 그렇게 진행했었다.
1-3.
| OrderNo | CusID | Quantity | Price |
|:-------:|:-------:|:--------:|:-----:|
| 536365 | 17850 | 6 | 2.55 |
| C536379 | 14527 | 1 | 20.5 | <-- 취소('C')
파생변수 생성: Total = Quantity * Price를 구하시오. 단, OrderNo가 'C'로 시작하면 반품이므로 Total을 음수(-)로 변환하시오.
1) 반품을 반영한(음수 처리) 후, 고객번호(CustomerID)별 총 구매액 합계가 가장 높은 값을 구하시오.
로직: 전체 데이터에서 groupby('CustomerID')['amount'].sum(), max() 값 출력
정답: 2807.73
2) 주문번호가 'C'로 시작하는(반품) 데이터 중에서, 주문번호별 총 금액(절대값 기준 가장 큰 금액)이 가장 높은 주문번호를 구하시오.
로직:
1. amount = Quantity * UnitPrice 계산 (음수 값 생성)
2. InvoiceNo가 'C'로 시작하는 행 필터링
3. InvoiceNo별로 groupby -> sum()
4. 가장 금액이 작은(절대값이 큰) 주문번호 찾기
정답: C542426
# 1. 금액(amount) 파생변수 생성
df['amount'] = df['Quantity'] * df['UnitPrice']
# 2. 반품('C'로 시작) 처리 -> 음수로 변환
# 주문번호(InvoiceNo)가 문자열이어야 함
cond_cancel = df['InvoiceNo'].str.startswith('C')
df.loc[cond_cancel, 'amount'] = df.loc[cond_cancel, 'amount'] * -1
# 3. (문제 1) 주문번호(InvoiceNo)별 반품 합계가 가장 큰 주문번호 찾기
# 'C'로 시작하는 행만 필터링해서 집계
cancel_df = df[cond_cancel].groupby('InvoiceNo')['amount'].sum()
# 반품액은 음수이므로, '절대값이 가장 큰' 혹은 '가장 작은 값(최대 음수)'을 찾아야 함
# 문제에서 '합계가 가장 낮은(음수로 큰)' 주문번호를 물었다면:
result_1 = cancel_df.idxmin()
print(result_1) # C542426
# 4. (문제 2) 고객(CustomerID)별 순매출 최대값
# 전체 데이터(반품 포함)를 고객별로 그룹핑
total_sales = df.groupby('CustomerID')['amount'].sum()
result_2 = total_sales.max()
print(result_2) # 2807.73
난이도: 중상? ... 사실 어렵진 않은데, 주문번호가 C로 시작하는 주문건에 대해서 금액을 음수처리하는 방법을 못 찾았다 ㅜ그리고 C만 들어있는걸 골라주는 함수도 뭘 써야할지 기억이 안 났음...(함수로 해결하는게 가장 좋았겠지만, order로 해결했다는 분들도 계셨음)
유형 2
분류 문제가 나왔고, f1-score 평가지표로 사용
- Target: 게임 활성화 레벨 (0, 1, 2)
- 평가지표: Macro F1-score
RandomForest 사용하였고, 모델 예측했을 때 0.67? 정도 성능 나왔었습니다.
* gemini한테 문제 예측해달라고 했을 때, 분류-회귀가 순서대로 나오는 중이라 이번 회차는 분류일 것 같다고 얘기했었음. 실제로 그렇게 나와서 ㄱㅇㄷ
** 카페에서 무지성랜포 돌렸음에도 불구하고 점수가 천차만별이라 이슈가 되고 있는듯 함...
유형3
3-1
로지스틱 회귀 & 진단 (답: 2.19 / 158 / 0.46)
- 데이터 구성 (의료 데이터 추정): 당뇨병(Diabetes) 데이터셋과 유사
| Age | BMI | Glucose | BloodPressure | Outcome |
|:---:|:---:|:-------:|:-------------:|:-------:|
| 50 | 33.6| 148 | 72 | 1 |
| 31 | 26.6| 85 | 66 | 0 |
1) 오즈비: 종속변수(Outcome)에 대해 로지스틱 회귀분석을 실시했을 때, 특정 독립변수(예: 당뇨 가족력이나 나이 등)의 오즈비(Odds Ratio)는? (단, 소수점 처리 주의) (답: 2.19) -> $\exp(\text{coeff})$ 계산 여부 확인.
2) 조건부 평균(?): (이 부분은 '158'이라는 숫자로 보아) "Outcome이 1인 그룹의 평균 혈당(Glucose)을 구하시오" 혹은 "특정 조건일 때의 혈당 예측값"일 가능성이 높습니다. (답: 158)
3) 민감도: 모델의 예측 결과(Threshold 0.5 기준)에 대한 민감도(Recall)를 구하시오. (답: 0.46)
* 민감도 = 재현율이란걸 몰랐다면 틀릴 수 밖에 없던 문제.(빅분기 필기 공부하셨으면, 다들 알고 계실듯)
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import recall_score
import numpy as np
# 데이터셋 준비 (X, y 분리)
# X = df[['Age', 'BMI', ...]]
# y = df['Outcome']
# 1. 로지스틱 회귀 모델 학습
model = LogisticRegression(solver='liblinear', random_state=1234)
model.fit(X, y)
# (문제 1) 특정 변수의 오즈비(Odds Ratio)
# model.coef_는 회귀계수(log-odds)이므로 exp를 취해야 함
coef_val = model.coef_[0][0] # 첫 번째 변수의 계수라고 가정
odds_ratio = np.exp(coef_val)
print(odds_ratio) # 2.19
# (문제 2) 조건부 평균 (예: 결과가 1인 그룹의 Glucose 평균)
mean_val = df[df['Outcome'] == 1]['Glucose'].mean()
print(mean_val) # 158
# (문제 3) 민감도 (Recall) 구하기
pred = model.predict(X)
sensitivity = recall_score(y, pred)
print(sensitivity) # 0.46
3-2
광고 효과 T-test & 회귀 (답: 0.429 / 0.505 / 2075.945)
| Sales | Ad_Budget | Pre_Event | Post_Event |
|:-----:|:---------:|:---------:|:----------:|
| 34000 | 500 | 3000 | 3200 |
| 36000 | 600 | 4000 | 4100 |
1) 상관계수: Sales(종속)와 가장 상관관계가 높은 변수와의 피어슨 상관계수를 구하시오. (답: 0.505)
2) 단일표본 T-검정: "평균 판매량이 35,000원이다"라는 귀무가설을 검정하시오. 양측검정 P-value는? (답: 0.429)
3) 회귀계수: Sales를 종속변수로 하고 Ad_Budget(혹은 상관계수 1등 변수)을 독립변수로 하는 단순 선형 회귀분석을 수행했을 때, 기울기(회귀계수)는? (답: 2075.945)
from scipy import stats
from sklearn.linear_model import LinearRegression
# 1. (문제 1) 상관계수 구하기
# 'Sales'와 다른 변수들 간의 상관계수 중 가장 높은 것 찾기
# abs()를 쓰는 이유는 음의 상관관계가 강할 수도 있어서인데,
# 여기선 0.505(양수)가 답이라고 하셨으니 그냥 max()
corr_max = df.corr()['Sales'].drop('Sales').max()
print(corr_max) # 0.505
# 2. (문제 2) 단일표본 T-검정 (귀무가설: 평균 = 35000)
# p-value 구하기
t_stat, p_val = stats.ttest_1samp(df['Sales'], 35000)
print(p_val) # 0.429 (귀무가설 기각 실패 -> 평균은 35000과 차이 없다)
# 3. (문제 3) 단순 선형 회귀분석 계수 구하기
# 상관계수가 가장 높았던 변수(예: 'Ad_Budget')를 X로 설정
# X는 2차원 배열이어야 함 [[값], [값]]
X_reg = df[['Ad_Budget']]
y_reg = df['Sales']
lr = LinearRegression()
lr.fit(X_reg, y_reg)
print(lr.coef_[0]) # 2075.945
** 시험 전 날 gemini로 예상했던 기출문제들


혹시 몰라서 t_test도 공부해갔는데 나왔었던...^^...
가채점 결과로는 1문제 빼고 맞았는데,,, 2유형 결과가 중요할 듯...