728x90
728x90

제7회 기출 변형 문제 (제3유형)

들어가며

  • 빅데이터분석기사 실기 제7회 제3유형 기출 변형 문제를 올려본다.
  • 제7회 제3유형에서는 고급 통계(회귀 분석)과 관련된 문제가 출제되었다.

 

참고

  • 회귀 분석에서는 귀무 가설대립 가설이 다음과 같이 설정된다.
    • 따라서 유의하지 않은 변수를 구하려면 귀무 가설을 채택(p-value > 0.05(유의수준))하는 변수를 선택하면 된다.
귀무 가설 : 해당 변수는 종속 변수에 미치는 영향력이 없다. (유의하지 않다.)
대립 가설 : 해당 변수는 종속 변수에 미치는 영향력이 있다. (유의하다.)

 

  • 로지스틱 회귀 분석statsmodels.api.Logit(y, X) 함수를 사용하고, 다중 선형 회귀 분석statsmodels.api.OLS(y, X) 함수를 사용한다.
  • p-value 값result.pvalues로, 회귀 계수(Coefficient) 값result.params을 통해 확인할 수 있다.
  • 오즈비(Odds Ratio)np.exp(result['변수'])를 이용하여 구할 수 있다.
    • 변수의 크기가 N 증가할 때, 오즈비(Odds Ratio)np.exp(N * np.exp(result['변수'])) 배수만큼 증가한다.
  • 로지스틱 회귀 분석에서 잔차 이탈도(Residual Deviance)GLM(Generalized Linear Model)을 통해 확인할 수 있다.
    • statsmodels.api.GLM(y, X, family=sm.families.Binomial())

 

사용 예시 코드
import numpy as np
import pandas as pd
import statsmodels.api as sm
df = pd.read_csv('./datasets/dataset.csv')
# 각 변수 간의 상관 계수 확인 하기
corr_df = df.corr(numeric_only=True)
print(corr_df)
""" 출력 예시
v1 v2 v3 v4 v5 Target
v1 1.000000 -0.066107 -0.036512 0.021895 -0.005389 0.872265
v2 -0.066107 1.000000 -0.124047 -0.061987 -0.114401 -0.383313
v3 -0.036512 -0.124047 1.000000 -0.115117 0.062719 0.310146
v4 0.021895 -0.061987 -0.115117 1.000000 0.033356 -0.011590
v5 -0.005389 -0.114401 0.062719 0.033356 1.000000 0.036221
Target 0.872265 -0.383313 0.310146 -0.011590 0.036221 1.000000
"""
##
## ===========================================================================
##
X = df[['변수1', '변수2', ...]] # 독립 변수
X = sm.add_constant(X) # 상수항 추가
y = df[['변수1']] # 종속 변수
# ✅ 로지스틱 회귀
model = sm.Logit(y, X).fit()
# Summary 확인
summary = model.summary()
""" 출력 예시
Logit Regression Results
==============================================================================
Dep. Variable: y_logit No. Observations: 100
Model: Logit Df Residuals: 96
Method: MLE Df Model: 3
Date: Fri, 15 Nov 2024 Pseudo R-squ.: 0.01884
Time: 02:25:50 Log-Likelihood: -66.748
converged: True LL-Null: -68.029
Covariance Type: nonrobust LLR p-value: 0.4640
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
const 1.5921 1.624 0.980 0.327 -1.591 4.775
X1 -0.0368 0.024 -1.540 0.124 -0.084 0.010
X2 -0.0020 0.015 -0.136 0.892 -0.031 0.027
X3 -4.16e-05 0.010 -0.004 0.997 -0.019 0.019
==============================================================================
"""
# ✅ 다중 선형 회귀
model = sm.OLS(y, X).fit()
# Summary 확인
summary = model.summary()
""" 출력 예시
OLS Regression Results
==============================================================================
Dep. Variable: y_ols R-squared: 0.989
Model: OLS Adj. R-squared: 0.988
Method: Least Squares F-statistic: 2795.
Date: Fri, 15 Nov 2024 Prob (F-statistic): 2.99e-93
Time: 02:25:50 Log-Likelihood: -304.81
No. Observations: 100 AIC: 617.6
Df Residuals: 96 BIC: 628.0
Df Model: 3
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 4.2031 4.072 1.032 0.305 -3.880 12.286
X1 1.9530 0.059 32.994 0.000 1.836 2.071
X2 2.9656 0.037 80.338 0.000 2.892 3.039
X3 -0.9938 0.025 -40.439 0.000 -1.043 -0.945
==============================================================================
Omnibus: 2.128 Durbin-Watson: 1.690
Prob(Omnibus): 0.345 Jarque-Bera (JB): 1.502
Skew: -0.040 Prob(JB): 0.472
Kurtosis: 2.405 Cond. No. 836.
==============================================================================
"""
# p-value 확인
p_values = model.pvalues
""" 출력 예시
const 3.045914e-01
X1 3.508077e-54
X2 7.613901e-90
X3 4.249762e-62
dtype: float64
"""
# 회귀 계수(coef) 확인
coefficients = model.params
""" 출력 예시
const 4.203092
X1 1.953025
X2 2.965557
X3 -0.993764
dtype: float64
"""
# 결정 계수(R-Squared) 확인
r_squared = model.rsquared
""" 출력 예시
0.046868286704138895
"""
# 로짓 우도값(Log-Likelihood) 확인
log_likelihood = model.llf
""" 출력 예시
-135.22741810901363
"""
# 오즈비(Odds Ratio) 구하기
odds_ratio = np.exp(model.params['변수'])
""" 출력 예시
0.072313213120958013
"""
# 잔차 이탈도(Residual Deviance) 확인
model = sm.GLM(y, X, family=sm.families.Binomial()).fit() # ✅ GLM(Generalized Linear Model) 모델링, Bionomial : 로지스틱 회귀
# Summary 확인
summary = model.summary()
""" 출력 예시
Generalized Linear Model Regression Results
==============================================================================
Dep. Variable: target No. Observations: 200
Model: GLM Df Residuals: 194
Model Family: Binomial Df Model: 5
Link Function: Logit Scale: 1.0000
Method: IRLS Log-Likelihood: -135.23
Date: Sat, 16 Nov 2024 Deviance: 270.45
Time: 20:07:33 Pearson chi2: 200.
No. Iterations: 4 Pseudo R-squ. (CS): 0.004967
Covariance Type: nonrobust
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
const -0.9495 1.424 -0.667 0.505 -3.740 1.841
age 0.0011 0.010 0.107 0.915 -0.019 0.021
chol 0.0012 0.003 0.370 0.712 -0.005 0.008
trestbps 0.0029 0.006 0.470 0.638 -0.009 0.015
thalach -0.0019 0.005 -0.376 0.707 -0.012 0.008
oldpeak 0.0549 0.102 0.537 0.591 -0.145 0.255
==============================================================================
"""
residual_deviance = model.deviance
""" 출력 예시
270.45483621802725
"""

 

