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