EDA & 데이터 분석/통계

통계학 4주차[회귀]

edcrfv458 2025. 1. 17. 14:03

목표

  1. 회귀가 무엇인지 이해
  2. 다양한 회귀의 종류에 대해 설명하고 특징 이해

 

회귀(Regression): 값을 예측할 때 사용

선형 회귀: 직선에 가까운 형태


4.1 단순선형회귀: 한 개의 변수에 의한 결과를 예측

  • 하나의 독립 변수(X)와 하나의 종속 변수(Y) 간의 관계를 직선으로 모델링하는 방법
  • 회귀식
    • y = ax + b이며 b는 절편, a는 기울기
  • 특징
    • 독립 변수의 변화에 따라 종속 변수가 어떻게 변화하는지 설명하고 예측
    • 데이터가 직선적 경향을 따를 때 사용
  • 간단하고 해석이 용이

 

실습: 광고비와 매출 간의 관계 분석

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.codf_, '\n', model.intercept_)

# 모델 평가
mse = mean_squared_error(X_test, y_pred)
r2 = r2_score(y_test, y_pred)
print('평균 제곱 오차: ', mse)
print('결정 계수(R2): ', r2)

# 시각화
plt.scatter(X, y, color='blue')
plt.plot(X_test, y_pred, color='red', linewidth=2)
plt.title('linear regression')
plt.xlabel('X: cost')
plt.ylabel('Y: sales')
plt.show()

4.2 다중선형회귀: 두 개 이상의 변수에 의한 결과를 예측

  • 두 개 이상의 독립 변수(X1, X2, ..., Xn)와 하나의 종속 변수(Y) 간의 관계를 모델링
  • 회귀식
    • y = b0 + b1*x1 + b2*x2 + ... +bm*xn
  • 특징
    • 여러 독립 변수의 변화를 고려해 종속 변수 설명하고 예측
    • 종속 변수에 영향을 미치는 여러 독립 변수 존재할때 사용
    • 여러 변수의 영향을 동시에 분석 가능
    • 변수들 간의 다중공선성 문제가 발생 여부 있음
  • 다중공선성: 독립 변수들 간에 높은 상관관계가 있는 경우
    • 회귀분석 모델의 성능과 해석에 여러 문제를 일으킴
      • 독립 변수들이 강하게 상관되어 있으면, 각 변수의 개별적인 효과를 분리해내기 어려워 회귀의 해석이 어려워짐
      • 다중공선성으로 인해 실제 중요한 변수가 통계적으로 유의하게 나타나지 않을 수 있음
  • 진단법
    • 상관관계를 계산해 상관관계가 높은 변수들이 있는지 확인
    • 더 정확한 방법으로는 분산팽창계수(VIF)를 계산하고 VIF 값이 10보다 높은지 확인하는 방법
  • 해결방법
    • 높은 계수 가진 변수 중 하나를 제거
    • 주성분 분석(PCA)과 같은 변수들을 효과적으로 줄이는 차원 줄이는 차원 분석 방법 적용

 

실습: 다양한 광고비와 매출 간의 관계 분석

# 예시 데이터 생성
data = {'TV': np.random.rand(100) * 100,
		'Radio': np.random.rand(100) * 50,
        'Newspaper': np.ranodm.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.codf_, '\n', model.intercept_)	# 회귀 계수가 변수의 개수만큼 나옴

# 모델 평가
mse = mean_squared_error(X_test, y_pred)
r2 = r2_score(y_test, y_pred)
print('평균 제곱 오차: ', mse)
print('결정 계수(R2): ', r2)

4.3 범주형변수: 수치형 데이터가 아닌 주로 문자형 데이터로 이루어져 있는 변수

  • 회귀에서 범주형 변수의 경우 특별히 변환을 해줘야 함
    • 예를 들어 성별, 지역 등이 있으며 더미 변수로 변환하여 회귀 분석에 사용
  1. 순서가 있는 범주형 변수
    1. 옷의 사이즈(M, L, ...), 수능 등급(1등급, 2등급, ...)과 같이 범주형 변수라도 순서가 있는 변수에 해당
    2. 이런 경우 각 문자를 순서가 잘 반영 될 수 있게 숫자로 변환해도 문제가 없음
  2. 순서가 없는 범주형 변수
    1. 성별(남, 여), 지역(부산, 대구, 대전, ...)과 같이 순서가 없는 변수에 해당
    2. 2개 밖에 없는 경우 임의의 숫자로 변환해도 문제가 없음
    3. 3개 이상인 경우에는 무조건 원-핫 인코딩(하나만 1, 나머지 0인 벡터) 변환을 해줘야 함 ➡️ pandas의 get_dummies 활용

 

실습: 성별/근무 경력과 연봉 간의 관계

# 예시 데이터 생성
data = {'Gender': ['Male', 'Female', 'Female', 'Male'],
		'Experience': [5, 7, 10, 3],
        'Salary': [50, 60, 65, 40]}
df = pd.DataFrame(data)

# 범주형 변수 더미 변수로 변환
df = pd.get_dummies(df, drop_first=True)
	# 원래는 Gender_Female 컬럼도 생겨야 하지만, drop_first=True로 한 컬럼은 뺌
	# 또 이렇게 한 컬럼을 뺴는 것이 다중공선성 문제도 어느정도 해결이 됨
	# Gender_Male 컬럼 생기고 Male인 경우 True, Female인 경우 False

# 독립 변수(X)와 종속 변수(Y) 설정
X = df[['Experience', 'Gender_Male']]
y = df['Salary']

# 다중선형회귀 모델 생성 및 훈련
model = LinearRegression()
model.fit(X, y)

# 예측
y_pred = model.predict(X)

# 회귀 계수 및 절편
print(model.codf_, '\n', model.intercept_)

# 모델 평가
mse = mean_squared_error(y, y_pred)
r2 = r2_score(y, y_pred)
print('평균 제곱 오차: ', mse)
print('결정 계수(R2): ', r2)

4.4 다항회귀, 스플라인 회귀

  • 데이터가 훨씬 복잡할때 사용 ➡️ 비선형 관계
  • 다항 회귀: 비선형 관계를 모델링
    • 교차 다항식의 경우 과적합 위험이 있음
  • 스플라인 회귀: 비선형 관계를 유연하게 모델링
    • 구간마다 다른 다항식을 사용하여 전체적으로 매끄러운 곡선을 생성
    • 적절한 매듭점(knots)의 선택이 중요

 

실습: 주택 가격 예측(면적과 가격 간의 비선형 관계)

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)
X = X[:, np.newaxis]

# 다항 회귀 (degree = 2차)
polynomial_features = PolynomialFeatures(degree=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)
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 regression')
plt.xlabel('area')
plt.ylabel('price')
plt.show()