문제 1

(1) 선형 관계 가장 큰 변수 찾아 상관 계수(Correlation Coefficient) 구하기

(2) Target 변수를 종속 변수로 하여 다중 선형 회귀 모델링을 진행했을 때 v2 컬럼의 회귀 계수(Coefficient) 구하기

(3) 회귀 계수들이 가지는 p-값들 중 최대값 구하기

import pandas as pd
import numpy as np
import statsmodels.api as sm
# 가상 데이터 생성
np.random.seed(0) # 재현성을 위해 시드 설정
n_samples = 100
# 독립 변수(v1 ~ v5) 및 종속 변수(Target) 생성
data = {
'v1': np.random.rand(n_samples) * 100,
'v2': np.random.rand(n_samples) * 50,
'v3': np.random.rand(n_samples) * 200,
'v4': np.random.rand(n_samples) * 80,
'v5': np.random.rand(n_samples) * 10,
}
# Target 변수는 v1, v2, v3에 영향을 받도록 생성
data['Target'] = (
3 * data['v1'] - 2 * data['v2'] + 0.5 * data['v3'] +
np.random.randn(n_samples) * 20 # 노이즈 추가
)
# DataFrame으로 변환
df = pd.DataFrame(data)
# (1) 선형 관계 가장 큰 변수 찾아 상관 계수 구하기
corr_df = df.corr(numeric_only=True)
print(corr_df)
target_corr = corr_df['Target']
most_correlated_variable = target_corr.sort_values(ascending=False)[1] # 'Target' 제외한 가장 높은 상관 변수
print(f"(1) 선형 관계 가장 큰 변수의 상관 계수: {most_correlated_variable:.4f}")
# (2) Target 변수를 종속 변수로 하여 다중 선형 회귀 모델링을 진행했을 때 v2 컬럼의 회귀 계수 구하기
x = df.drop('Target', axis=1)
x = sm.add_constant(x) # 상수항 추가
y = df['Target']
# 다중 선형 회귀 분석 모델 생성
model = sm.OLS(y, x).fit()
summary = model.summary()
print(summary)
v2_coef = model.params['v2']
print(f"(2) v2 변수의 회귀 계수: {v2_coef:.4f}")
# (3) 회귀 계수들이 가지는 p-값들 중 최대값 구하기
max_pvalue = model.pvalues.max()
print(f"(3) 회귀 계수의 p-값 중 최대값: {max_pvalue:.4f}")
v1 v2 v3 v4 v5 Target
v1 1.000000 -0.066107 -0.036512 0.021895 -0.005389 0.872265
v2 -0.066107 1.000000 -0.124047 -0.061987 -0.114401 -0.383313
v3 -0.036512 -0.124047 1.000000 -0.115117 0.062719 0.310146
v4 0.021895 -0.061987 -0.115117 1.000000 0.033356 -0.011590
v5 -0.005389 -0.114401 0.062719 0.033356 1.000000 0.036221
Target 0.872265 -0.383313 0.310146 -0.011590 0.036221 1.000000
(1) 선형 관계 가장 큰 변수의 상관 계수: 0.8723
OLS Regression Results
==============================================================================
Dep. Variable: Target R-squared: 0.960
Model: OLS Adj. R-squared: 0.957
Method: Least Squares F-statistic: 447.0
Date: Sat, 16 Nov 2024 Prob (F-statistic): 7.20e-64
Time: 19:42:11 Log-Likelihood: -443.47
No. Observations: 100 AIC: 898.9
Df Residuals: 94 BIC: 914.6
Df Model: 5
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 3.2852 9.174 0.358 0.721 -14.929 21.500
v1 3.0453 0.073 41.575 0.000 2.900 3.191
v2 -2.1320 0.155 -13.754 0.000 -2.440 -1.824
v3 0.5132 0.036 14.452 0.000 0.443 0.584
v4 -0.0582 0.093 -0.624 0.534 -0.244 0.127
v5 -0.3720 0.705 -0.528 0.599 -1.771 1.027
==============================================================================
Omnibus: 2.625 Durbin-Watson: 1.810
Prob(Omnibus): 0.269 Jarque-Bera (JB): 2.212
Skew: -0.361 Prob(JB): 0.331
Kurtosis: 3.101 Cond. No. 577.
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
(2) v2 변수의 회귀 계수: -2.1320
(3) 회귀 계수의 p-값 중 최대값: 0.7211

 

