데이터 분석/통계

선형 회귀 모델

fullfish 2025. 10. 31. 16:40
import pandas as pd
import numpy as np

# 그래프 라이브러리
import matplotlib.pyplot as plt
import seaborn as sns

# 회귀 라이브러리
from sklearn.linear_model import LinearRegression # 선형회귀 모델
import statsmodels.api as sm # 통계 해석
from sklearn.metrics import r2_score # R2 성능지표

1. 선형회귀 모델의 이해
# 보험료 (charges) 예측 선형회귀 모델 만들기

# 보험료 데이터 불러오기
df_ins = pd.read_csv('/content/drive/MyDrive/multicampus/시각화/data/insurance.csv')
df_ins.head()

# X: 피쳐, 독립변수, 설명변수
# y: 종속변수, 관심변수, 타깃

y = df_ins['charges']

# 우선 수치형 변수들만 피쳐로(범주형 변수는 나중에 인코딩해서 넣을 예정)
X = df_ins[['age','bmi','children','period']]

# 모델 선언
model=LinearRegression()

# 모델에 데이터 적합(학습)
model.fit(X,y)

# 회귀계수, 절편
print(model.coef_)
print(model.intercept_)

# 보험료 예측: 25살, bmi가 33, 자녀 수가 2명, 보험기간은 4.5
model.predict([[25,33,2,4.5]])

# 모델 성능: R2
y_pred= model.predict(X)
r2_score(y,y_pred) # 0.12025303515697039

# 성능이 안 좋은 이유는, 범주형 변수들이 빠져있기 때문

'''
R² < 0.3 → 설명력이 매우 낮음 (모델이 데이터를 거의 설명 못 함)
0.3 ≤ R² < 0.5 → 약한 설명력 (패턴은 약간 잡지만 오차 큼)
0.5 ≤ R² < 0.7 → 중간 정도 (모델이 절반 이상은 설명)
0.7 ≤ R² < 0.9 → 꽤 좋은 편 (현실적 예측력)
R² ≥ 0.9 → 매우 좋음 (거의 완벽에 가까움)'''

2.변수 선택과 모델 성능
2-1 범주형 변수의 수치화
# 원핫 인코딩(one-hot encoding) -> 1또는 0으로 바뀜
df_dummies = pd.get_dummies(data=df_ins, dtype='int', drop_first=True)
df_dummies.head() # 내용 보면 type A가 없어진 이유는 B와 C만 있어도 알 수 있기 떄문에

# 독립변수(피쳐)와 종속변수 선언
y = df_dummies['charges']
X = df_dummies.drop(columns=['charges']) # charges를 제외한 나머지 변수를 독립변수

# 선형회귀 모델 적합(fit)
linear_model = LinearRegression(fit_intercept=True)
linear_model.fit(X,y)

# 회귀계수, 절편 확인
print(linear_model.coef_)
print(linear_model.intercept_)  

# 모델 성능: R2
y_pred= linear_model.predict(X)
r2_score(y,y_pred)

