상관 및 회귀 분석
과목: 데이터 사이언스
주제: 상관계수, 단순/다중 회귀분석, 데이터 해석
들어가기
이번 장에서는 변수들 간의 관계를 이해하기 위한 상관 분석과 회귀 분석을 다룬다.
이는 데이터의 패턴을 이해하고 예측 모델을 구축하는 데 핵심적인 도구이다.
- 상관 분석(Correlation Analysis): 두 변수 간의 선형적 관계의 강도와 방향을 측정
- 회귀 분석(Regression Analysis): 하나 또는 그 이상의 독립 변수를 이용하여 종속 변수를 설명하거나 예측
상관 분석
상관의 개념
상관은 두 변수가 함께 변하는 정도를 수치로 나타낸 것이다.
- 양의 상관 → 두 변수가 함께 증가
- 음의 상관 → 한 변수가 증가할 때 다른 변수는 감소
- 0에 가까운 상관 → 선형적 관계가 거의 없음
피어슨 상관계수 (Pearson Correlation Coefficient)
가장 널리 쓰이는 상관계수는 피어슨 상관계수 \(r\) 로, 다음과 같이 정의된다.
- \(r \in [-1, 1]\)
- \(r = 1\): 완전한 양의 상관
- \(r = -1\): 완전한 음의 상관
- \(r = 0\): 선형 상관 없음
⚠️ 상관관계는 인과관계를 의미하지 않는다.
코사인 유사도 (Cosine Similarity)
두 벡터의 내적을 각 벡터의 노름으로 정규화한 값 → 각도 기반 유사도.
- 범위: 이론상 \([-1, 1]\) (실무에선 비음수 데이터가 많아 0~1로 쓰이는 경우가 많음)
- 의미: 벡터 방향의 유사성(크기 무시)
차이점
구분 | 피어슨 상관계수 | 코사인 유사도 |
---|---|---|
관점 | 평균을 제거한 선형 관계 | 크기 무시, 방향(각도) |
평균(shift) 영향 | 제거(중심화)로 영향 적음 | 평균 이동에 민감 |
스케일(scale) 영향 | 표준편차로 정규화 | 노름 정규화로 크기 영향 제거 |
주 사용처 | 통계적 상관, 변수 관계 분석 | 텍스트 임베딩, 추천, 벡터 검색 |
해석 | 같이 오르내리면 높음 | 같은 방향일수록 높음 |
한 줄 요약: “같이 오르내리는가?”는 피어슨, “같은 방향을 가리키는가?”는 코사인.
실습 1: 완전 선형 관계(스케일만 다름)
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10]) # x와 완전 선형 관계 (배수)
pearson_r = np.corrcoef(x, y)[0, 1]
cos_sim = cosine_similarity([x], [y])[0, 0]
print("피어슨 상관계수:", pearson_r)
print("코사인 유사도:", cos_sim)
- 출력결과
실행결과
피어슨 상관계수: 1.0
코사인 유사도: 0.9999999999999999
해석: 크기만 달라도 선형 패턴과 방향이 동일하므로 두 값 모두 1에 가깝다.
실습 2: 상수항(평행 이동) 추가
x = np.array([1, 2, 3, 4, 5])
y = x + 100 # 평균이 크게 이동
pearson_r = np.corrcoef(x, y)[0, 1]
cos_sim = cosine_similarity([x], [y])[0, 0]
print("피어슨 상관계수:", pearson_r)
print("코사인 유사도:", cos_sim)
- 출력결과
실행결과
피어슨 상관계수: 1.0
코사인 유사도: 0.9786043735886338
해석:
-
피어슨: 평균을 뺀 뒤 보는 지표라서 “형태가 같은가?”만 보며 1.0 유지
-
코사인: 평균 이동으로 각도가 미세하게 변해 1에서 멀어진다
언제 무엇을 쓸까?
-
피어슨 상관계수
-
목적: 통계적 상관(공분산 기반)
-
데이터: 연속형 변수, 선형적 관계 가정
-
사용처: 변수 간 관계 탐색, 회귀 전 상관 검토
-
코사인 유사도
-
목적: 벡터 의미 유사성(방향 기반)
-
데이터: 고차원 임베딩(문장/문서/이미지), sparse 벡터
-
사용처: 검색/추천, 최근접 이웃 탐색, 문장 의미 비교
실무 팁 & 주의사항
- 상관 ≠ 인과: 높은 피어슨 값이 원인-결과를 의미하진 않는다.
- 비선형 관계: 피어슨은 선형성에 민감. 비선형이라면 스피어만 순위 상관(ρ), 켄달 τ 고려.
- 스케일 & 평균 처리:
- 피어슨은 평균 중심화가 내장
- 코사인은 크기를 무시하지만 평균 이동에는 민감 → 필요 시 중앙값/평균 보정 고려
- 희소 벡터(예: TF–IDF): 코사인이 안정적이고 빠르게 동작하는 편
### 상관행렬 및 히트맵 시각화 ```python import seaborn as sns import matplotlib.pyplot as plt # 여러 변수 예시 np.random.seed(42) df_multi = pd.DataFrame({ 'X1': np.random.normal(50, 10, 100), 'X2': np.random.normal(30, 5, 100), 'X3': np.random.normal(100, 20, 100) }) corr_matrix = df_multi.corr() plt.figure(figsize=(6, 4)) sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt=".2f") plt.title("상관행렬 히트맵") plt.show()
실행결과 그래프 출력됨
단순 회귀 분석
개념
단순 회귀분석(Simple Linear Regression) 은 하나의 독립 변수 \(x\)와 종속 변수 \(y\) 사이의 선형 관계를 모델링한다.
- \(\beta_0\): 절편
- \(\beta_1\): 기울기
- \(\varepsilon\): 오차항
파이썬 예제: 단순 회귀
from sklearn.linear_model import LinearRegression
import numpy as np
X = df[['공부시간']] # 2차원 배열
y = df['점수']
model = LinearRegression()
model.fit(X, y)
print("절편 (β0):", model.intercept_)
print("기울기 (β1):", model.coef_[0])
# 공부시간이 7시간일 때 점수 예측
y_pred_7 = model.predict([[7]])
print("예측 점수 (x=7):", y_pred_7[0])
실행결과
[오류 발생] name 'df' is not defined
회귀직선 시각화
plt.scatter(X, y, color='blue', label='데이터')
plt.plot(X, model.predict(X), color='red', label='회귀직선')
plt.xlabel('공부 시간(시간)')
plt.ylabel('점수')
plt.legend()
plt.show()
실행결과
그래프 출력됨
다중 회귀 분석
개념
다중 회귀분석(Multiple Regression) 은 두 개 이상의 독립 변수를 사용해 종속 변수를 설명한다.
파이썬 예제: 다중 회귀
# 가상의 데이터 생성
np.random.seed(0)
n = 100
X1 = np.random.normal(50, 10, n)
X2 = np.random.normal(30, 5, n)
y = 5 + 0.8*X1 + 1.2*X2 + np.random.normal(0, 5, n)
df_multi = pd.DataFrame({'X1': X1, 'X2': X2, 'y': y})
X = df_multi[['X1', 'X2']]
y = df_multi['y']
model_multi = LinearRegression()
model_multi.fit(X, y)
print("절편:", model_multi.intercept_)
print("회귀계수:", model_multi.coef_)
실행결과
[오류 발생] name 'np' is not defined
회귀계수 해석
- 절편: 모든 독립변수가 0일 때의 예측값
- 회귀계수: 다른 변수를 고정했을 때 각 독립변수가 종속 변수에 미치는 영향
모델 평가 지표
결정계수 (\(R^2\))
모델이 종속 변수의 변동을 얼마나 잘 설명하는지를 나타낸다.
- \(R^2 \approx 1\): 설명력이 매우 좋음
- \(R^2 \approx 0\): 설명력이 낮음
r2 = model_multi.score(X, y)
print("R^2 점수:", r2)
실행결과
[오류 발생] name 'model_multi' is not defined
잔차(Residual) 분석
잔차 = 실제값 - 예측값
잔차 분석을 통해 회귀모형이 적절한지 판단할 수 있다.
y_pred = model_multi.predict(X)
residuals = y - y_pred
plt.scatter(y_pred, residuals)
plt.axhline(0, color='red', linestyle='--')
plt.xlabel("예측값")
plt.ylabel("잔차")
plt.title("잔차도")
plt.show()
실행결과
그래프 출력됨
좋은 회귀 모델의 잔차는 0을 중심으로 무작위로 퍼져 있어야 하며, 뚜렷한 패턴이 없어야 한다.
요약
- 상관분석은 변수 간 선형 관계의 강도를 수치로 측정한다.
- 회귀분석은 변수 간의 함수적 관계를 추정하고 예측에 활용할 수 있다.
- 시각화 및 잔차 분석은 모델의 적절성을 평가하는 중요한 과정이다.
- 높은 상관계수나 \(R^2\) 값이 인과관계를 보장하지는 않는다는 점에 유의하자.