더보기

(1) 각 변수간 상관 계수는 dataframe.corr() 메서드를 이용하여 확인할 수 있다. Target과 가장 높은 선형 관계를 가진 변수는 v1이며, 상관 계수는 약 0.7966이다.

(2) Target종속 변수로 하고 나머지 변수를 독립 변수로 설정했을 때, v2의 회귀 계수는 약 -2.0841이다. 이때, 상수항을 포함시켜서 구한다.

(3) 회귀 분석 결과 중 p-값이 가장 큰 것은 0.7643으로, 유의 수준 0.05보다 크다. (귀무 가설(해당 변수는 종속 변수에 미치는 영향이 없다.) 채택) 따라서 독립 변수가 통계적으로 유의미하지 않을 가능성이 높다.

 

문제 2

(1) train 데이터로 target을 종속 변수로 로지스틱 회귀를 진행할 때, age 컬럼의 오즈비(Odds Ratio) 구하기

(2) train 데이터로 로지스틱 회귀를 진행했을 경우 잔차 이탈도(Residual Deviance) 계산하기

(3) train 데이터로 로지스틱 회귀를 진행했을 경우 로짓 우도값(Log-Likelihood) 도출하기

(4) test 데이터의 독립 변수로 target 예측 후 오류율(Error Rate) 구하기

