오랑우탄의 반란
[기초통계] 회귀 (파이썬) 본문
반응형
이전 포스트에 이어 기본적인 회귀 종류를 살펴보겠습니다.
단순선형회귀
- 독립변수 x와 종속변수 y 사이의 관계를 직선 형태로 모델링한 방법
- 데이터가 직선적 경향을 따를 때 사용, 간단하고 해석이 용이함
- 가지고 있지 않는 데이터에 대해 예측할 수 있음
- Y = β0 + β1X
- ex) 광고비x와 매출y의 관계 분석
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 예시 데이터 생성
np.random.seed(0)
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)
# 데이터 분할
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
# 단순선형회귀 모델 생성 및 훈련
model = LinearRegression()
model.fit(x_train, y_train)
# 예측
y_pred = model.predict(x_test)
# 회귀 계수 및 절편 출력
print("회귀 계수:", model.coef_)
print("절편:", model.intercept_)
# 모델 평가
mse = mean_squared_error(y_test, y_pred) #오차, 낮을수록 좋음
r2 = r2_score(y_test, y_pred) # 회귀의 설명력, 높을수록 좋음
print("평균 제곱 오차(MSE):", mse)
print("결정 계수(R2):", r2)
# 시각화
plt.scatter(x, y, color='blue')
plt.plot(x_test, y_pred, color='red', linewidth=2)
plt.title('linear regeression')
plt.xlabel('X : cost')
plt.ylabel('Y : sales')
plt.show()
mse는 오차 정도로, 낮을수록 좋으며 r2는 회귀의 설명력으로 높을수록 좋습니다.
다중선형회귀
- 2개 이상의 독립변수(x1, x2, x3, ..., xn)와 하나의 종속변수 y 간의 관계 모델링
- 종속변수에 여러 독립변수가 영향을 미치는 상황에 사용
- 다중공선성 Multicollinearity 문제 발생 가능
- 회귀분석에서 독립 변수들 간에 높은 상관관계가 있는 경우
- 다중공선성으로 인해 실제 중요한 변수가 통계적으로 유의하지 않게 나타날 수 있음
- 변수의 상관계수 확인 (0.7 이상), 분산 팽창 계수(VIF) 계산 (10 이상) = 다중공선성 높음
- 높은 계수의 변수 제거 or 주성분분석(PCS)과 같이 변수를 효과적으로 줄이는 차원 분석 방법 적용
- Y = β0 + β1X1 + β2X2 + ... + βnXn
- ex) 다양한 광고비와 매출 간의 관계 분석
# 예시 데이터 생성
data = {'TV': np.random.rand(100) * 100,
'Radio': np.random.rand(100) * 50,
'Newspaper': np.random.rand(100) * 30,
'Sales': np.random.rand(100) * 100}
df = pd.DataFrame(data)
# 독립 변수(X)와 종속 변수(Y) 설정
X = df[['TV', 'Radio', 'Newspaper']]
y = df['Sales']
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 다중선형회귀 모델 생성 및 훈련
model = LinearRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 회귀 계수 및 절편 출력
print("회귀 계수:", model.coef_)
print("절편:", model.intercept_)
# 모델 평가
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("평균 제곱 오차(MSE):", mse)
print("결정 계수(R2):", r2)
범주형변수
- 숫자가 아닌 문자로 이루어진 데이터
- 순서가 있는 경우(옷 사이즈, 수능 등급 등) vs 순서가 없는 경우 (성별, 지역 등)
- 순서 없는 데이터가 2개 밖에 없는 경우 임의의 숫자로 바로 변환, 3개 이상인 경우에는 무조건 원-핫 인코딩(하나만 1이고 나머지는 0인 벡터)변환→ pandas get_dummies
ex) 부산 = [1,0,0,0], 대전 = [0,1,0,0], 대구 = [0,0,1,0], 광주 = [0,0,0,1]
- 순서 없는 데이터가 2개 밖에 없는 경우 임의의 숫자로 바로 변환, 3개 이상인 경우에는 무조건 원-핫 인코딩(하나만 1이고 나머지는 0인 벡터)변환→ pandas get_dummies
- ex) 성별, 근무 경력과 연봉 간의 관계 분석 (성별이 범주형 요인변수) → 범주형 변수 더미로 변환 → 회귀 수행
# 예시 데이터 생성
data = {'Gender': ['Male', 'Female', 'Female', 'Male', 'Male'],
'Experience': [5, 7, 10, 3, 8],
'Salary': [50, 60, 65, 40, 55]}
df = pd.DataFrame(data)
# 범주형 변수 더미 변수로 변환
df = pd.get_dummies(df, drop_first=True) # 범주형 변수 개수 중 1개 빼는 것
# 독립 변수(X)와 종속 변수(Y) 설정
X = df[['Experience', 'Gender_Male']]
y = df['Salary']
# 단순선형회귀 모델 생성 및 훈련
model = LinearRegression()
model.fit(X, y)
# 예측
y_pred = model.predict(X)
# 회귀 계수 및 절편 출력
print("회귀 계수:", model.coef_)
print("절편:", model.intercept_)
# 모델 평가
mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print("평균 제곱 오차(MSE):", mse)
print("결정 계수(R2):", r2)
df = pd.get_dummies(df, drop_first=True) 에서 drop_first=True 로 변수 1개를 빼도 무관하기 때문에 빼줍니다.
마치 if 문에서 마지막 else 에 굳이 조건을 추가하지 않고 나머지로 묶는 것과 비슷한 이유지요.
또한 다중공선성 문제도 완화해줍니다.
다항회귀, 스플라인회귀
다항회귀
- 독립변수와 종속변수 간의 관계가 선형이 아닐 때 (데이터가 곡선적 경향을 따를 때) 사용
- 고차 다항식의 경우 과적합 overfitting 위험(너무 과하게 그려짐)이 있음
- Y = β0 + β1X + β2X^2
- ex) 주택 가격 예측 (면적과 가격 간의 비선형 관계)
스플라인 회귀
- 독립변수의 구간별로 다른 회귀식을 적용해 복잡한 관계 모델링
- 일반적인 경향성이 보이지 않고 데이터가 국부적으로 다른 패턴 보일 때 사용
- 적절한 매듭점 knots 의 선택이 중요
- ex) 주식차트
from sklearn.preprocessing import PolynomialFeatures
# 예시 데이터 생성
np.random.seed(0)
X = 2 - 3 * np.random.normal(0, 1, 100)
y = X - 2 * (X ** 2) + np.random.normal(-3, 3, 100) # 2차식
X = X[:, np.newaxis]
# 다항 회귀 (2차)
polynomial_features = PolynomialFeatures(degree=2) # 2차
X_poly = polynomial_features.fit_transform(X)
model = LinearRegression()
model.fit(X_poly, y)
y_poly_pred = model.predict(X_poly)
# 모델 평가
mse = mean_squared_error(y, y_poly_pred)
r2 = r2_score(y, y_poly_pred)
print("평균 제곱 오차(MSE):", mse)
print("결정 계수(R2):", r2)
# 시각화
plt.scatter(X, y, s=10)
# 정렬된 X 값에 따른 y 값 예측
sorted_zip = sorted(zip(X, y_poly_pred))
X, y_poly_pred = zip(*sorted_zip)
plt.plot(X, y_poly_pred, color='m')
plt.title('polynomial regerssion')
plt.xlabel('area')
plt.ylabel('price')
plt.show()
이상 회귀의 몇 가지 종류 관련해서 살펴봤습니다.
다음 포스트에서는 상관관계에 대해 알아보겠습니다.
오랑우탄이 영어를 하고 오랑이가 데이터분석가가 되는 그날까지~
반응형
'PYTHON > 데이터분석' 카테고리의 다른 글
[기초통계] 가설검정의 주의점 (파이썬) (0) | 2024.08.02 |
---|---|
[기초통계] 상관관계 (파이썬) (0) | 2024.08.02 |
[기초통계] 유의성검정 (파이썬) (0) | 2024.08.01 |
[기초통계] 데이터 분포 시각화 (파이썬) (0) | 2024.08.01 |
[기초통계] 통계 기초 개념 시각화 (파이썬) (0) | 2024.08.01 |