선형회귀
선형회귀 (Linear Regression)
│
├─ 1. 모델 정의 (Model)
│ └─ Y = β₀ + β₁X + ε
│ 여기서 ε ~ N(0, σ²)
│
│ 예측: Ŷ = β₀ + β₁X
│ 출력: 연속형 실수 (-∞ ~ +∞)
│
├─ 2. 목표 (Objective)
│ ├─ SSE 최소화
│ │ min Σ(Yi - Ŷi)²
│ └─ = MSE 최소화 (같은 것)
│
└─ 3. 방법 (Method)
├─ 최소제곱법 (OLS)
│ └─ Closed-form solution ✅
│ β̂ = (X'X)⁻¹X'Y
│
└─ 수치 최적화 (선택사항)
├─ Gradient descent
└─ 등등...
전체 흐름
1. 데이터 수집
↓
2. 모델 설정 (Y = β₀ + β₁X + ε)
↓
3. 파라미터 추정 (최소제곱법) → β̂₀, β̂₁ 구함
↓
4. 모델 품질 평가 (R²) → "모델이 좋은가?"
↓
5. 전체 모델 검정 (F-검정/분산분석) → "모델이 유의미한가?"
↓
6. 개별 파라미터 추론
- 점추정: β̂₁ = 0.038 (값 하나)
- 구간추정: 0.035 ≤ β₁ ≤ 0.041 (범위)
- 가설검정: β₁이 0인가? (t-검정)
↓
7. 예측 및 활용
| 기호 | 이름 | 의미 | CIMS 예 |
|---|---|---|---|
| $Yi$ | 실제값 | 센서가 측정한 온도 | 23.1°C |
| $\bar{Y}$ | 평균값 | 모든 측정값의 평균 | 22.3°C |
| $\hat{Y_i}$ | 예측값 | 회귀선이 예측한 온도 | 22.8°C |
3. 파라미터 추정 (최소제곱법)
- 목적: “가장 좋은 직선 찾기”
- 방법: 손실 함수 최소화 \(min\sum_{i=1}(Y_i−\hat{Yi})^2\)
결과: \(\hat{\beta_1}=\frac{\sum(X_i−\bar{X})(Y_i−\bar{Y})}{\sum(X_i−\bar{X})^2}\)\(\hat{\beta_0}=\bar{Y}-\hat{\beta_1}\bar{X}\)입력: 전력, 온도 데이터 출력: $\hat{\beta_0}$ = 30.975, $\hat{\beta_1}$ = 0.0383 회귀식: 온도 = 30.975 + 0.0383 × 전력
4. 파라미터 추정 (최소제곱법) 결정계수
-
목적: “모델이 얼마나 데이터를 잘 설명하는가?” 계산: \(R^2=\frac{SSR}{SST} = 1 - \frac{SSE}{SST}\) 의미:
- R² = 0.70 → “X가 Y 변동의 70% 설명”
- 0 ≤ R² ≤ 1
- 클수록 좋음
- R² = 독립변수(X)가 종속변수(Y) 변동을 얼마나 설명하는가
판단 기준:
- R² < 0.3: 약함
- R² = 0.3~0.5: 중간
- R² = 0.5~0.7: 강함
- R² > 0.7: 매우 강함
단순회귀 : $R^2$ = 0.25 약함 다중회귀 : $R^2$ = 0.7 강함
5. 분산분석(ANOVA)/F-검정
목적: “모델 전체가 통계적으로 유의미한가?” 가설:
- $H_0$: 모든 $\beta = 0$ (모델 무의미)
- $H_1$: 적어도 하나는 $≠0$ (모델 유의미)
검정통계량: \(F=\frac{MSR}{MSE}=\frac{SSR/p}{SSE/(n-p-1)}\)
ANOVA 표:
| 요인 | 제곱합 | 자유도 | 평균제곱 | F | p-value |
|---|---|---|---|---|---|
| 회귀 | SSR | p | MSR | F | p |
| 오차 | SSE | n-p-1 | MSE | - | - |
| 총합 | SST | n-1 | - | - | - |
=== 다중회귀: 전력 + 습도 + Cold온도 → Hot온도 ===
R² = 0.6968 (69.68%)
개선: 44.7%p
F(3,698) = 534.65, p = 0.000000
F = 534.65, p < 0.001
→ 모델 매우 유의미 ✅
6. 개별 파라미터 추론
6-1. 점추정
목적: “파라미터의 최선 추정값” 결과: \(\hat{\beta_1} = 0.0383\) 의미: \(전력 1kW ↑ → 온도 0.0383°C ↑\)
6-2. 구간추정
목적: “파라미터의 신뢰 범위” 공식: \(\hat{\beta_1} \pm t_{\alpha/2, n-2} \times sd\{\hat{\beta_1}\}\)
결과:
- 95% 신뢰구간: [0.035, 0.041] 의미:
- 진짜 $\beta_1$이 이 범위에 있을 확률 95%
- 불확실성 표현
전력 10kW 증가 시:
- 점추정: 온도 +0.383°C
- 구간추정: 온도 +0.35~0.41°C (95% 신뢰)
참고
일반 구간추정 \(\hat{\theta} - 상수값{\cdot}표준편차(\hat{\theta}) \leq \theta \leq \hat{\theta} +상수값{\cdot}표준편차(\hat{\theta})\) \(\hat{\beta_1} - t_{\alpha/2, n-2} \cdot sd\{\hat{\beta_1}\} \leq \beta_1 \leq \hat{\beta_1} + t_{\alpha/2, n-2} \cdot sd\{\hat{\beta_1}\}\)
6-3 가설검정 - t검정
목적: “이 변수가 정말 영향을 주는가?” 가설:
- $H_0:\beta_1=0$ (영향 없음)
- $H_0:\beta_1\neq0$ (영향 있음) 검정통계량: \(t^* = \frac{\hat{\beta_1}-0}{sd(\hat{\beta_1})}\) 판단:
-
$ t* $ 크고 $p < 0.05 → H_o$ 기각 → 유의미
전력: t = 35.3, p < 0.001 → 유의미 ✅
습도: t = 32.9, p < 0.001 → 유의미 ✅
| 일반 형태 | 베타1 구체화 | 의미 |
|---|---|---|
| $\hat{\theta}$ | $\hat{\beta}$ | 추정량 (점추정값) |
| $\theta$ | $\beta_1$ | 모수 (진짜 값) |
| 상수값 | $t_{\alpha/2, n-2}$ | t-분포 임계값 |
| 표준편차($\hat{\theta}$) | $sd{\hat{\beta_1}}$ | 추정량의 표준오차 |
CIMS 적용
# 데이터 준비
df = pd.read_csv('containment_hot_aisle.csv')
X = df<span title='There is no note that matches this link.' class='invalid-link'> <span class='invalid-link-brackets'>[[</span> 'power', 'humiHot', 'tempCold' <span class='invalid-link-brackets'>]]</span></span>.values
y = df['tempHot'].values
# 파라미터 추정(최소제곱법)
model = LinearRegression() model.fit(X, y)
print(f"β₀ = {model.intercept_}")
print(f"β₁ = {model.coef_[0]}")
print(f"β₂ = {model.coef_[1]}")
print(f"β₃ = {model.coef_[2]}")
# 결정계수 평가
R2 = model.score(X, y)
print(f"R² = {R2:.4f}")
# 전체 모델 검정 (F-검정/분산분석)
n, p = len(y), X.shape[1]
SST = np.sum((y - y.mean())**2)
SSR = np.sum((y_pred - y.mean())**2)
SSE = np.sum((y - y_pred)**2)
F_stat = (SSR/p) / (SSE/(n-p-1))
p_value = 1 - stats.f.cdf(F_stat, p, n-p-1)
print(f"F = {F_stat:.2f}, p = {p_value:.6f}")
#구간추정
# 표준오차 계산
s = np.sqrt(SSE / (n-p-1))
X_design = np.column_stack([np.ones(n), X])
XtX_inv = np.linalg.inv(X_design.T @ X_design)
se_beta = s * np.sqrt(np.diag(XtX_inv))
# 95% 신뢰구간
t_crit = stats.t.ppf(0.975, n-p-1)
ci_lower = model.coef_[0] - t_crit * se_beta[1]
ci_upper = model.coef_[0] + t_crit * se_beta[1]
print(f"전력 계수 95% 신뢰구간: [{ci_lower:.4f}, {ci_upper:.4f}]")
#가설검ㅁ정
t_stats = model.coef_ / se_beta[1:]
p_values = 2 * (1 - stats.t.cdf(np.abs(t_stats), n-p-1))
print(f"전력: t = {t_stats[0]:.2f}, p = {p_values[0]:.6f}")
print(f"습도: t = {t_stats[1]:.2f}, p = {p_values[1]:.6f}")
#출력
#R² = 0.6968 (69.68%)R² = 0.6968 (69.68%)
#F(3,698) = 534.65, p = 0.000000
#전력 계수 95% 신뢰구간: [0.0290, 0.0329]
#전력: t = 31.10, p = 0.000000
#습도: t = -20.75, p = 0.000000#출력
#R² = 0.6968 (69.68%)R² = 0.6968 (69.68%)
#F(3,698) = 534.65, p = 0.000000
#전력 계수 95% 신뢰구간: [0.0290, 0.0329]
#전력: t = 31.10, p = 0.000000
#습도: t = -20.75, p = 0.000000
This line appears after every note.
Notes mentioning this note
There are no notes linking to this note.