import numpy as np
import pandas as pd
import statsmodels.api as sm
from sklearn.metrics import accuracy_score, confusion_matrix
# 가상의 데이터 생성
np.random.seed(42)
n_samples = 300
data = {
'age': np.random.randint(30, 80, n_samples), # 나이 (30~80세)
'chol': np.random.randint(150, 300, n_samples), # 콜레스테롤 수치 (150~300)
'trestbps': np.random.randint(100, 180, n_samples), # 안정 시 혈압 (100~180)
'thalach': np.random.randint(100, 200, n_samples), # 최대 심박수 (100~200)
'oldpeak': np.random.uniform(0, 5, n_samples), # ST depression induced by exercise
'target': np.random.binomial(1, 0.4, n_samples) # 심장병 발병 여부 (0 또는 1, 40% 확률)
}
df = pd.DataFrame(data)
# train/test 데이터 분할
train_data = df[:200].reset_index(drop=True)
test_data = df[200:].reset_index(drop=True)
# [1] train 데이터로 로지스틱 회귀 분석 수행
X = train_data.drop('target', axis=1) # 독립 변수
X = sm.add_constant(X) # 상수항 추가
y = train_data['target'] # 종속 변수
# 로지스틱 회귀 모델 생성
model1 = sm.Logit(y, X).fit()
summary1 = model1.summary()
print(summary1)
# (1) 오즈비 계산 (age)
answer1 = np.exp(model1.params['age'])
print("(1) 오즈비 (age):", answer1)
# (2) 잔차 이탈도 계산
model2 = sm.GLM(y, X, family=sm.families.Binomial()).fit() # GLM(Generalized Linear Models) 모델링, Bionomial : 로지스틱 회귀
summary2 = model2.summary()
print(summary2)
answer2 = model2.deviance
print("(2) 잔차 이탈도:", answer2)
# (3) 로짓 우도값(Log-Likelihood) 계산
answer3 = model1.llf
print("(3) 로짓 우도값:", answer3)
# (4) test 데이터로 target 예측 후 오류율(Error Rate) 계산
X_test = test_data.drop('target', axis=1)
X_test = sm.add_constant(X_test) # 상수항 추가
y_test = test_data['target']
pred = model1.predict(X_test)
## 방법 1 (1 - Accuracy 구하기)
pred = (pred > 0.5).astype(int) # 예측된 확률값을 0.5 기준으로 이진 분류하여 변환 (0.5 초과 : 1, 0.5 이하 : 0)
error_rate = 1 - accuracy_score(y_test, pred) # Error Rate = 1 - Accuracy
# print("(4) 오류율:", error_rate)
## 방법 2 (혼동 행렬 이용하기)
cm = confusion_matrix(y_test, pred)
# 오류율 계산
error_rate = (cm[0, 1] + cm[1, 0]) / cm.sum() # 오차 행렬에서 오답의 합을 전체로 나누기
print("(4) 오류율:", error_rate)
Optimization terminated successfully.
Current function value: 0.676137
Iterations 4
Logit Regression Results
==============================================================================
Dep. Variable: target No. Observations: 200
Model: Logit Df Residuals: 194
Method: MLE Df Model: 5
Date: Sat, 16 Nov 2024 Pseudo R-squ.: 0.003669
Time: 20:29:45 Log-Likelihood: -135.23
converged: True LL-Null: -135.73
Covariance Type: nonrobust LLR p-value: 0.9629
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
const -0.9495 1.424 -0.667 0.505 -3.740 1.841
age 0.0011 0.010 0.107 0.915 -0.019 0.021
chol 0.0012 0.003 0.370 0.712 -0.005 0.008
trestbps 0.0029 0.006 0.470 0.638 -0.009 0.015
thalach -0.0019 0.005 -0.376 0.707 -0.012 0.008
oldpeak 0.0549 0.102 0.537 0.591 -0.145 0.255
==============================================================================
(1) 오즈비 (age): 1.001112327790342
Generalized Linear Model Regression Results
==============================================================================
Dep. Variable: target No. Observations: 200
Model: GLM Df Residuals: 194
Model Family: Binomial Df Model: 5
Link Function: Logit Scale: 1.0000
Method: IRLS Log-Likelihood: -135.23
Date: Sat, 16 Nov 2024 Deviance: 270.45
Time: 20:29:45 Pearson chi2: 200.
No. Iterations: 4 Pseudo R-squ. (CS): 0.004967
Covariance Type: nonrobust
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
const -0.9495 1.424 -0.667 0.505 -3.740 1.841
age 0.0011 0.010 0.107 0.915 -0.019 0.021
chol 0.0012 0.003 0.370 0.712 -0.005 0.008
trestbps 0.0029 0.006 0.470 0.638 -0.009 0.015
thalach -0.0019 0.005 -0.376 0.707 -0.012 0.008
oldpeak 0.0549 0.102 0.537 0.591 -0.145 0.255
==============================================================================
(2) 잔차 이탈도: 270.45483621802725
(3) 로짓 우도값: -135.22741810901363
(4) 오류율: 0.4

 

