데이터: 객실 사용 여부 관련 데이터
<머신러닝>
(1) 데이터를 탐색하고, 결과를 제시하시오.
(2) 결측치를 탐색하고, 대체 방법 및 근거를 제시하시오.
import pandas as pd
import numpy as np
hotel = pd.read_csv('data/hotel_bookings.csv')
print(hotel.isna().sum())
hotel.info()
print(hotel.deposit_type.describe()) # 종속변수 특징 분석
print(hotel.groupby(hotel['deposit_type']).mean()['adr'])
## 결측치가 1% 미만이면, 결측치가 있는 행 단순 삭제
## 결측치가 1% 이상이면, 최빈값이나 평균으로 대체
hotel_nonull = hotel.copy()
hotel_nonull.dropna(subset=['lead_time'], axis=0, inplace=True) # 행 삭제
hotel_nonull['is_repeated_guest'] = hotel_nonull['is_repeated_guest'].fillna(0) # 값 대체
fill_mean_func = lambda g: g.fillna(g.mean())
hotel_nonull = hotel_nonull.groupby('deposit_type').apply(fill_mean_func) # 그룹별 평균을 이용해 결측값 대체
#hotel_nonull.index = hotel_nonull.index.droplevel(0)
hotel_nonull.sort_index(inplace=True)
hotel_nonull.isna().sum()



(3) 데이터 질을 향상시킬 수 있는 방법을 제안하시오.
- IQR 방식으로 lead_time 변수의 이상치를 보정하여 극단적인 값 제거
- is_repeated_guest 변수의 데이터를 더 수집하여 해당 변수의 불균형을 해소
(4) 데이터 불균형을 시각화하여 식별하고, 불균형 판단근거를 작성하시오.
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
hotel_nonull['is_canceled'] = hotel_nonull['is_canceled'].apply(lambda x: 1 if x == 'yes' else 0)
sns.countplot(x='is_canceled', data=hotel_nonull)
plt.show()
ratio0 = round(len(hotel_nonull[hotel_nonull['is_canceled'] == 0]) / len(hotel_nonull) * 100, 2)
ratio1 = round(len(hotel_nonull[hotel_nonull['is_canceled'] == 1]) / len(hotel_nonull) * 100, 2)
print('0 비율: {}%'.format(ratio0))
print('1 비율: {}%'.format(ratio1))
(5) 오버 샘플링 기법을 설명하고 비교한 뒤 2개 기법을 선정하고 근거를 제시하시오.
일반적으로 불균형한 데이터는 오버 샘플링을 사용함- Random Oversampling, SMOTE
(6) 기법을 선정한 이유를 작성하고, 원데이터를 포함해 3개의 데이터 세트를 구성하시오.
from imblearn.over_sampling import RandomOverSampler, SMOTE
import time
hotel_nonull = pd.get_dummies(hotel_nonull)
X = hotel_nonull[hotel_nonull.columns.difference(['is_canceled'])]
y = hotel_nonull['is_canceled']
start = time.time()
ros = RandomOverSampler(random_state=42)
X_ro, y_ro = ros.fit_resample(X, y)
print('time: ', time.time() - start)
start = time.time()
sm = SMOTE(random_state=42)
X_sm, y_sm = sm.fit_resample(X, y)
print('time: ', time.time() - start)
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
start = time.time()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=100)
clf = RandomForestClassifier(n_estimators=100, min_samples_split=10)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)
print('train 정확도: ', clf.score(X_train, y_train), '\n')
print(classification_report(y_test, pred))
print('time: ', time.time() - start)
start = time.time()
X_ro_train, X_ro_test, y_ro_train, y_ro_test = train_test_split(X_ro, y_ro, test_size=0.2, stratify=y_ro, random_state=100)
clf_ro = RandomForestClassifier(n_estimators=100, min_samples_split=10)
clf_ro.fit(X_ro_train, y_ro_train)
pred_ro = clf_ro.predict(X_ro_test)
print('train 정확도: ', clf_ro.score(X_ro_train, y_ro_train), '\n')
print(classification_report(y_ro_test, pred_ro))
print('time: ', time.time() - start)
start = time.time()
X_sm_train, X_sm_test, y_sm_train, y_sm_test = train_test_split(X_sm, y_sm, test_size=0.2, stratify=y_sm, random_state=100)
clf_sm = RandomForestClassifier(n_estimators=100, min_samples_split=10)
clf_sm.fit(X_sm_train, y_sm_train)
pred_sm = clf_sm.predict(X_sm_test)
print('train 정확도: ', clf_sm.score(X_sm_train, y_sm_train), '\n')
print(classification_report(y_sm_test, pred_sm))
print('time: ', time.time() - start)
(7) 오버 샘플링 데이터와 원데이터를 사용해 정확도 측면 모델 하나와 속도 측면의 모델 하나를 선정하고, 그 이유를 설명하시오.