2-2 선형회귀 모델 통계적 해석
# 선형회귀 모델 적합
ls = sm.OLS(y, X_sm).fit()
ls.summary()
'''
OLS Regression Results
Dep. Variable:	charges	R-squared:	0.716
Model:	OLS	Adj. R-squared:	0.714
Method:	Least Squares	F-statistic:	308.1
Date:	Fri, 31 Oct 2025	Prob (F-statistic):	0.00
Time:	08:22:11	Log-Likelihood:	-13772.
No. Observations:	1353	AIC:	2.757e+04
Df Residuals:	1341	BIC:	2.763e+04
Df Model:	11		
Covariance Type:	nonrobust		
coef	std err	t	P>|t|	[0.025	0.975]
const	-1.207e+04	1169.484	-10.319	0.000	-1.44e+04	-9774.013
age	250.8880	12.549	19.992	0.000	226.270	275.506
bmi	345.8472	30.745	11.249	0.000	285.534	406.160
children	463.5501	145.420	3.188	0.001	178.275	748.826
period	71.1445	87.343	0.815	0.415	-100.200	242.489
sex_male	-210.9795	350.370	-0.602	0.547	-898.312	476.353
smoker_yes	2.273e+04	430.472	52.805	0.000	2.19e+04	2.36e+04
region_northwest	-396.3045	507.073	-0.782	0.435	-1391.047	598.438
region_southeast	-1750.5860	506.397	-3.457	0.001	-2744.002	-757.170
region_southwest	-1008.1375	505.478	-1.994	0.046	-1999.751	-16.524
ins_type_B	77.0063	431.504	0.178	0.858	-769.491	923.503
ins_type_C	228.3587	429.395	0.532	0.595	-614.001	1070.718
Omnibus:	217.162	Durbin-Watson:	2.152
Prob(Omnibus):	0.000	Jarque-Bera (JB):	537.770
Skew:	0.873	Prob(JB):	1.68e-117
Kurtosis:	5.548	Cond. No.	352.


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.'''

# 보면 smoker_yes가 coef도 크고 p-value가 작아서 영향을 많이 미침을 알 수 있음
X = df_dummies.drop(columns=['charges','smoker_yes']) # smoker_yes 뺴봄
# 선형회귀 모델 적합(fit)
linear_model = LinearRegression(fit_intercept=True)
linear_model.fit(X,y)
y_pred= linear_model.predict(X)
r2_score(y,y_pred) # 0.12701578689708792
# 성능이 떨어짐을 알 수 있음

[실습] grade 예측 선형회귀 모델링
df_work = pd.read_csv('/content/drive/MyDrive/multicampus/시각화/data/work_grade.csv')
df_work.head()

# 범주형 변수를 수치형 변수로 원핫 인코딩
df_dummies = pd.get_dummies(data=df_work, dtype='int', drop_first=True)
df_dummies.head()

# 독립션수/종속변수 선언
y = df_dummies['grade']
X = df_dummies.drop(columns=['grade'])
X

X_sm = sm.add_constant(X) # 모델에 상수항 추가
X_sm

ls = sm.OLS(y,X_sm).fit()
ls.summary()

'''
OLS Regression Results
Dep. Variable:	grade	R-squared:	0.776
Model:	OLS	Adj. R-squared:	0.754
Method:	Least Squares	F-statistic:	36.46
Date:	Fri, 31 Oct 2025	Prob (F-statistic):	4.76e-27
Time:	08:44:48	Log-Likelihood:	-3.0869
No. Observations:	105	AIC:	26.17
Df Residuals:	95	BIC:	52.71
Df Model:	9		
Covariance Type:	nonrobust		
coef	std err	t	P>|t|	[0.025	0.975]
const	-0.0954	0.377	-0.253	0.801	-0.845	0.654
ID	-0.0009	0.001	-0.988	0.326	-0.003	0.001
work_hour	0.0018	0.000	8.744	0.000	0.001	0.002
sex_male	0.0721	0.052	1.393	0.167	-0.031	0.175
department_B	-0.0927	0.064	-1.441	0.153	-0.220	0.035
department_C	-0.0012	0.064	-0.018	0.986	-0.129	0.127
achievement_many	0.4545	0.085	5.354	0.000	0.286	0.623
achievement_medium	0.1921	0.075	2.576	0.012	0.044	0.340
achievement_so many	0.7787	0.081	9.576	0.000	0.617	0.940
achievement_very little	-0.3862	0.087	-4.438	0.000	-0.559	-0.213
Omnibus:	27.495	Durbin-Watson:	1.748
Prob(Omnibus):	0.000	Jarque-Bera (JB):	61.036
Skew:	-0.986	Prob(JB):	5.57e-14
Kurtosis:	6.172	Cond. No.	2.69e+04


Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 2.69e+04. This might indicate that there are
strong multicollinearity or other numerical problems.'''