더보기

(1) 변수의 오즈비(Odds Ratio)np.exp(df['변수'])와 같이 구할 수 있다. 

(2) 로지스틱 회귀를 진행할 때, 잔차 이탈도(Residual Deviance)GLM(Generalized Linear Model) 모델링을 통해 확인할 수 있다. (sm.GLM(y, X)) summary 함수를 이용하여 결과값을 출력한 후, Deviance 항목의 값을 확인하면 된다.

(3) 로지스틱 회귀를 진행할 때, 로짓 우도값(Log-Likelihood)은  sm.Logit(y, X) 모델링 후 summary 함수를 이용하여 결과값을 출력한 후, Log-Likelihood 항목의 값을 확인하면 된다.

(4) 우선, 테스트 데이터의 독립 변수와 종속 변수를 분리한다. 그리고 훈련 데이터를 이용하여 미리 생성한 로지스틱 회귀 모델(model1)에 테스트 데이터의 독립 변수를 넣어준 후 예측해준다. (pred = model1.predict(X_test)) <오류율(Error Rate) = 1 - 정확도(Accuracy Score)>이므로 직접 구해주거나(방법①) 혼동 행렬(Confusion Matrix)을 이용(방법②)하여 구해준다.

 

(참고) GLM(Generalized Linear Models)

개념

  • 일반화된 선형 모델
  • 선형 회귀, 로지스틱 회귀, 포아송 회귀 등 다양한 회귀 모델하나의 프레임워크에서 처리할 수 있게 해주는 클래스

 

사용 예시

  • sm.GLM 클래스를 통해 다양한 회귀 모델을 피팅할 수 있다.

 

예시 코드 : 로지스틱 회귀
import statsmodels.api as sm
# 모델 정의
model = sm.GLM(y, X, family=sm.families.Binomial())
result = model.fit()
# 결과 출력
print(result.summary())
Generalized Linear Model Regression Results
==============================================================================
Dep. Variable: target No. Observations: 200
Model: GLM Df Residuals: 194
Model Family: Binomial Df Model: 5
Link Function: Logit Scale: 1.0000
Method: IRLS Log-Likelihood: -135.23
Date: Sat, 16 Nov 2024 Deviance: 270.45
Time: 20:29:45 Pearson chi2: 200.
No. Iterations: 4 Pseudo R-squ. (CS): 0.004967
Covariance Type: nonrobust
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
const -0.9495 1.424 -0.667 0.505 -3.740 1.841
age 0.0011 0.010 0.107 0.915 -0.019 0.021
chol 0.0012 0.003 0.370 0.712 -0.005 0.008
trestbps 0.0029 0.006 0.470 0.638 -0.009 0.015
thalach -0.0019 0.005 -0.376 0.707 -0.012 0.008
oldpeak 0.0549 0.102 0.537 0.591 -0.145 0.255
==============================================================================

 

Log-Likelihood : 로짓 우도

Deviance : 잔차 이탈도

 

family 파라미터
  • 모델이 따르는 확률 분포를 지정한다.
파라미터 값 설명
sm.families.Binomial() 로지스틱 회귀 (이항 분포)
sm.families.Poisson() 포아송 회귀 (카운트 데이터)
sm.families.Gaussian() 일반 선형 회귀 (연속형 종속 변수)
sm.familes.Gamma() 감마 분포 (양의 연속형 데이터)

 

참고 사이트

  • 보다 자세한 내용은 아래의 공식 문서를 확인한다.
 

Generalized Linear Models - statsmodels 0.14.4

Generalized Linear Models Generalized linear models currently supports estimation using the one-parameter exponential families. See Module Reference for commands and arguments. Examples # Load modules and data In [1]: import statsmodels.api as sm In [2]: d

www.statsmodels.org

 

728x90
728x90

제7회 기출 변형 문제 (제3유형)들어가며 참고문제 1문제 2(참고) GLM(Generalized Linear Models)개념사용 예시참고 사이트