→ 속도, 정확도 측면에서 Random Oversampling 성능이 더 좋다고 나옴
→ 일반적으로는 SMOTE 정확도가 더 좋다고 함
(8) 원데이터와 오버 샘플링 데이터를 가지고 각각 분류한 결과를 바탕으로, 오버 샘플링이 성능에 미친 영향에 대해 작성하시오.
*테스트 데이터로 모델의 최종 성능을 비교해보면, 오버 샘플링이 분석 정확도에 긍정적인 영향을 줌
*오버 샘플링은 데이터의 불균형으로 인한 과적합을 방지하고, 예측모델의 일반화를 가능하게 함
<통계분석>
1. 공장에서는 시제품의 농도(%)가 60이라고 주장하며 품질관리팀에서 10개의 샘플을 뽑았다. 유의수준 5%에서 다음을 검정하시오.
데이터: (시제품 샘플 농도) 52, 50, 62, 75, 26, 45, 62, 35, 57, 14
(1) 연구가설, 귀무가설을 작성하시오.
- 연구가설(H0): 시제품의 농도는 60이다
- 귀무가설(H1): 시제품의 농도는 60이 아니다
(2) 유효한 샘플 수를 계산하시오.
(3) 검정통계량을 구하고 연구가설 채택 여부를 작성하시오.
→ 중심극한 정리를 적용하기에 표본의 크기가 작으므로 비모수 분석의 부호검정을 실시한다
import numpy as np
import pandas as pd
from scipy import stats
x = [52, 50, 62, 75, 26, 45, 62, 35, 57, 14]
moe = 5 # 오차한계: 5, 신뢰수준: 0.05
a = 0.05
std = np.std(x)
print(std)
print((stats.t.ppf(q=0.05, df=9)*std / 5)**2)
print(stats.wilcoxon(pd.Series(x) - 60))

→ 허용오차식에 오차한계 5, 신뢰수준 0.05, 샘플 표준편차를 대입하여 – 유효한 샘플 수 40
→ Wilcoxon 부호검정*을 통해 시제품의 농도는 60이라고 판단할 수 있다
*모집단이 정규성을 만족하지 못할 때 사용하는 검정
*효과 크기, 검정력이 주어졌을 때, 유효한 샘플 크기 구하는 방법
import statsmodels.stats.api as sms
effect_size = 0.5 # Cohen's d로 효과 크기 (작은 효과 크기: 0.2, 중간 효과 크기: 0.5, 큰 효과 크기: 0.8)
alpha = 0.05 # 유의수준
power = 0.8 # 검정력 (일반적으로 0.8)
alternative = 'two-sided' # 양측 검정
sample_size = sms.tt_ind_solve_power(effect_size=effect_size, alpha=alpha, power=power, alternative=alternative)
print(f"유효한 샘플 크기: {sample_size:.2f}")
2. 코로나 시계열 데이터로 다음을 수행하시오.
데이터: 지역별 코로나 확진자 수 시계열 데이터
(1) ACF 사용해서 distancd를 계산하시오.
*평균연결법으로 계층적 군집분석 수행
임계 값은 linkage matrix 3번째 열의 최대 값의 30%로 설정
- 첫 번째 열: 한 클래스의 인덱스
- 두 번째 열: 다른 클래스의 인덱스
- 세 번재 열: 클래스 사이의 거리
- 네 번째 열: 클래스를 만드는 데 사용된 데이터 포인트의 개수
import pandas as pd
import numpy as np
import statsmodels.api as sm
covid = pd.read_csv('data/서울특별시_코로나19.csv')
covid1 = covid[covid.columns.difference(['Date'])]
def acf(x, n_lags):
return sm.tsa.stattools.acf(x, nlags=n_lags) # acf distance 계산
n_lags = 785 # 데이터 관측개수를 고려하여 785로 설정(?)
lag_arr = np.repeat(n_lags, covid1.shape[1])
acf_list = list(map(acf, covid1.transpose().to_numpy(), lag_arr)) # map(): 여러 개의 데이터를 받아서 각각의 요소에 함수를 적용한 결과를 반환하는 내장 함수
acf_df = pd.DataFrame(acf_list).transpose()
acf_df.columns = covid1.columns
print(acf_df)
acf_df = acf_df.T # 계층적 군집분석의 입력형태를 맞추기 위해 acf_df를 transpose함
print(acf_df.head())
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
plt.figure(figsize=(15,5))
label = acf_df.index
dend1 = sch.linkage(acf_df, method='average')
cutoff = 0.5 * max(dend1[:,2]) # 3번째 열을 선택하여 임계값 설정
dend_res1 = sch.dendrogram(dend1, color_threshold=cutoff, labels=label)
plt.show()

(2) 계층적 군집 분석을 위해 덴드로그램을 작성하시오.

→ 샘플 데이터 생성할 때 비슷한 로직으로 생성해서 루트 부분에 몰려 있는 형태인듯
3. 사회과학, 자연과학, 공학 세 개 학과의 평점조사표를 보고 학과와 성적이 관계있는지 검정하시오.

(1) 연구가설, 귀무가설을 작성하시오.
- 연구가설(H0): 성적과 학과 간에는 관련성이 없다
- 귀무가설(H1): 성적과 학과 간에는 관련성이 있다
(2) 학과와 성적이 독립일 때 기댓값을 구하시오.
import pandas as pd
from scipy import stats
사회 = [16, 30, 12]
자연 = [12, 20, 3]
공학 = [18, 13, 14]
table = pd.DataFrame({'사회과학': 사회, '자연과학': 자연, '공학': 공학}, index=['3.5-4.5', '2.5-3.5', '1.5-2.5'])
print(stats.chi2_contingency(observed=table))

→ 학업 성적이 학과와 독립일 때, 기대치는 array의 출력 값과 같음
(3) 검정통계량을 구하고 연구가설 채택 여부를 작성하시오.
→ chi-square 값은 10.199, p-value 값은 약 0.03이기 때문에 대립가설을 채택하므로, 성적과 학과 간에는 관련성이 있다
'데이터 분석 > ADP 자격증 공부' 카테고리의 다른 글
| [ADP 실기] 확률분포 계산 문제 (0) | 2026.04.06 |
|---|---|
| [ADP 실기] NPV(Net Present Value, 순현재가치), IRR 구하기 (0) | 2026.04.06 |
| (파이썬 한권으로 끝내기) 모의고사 제2회 소스코드, 샘플 데이터 (0) | 2026.04.06 |
| [ADP 실기] (테스트 완료, 학습 데이터) 파이썬 비정형 텍스트마이닝 1편 – 영문 전처리, 워드클라우드(nltk) (0) | 2026.04.06 |
| (파이썬 한권으로 끝내기) 모의고사 제1회 소스코드, 샘플 데이터 (0) | 2026.04.06 |