앞서 본 것처럼, 단순 선형 회귀에서는 데이터를 "최적 적합선"으로 모델링합니다. 이 선의 공식은 다음과 같습니다.
여기서 m은 기울기, b는 절편입니다.
"다중 선형 회귀"는 하나의 예측 변수를 여러 예측 변수(방 개수, 해안까지의 거리, 동네의 중간소득 등)로 일반화한 것입니다. 공식은 다음과 같이 확장됩니다.
여기서 각 xi는 독립 변수이며, 해당하는 bi는 그 계수입니다. 3차원에서는 선이 평면으로 일반화되고, 더 높은 차원에서는 "초평면"이 됩니다.
계수와 절편은 어떻게 해석할까요? 절편은 모든 독립 변수가 0일 때의 y 예측값, 즉 예측 변수가 기여하지 않을 때 종속 변수의 기준선 값입니다. 각 계수 bi는 다른 독립 변수를 고정했을 때 xi가 한 단위 변할 경우 종속 변수 y가 얼마나 변하는지를 나타냅니다.
환경 설정
scikit-learn 설치는 간단합니다. pip install scikit-learn 명령을 사용하세요. 특정 버전(예: 1.2.2)을 설치하려면 다음처럼 버전을 포함해 실행합니다: pip install scikit-learn==1.2.2. Anaconda를 사용한다면 scikit-learn이 이미 설치되어 있을 가능성이 큽니다. Anaconda 배포판에서 별도로 설치해야 한다면 conda install scikit-learn 명령을 사용하세요.
scikit-learn 사용 시 필수 또는 권장되는 라이브러리가 있습니다. numpy 는 특성과 레이블을 저장하는 데 필요합니다. pandas 는 데이터셋 로딩, 전처리, 탐색에 권장됩니다.
scikit-learn을 사용한다면 데이터 준비를 위해 이미 pandas를 사용할 가능성이 큽니다. 결과를 시각화하려면 matplotlib 또는 seaborn 혹은 둘 다를 사용하게 될 것입니다. 위 예시처럼 pip install을 통해 이들 라이브러리를 설치할 수 있습니다. 하나의 명령으로 여러 라이브러리를 한꺼번에 설치할 수도 있습니다.
# Import libraries.import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns제공
데이터셋 로딩
널리 알려진 California housing 데이터셋을 사용해 보겠습니다.
# Read in California housing dataset.from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()제공
데이터 준비
데이터를 학습/테스트 세트로 나눕니다. sklearn.model_selection의 train_test_split() 메서드를 임포트한 뒤, 테스트 세트 비율과 random_state를 지정해 호출합니다. 또한 평균 방 개수 특성 하나만 사용하는 단순 선형 회귀를 적용하겠습니다.
# Import train_test_split.from sklearn.model_selection import train_test_split
# Create features X and target y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)[["AveRooms"]]
y = housing.target # Median house value in $100,000s# Split the dataset into training (80%) and testing (20%) sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)제공
테스트/학습 세트로 분할했으니, 이제 특성을 표준화해 보겠습니다. 이 과정은 모든 변수가 동일한 스케일을 갖도록 하여, 모델 성능과 수치적 안정성을 높일 수 있습니다.
# Import StandardScaler.from sklearn.preprocessing import StandardScaler
# Instantiate StandardScaler.
scaler = StandardScaler()# Fit and transform training data.
X_train_scaled = scaler.fit_transform(X_train)# Also transform test data.
X_test_scaled = scaler.transform(X_test)제공
이 코드에서 StandardScaler 는 평균을 제거하고 단위 분산으로 스케일링하는 전처리 도구입니다. 스케일 차이로 인해 특정 특성이 모델을 지배하지 않도록 도와줍니다.
스케일러는 fit_transform() 메서드로 학습 데이터에 적합 및 변환됩니다. 테스트 데이터는 동일한 스케일링 인자를 사용하도록 transform() 만 적용해 별도로 변환하여 데이터 누수를 방지합니다.
선형 회귀 모델 학습
선형 회귀 모델을 만들려면 sklearn.linear_model에서 LinearRegression() 을 임포트하고, 인스턴스를 생성해 변수에 할당합니다.
# Import LinearRegression.from sklearn.linear_model import LinearRegression
# Instantiate linear regression model.
model = LinearRegression()제공
학습 데이터로 모델을 적합하는 과정은 간단합니다.
# Fit the model to the training data.
model.fit(X_train_scaled, y_train)제공
예측 수행
모델 학습을 마쳤으니, 테스트 세트에 대해 예측을 수행합니다.
# Make predictions on the testing data.
y_pred = model.predict(X_test_scaled)제공
모델 성능 평가
테스트 세트에 대한 예측을 얻었으니, 실제와 얼마나 잘 맞는지 확인해야 합니다. 회귀 알고리즘의 성능을 평가하는 지표는 여러 가지가 있습니다. 가장 일반적인 지표로 결정계수(R2), 평균제곱오차(MSE), 제곱근 평균제곱오차(RMSE)가 있습니다.
결정계수 R2는 회귀 모델이 목표 변수의 변동성을 얼마나 잘 설명하는지를 측정합니다. 즉, 예측 변수가 목표 변수의 변동성 중 얼마나 많은 부분을 설명하는지를 정량화하며, 적합도(goodness of fit)로 알려져 있습니다.
이를 더 잘 이해하기 위해 공식을 살펴봅시다.
여기서 yactual은 목표 변수의 실제 값, ypredicted는 모델에서 예측된 값, ȳ는 실제 값의 평균입니다. 이 공식은 목표 변수의 분산 중 모델이 설명하는 비율을 이해하는 데 도움을 줍니다. 분모는 데이터의 총분산, 분자는 회귀 모델 적용 후에도 설명되지 않은 분산을 나타냅니다. 따라서 그 비율은 모델이 설명하는 분산의 비율을 제공합니다.
R2는 어떻게 해석할까요?
R2 = 1: 모델이 목표 변수의 모든 분산을 완벽하게 설명합니다.
R2 = 0: 모델이 분산을 전혀 설명하지 못해, 평균만 사용하는 것과 다르지 않습니다.
R2 < 0: 평균만 사용하는 것보다도 성능이 나쁘며, 적합도가 매우 낮음을 의미합니다.
몇 가지 유의할 점이 있습니다.
높은 R2가 항상 좋은 것은 아닙니다. 특히 복잡한 모델에서는 과적합을 의미할 수 있습니다.
특성을 더 추가하면 R2가 인위적으로 증가할 수 있으므로, 값이 높다고 반드시 더 좋은 것은 아닙니다.
다중 회귀에서는 예측 변수의 수를 보정한 수정 R2를 사용하여 불필요한 변수로 인한 오해를 줄이세요.
다른 일반적인 지표로 평균제곱오차(MSE)와 제곱근 평균제곱오차(RMSE)가 있습니다. 이 지표들은 모델의 예측이 실제 값에서 얼마나 벗어나는지를 측정합니다.
MSE는 실제 값과 예측 값의 제곱 차이의 평균을 계산합니다.
여기서 n은 전체 관측치 수입니다. 평균을 내기 전에 오차를 제곱하기 때문에 큰 오차가 작은 오차보다 더 크게 페널티를 받아, MSE는 이상치에 민감합니다. MSE가 낮을수록 모델 적합도가 좋다는 뜻입니다.
이 이슈를 보완하기 위해 RMSE를 사용합니다. RMSE는 MSE의 제곱근으로, 목표 변수와 같은 단위를 사용하므로 평균적으로 예측이 얼마나 빗나가는지 더 해석하기 쉽습니다.
scikit-learn으로 MSE와 RMSE를 계산하는 것도 간단합니다.
# Calculate and print MSE.
mse = mean_squared_error(y_test, y_pred)print(f"Mean squared error: {mse:.4f}")# Calculate and print RMSE.
rmse = mse **0.5print(f"Root mean squared error: {rmse:.4f}")제공
Mean squared error:1.2923
Root mean squared error:1.1368제공
scikit-learn에서 다중 선형 회귀 다루기
이번에는 평균 방 개수 하나만이 아니라 사용 가능한 모든 특성으로 모델을 다시 실행해 보겠습니다. 결과가 더 좋아질까요, 나빠질까요?
# Uses all features.import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load data set.
housing = fetch_california_housing()# Split into X, y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target # Median house value in $100,000s
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Scale the data.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# Create model and fit it to the training data.
model = LinearRegression()
model.fit(X_train_scaled, y_train)# Make predictions.
y_pred = model.predict(X_test_scaled)# Calculate and print errors.
r2 = r2_score(y_test, y_pred)print(f"R-squared: {r2:.4f}")
mse = mean_squared_error(y_test, y_pred)print(f"Mean squared error: {mse:.4f}")
rmse = mse **0.5print(f"Root mean squared error: {rmse:.4f}")제공
R-squared:0.5758
Mean squared error:0.5559
Root mean squared error:0.7456제공
단일 특성만 사용했을 때보다 결과가 훨씬 좋아졌습니다. 하지만 그렇다고 해서 모든 특성이 필요한지는 별개의 문제입니다. 어떤 특성은 다른 것보다 더 중요할 수 있습니다. 데이터셋에서 가장 관련성 높은 특성을 선택하는 작업을 특성 선택이라고 합니다.
특성 선택이 중요한 이유는 여러 가지입니다.
과적합 감소. 특성이 적을수록 복잡도가 낮아져 과적합 위험이 줄어듭니다.
정확도 향상. 무관하거나 중복된 특성을 제거하면 모델이 의미 있는 패턴에 집중할 수 있습니다.
해석 용이성 향상. 가장 중요한 요인을 부각시켜 모델을 이해하기 쉽게 만듭니다.
학습 속도 향상. 특성 수를 줄이면 계산 시간과 메모리 사용량이 감소합니다.
여러 특성 간 상관이 매우 높으면, 본질적으로 같은 정보를 모델에 제공하는 중복 상태가 됩니다. 이를 다중공선성이라고 합니다. 다중공선성이 항상 예측 정확도에 악영향을 주는 것은 아니지만, 특히 선형 회귀 및 관련 모델에서 특성 선택과 해석을 복잡하게 만듭니다.
분산팽창계수(VIF)는 예측 변수 간 다중공선성을 탐지하는 데 쓰이는 지표입니다. 각 예측 변수에 대해 VIF는 다음과 같이 계산합니다.
여기서 Ri2는 예측 변수 Xi를 나머지 모든 예측 변수에 대해 회귀시켰을 때 얻는 R2 값입니다. VIF가 높을수록 해당 예측 변수가 다른 변수들과 강하게 상관되어 있음을 의미합니다.
VIF = 1: 다중공선성 없음(이상적).
VIF < 5: 낮거나 보통 수준의 다중공선성(일반적으로 허용 가능).
VIF > 5: 높은 다중공선성(상관된 변수를 제거하거나 결합 고려).
VIF > 10: 심각한 다중공선성(변수 중복 가능성이 큼).
# Import libraries.import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from statsmodels.stats.outliers_influence import variance_inflation_factor
# Load the dataset.
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)# Compute the correlation matrix.
corr_matrix = X.corr()# Identify pairs of features with high collinearity (correlation > 0.8 or < -0.8).
high_corr_features =[(col1, col2, corr_matrix.loc[col1, col2])for col1 in corr_matrix.columns
for col2 in corr_matrix.columns
if col1 != col2 andabs(corr_matrix.loc[col1, col2])>0.8]# Convert to a DataFrame for better visualization.
collinearity_df = pd.DataFrame(high_corr_features, columns=["Feature 1","Feature 2","Correlation"])print("\nHighly Correlated Features:\n", collinearity_df)# Compute Variance Inflation Factor (VIF) for each feature.
vif_data = pd.DataFrame()
vif_data["Feature"]= X.columns
vif_data["VIF"]=[variance_inflation_factor(X.values, i)for i inrange(X.shape[1])]# Print VIF values.print("\nVariance Inflation Factor (VIF) for each feature:\n", vif_data)제공
Highly Correlated Features:
Feature 1 Feature 2 Correlation
0 AveRooms AveBedrms 0.8476211 AveBedrms AveRooms 0.8476212 Latitude Longitude -0.9246643 Longitude Latitude -0.924664
Variance Inflation Factor (VIF)for each feature:
Feature VIF
0 MedInc 11.5111401 HouseAge 7.1959172 AveRooms 45.9936013 AveBedrms 43.5903144 Population 2.9357455 AveOccup 1.0952436 Latitude 559.8740717 Longitude 633.711654제공
모델에서 AveBedrms를 제거해 보겠습니다.
# Import libraries.import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load California housing dataset.
housing = fetch_california_housing()# Create DataFrame and remove "AveBedrms" feature.
X = pd.DataFrame(housing.data, columns=housing.feature_names).drop(columns=["AveBedrms"])
y = housing.target # Median house value in $100,000s# Split data into training and testing sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Scale the data (Standardization).
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# Create a linear regression model and train it.
model = LinearRegression()
model.fit(X_train_scaled, y_train)# Make predictions on the test set.
y_pred = model.predict(X_test_scaled)# Calculate performance metrics.
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)# Print evaluation metricsprint(f"R-squared: {r2:.4f}")print(f"Mean squared error: {mse:.4f}")print(f"Root mean squared error: {rmse:.4f}")제공
R-squared:0.5823
Mean squared error:0.5473
Root mean squared error:0.7398제공
결과가 (소폭) 개선되었습니다.
모델 인사이트 도출
회귀 모델을 구축하는 것은 시작일 뿐이며, 출력 결과를 이해하는 것도 똑같이 중요합니다. 모델의 계수를 분석하면 어떤 특성이 예측에 가장 큰 영향을 미치는지 파악할 수 있습니다.
회귀 계수 이해하기
선형 회귀 모델을 학습한 후에는 model.coef_ 로 계수에, model.intercept_ 로 절편에 접근할 수 있습니다.
LinearRegression()으로 학습된 선형 회귀 모델은 model.coef_ 로 계수, model.intercept_ 로 절편을 확인할 수 있습니다.
Scikit-Learn은 Statsmodels처럼 내장된 summary() 메서드를 제공하지 않으므로, 회귀 계수를 사용해 각 특성의 중요도를 수동으로 추출하고 시각화할 수 있습니다. 계수의 절댓값이 클수록 목표 변수에 미치는 영향이 더 큽니다. 다음 코드를 참고하세요.
# Compute residuals.
residuals = y_test - y_pred
# Create plots.
plt.figure(figsize=(12,5))# Plot 1: Residuals Distribution.
plt.subplot(1,2,1)
sns.histplot(residuals, bins=30, kde=True, color="blue")
plt.axvline(x=0, color='red', linestyle='--')
plt.title("Residuals Distribution")
plt.xlabel("Residuals (y_actual - y_predicted)")
plt.ylabel("Frequency")# Plot 2: Regression Fit (Actual vs Predicted).
plt.subplot(1,2,2)
sns.scatterplot(x=y_test, y=y_pred, alpha=0.5)
plt.plot([min(y_test),max(y_test)],[min(y_test),max(y_test)], color='red', linestyle='--')# Perfect fit line
plt.title("Regression Fit: Actual vs Predicted")
plt.xlabel("Actual Prices (in $100,000s)")
plt.ylabel("Predicted Prices (in $100,000s)")# Show plots.
plt.tight_layout()
plt.show()제공
잔차와 회귀 적합도 시각화 플롯
잔차 분포(왼쪽 플롯)는 0을 중심으로 분포하는 것이 이상적이며, 이는 오차가 무작위로 분포함을 의미합니다. 잔차가 정규분포를 따른다면 모델이 잘 맞는 것이고, 왜도나 추세가 보이면 체계적인 오차가 있음을 시사합니다. 회귀 적합도(오른쪽 플롯)는 실제 값과 예측 값을 비교하며, 붉은 점선은 완벽한 적합선을 나타냅니다. 점들이 선을 밀접하게 따른다면 예측이 정확한 것이고, 곡선 같은 패턴이 보이면 실제 관계가 선형이 아닐 수 있습니다.
이러한 시각화는 과적합/과소적합을 진단하고, 누락된 관계를 시사하는 잔차 패턴을 드러내며, 모델 효과성을 명확히 평가하는 데 도움을 줍니다.
현업 활용 사례
선형 회귀는 다양한 산업에서 예측과 의사결정에 널리 사용됩니다. 부동산에서는 면적, 위치 같은 요인을 바탕으로 주택 가격을 추정합니다.
영업과 마케팅에서는 수요 예측과 예산 최적화에, 의료에서는 질병 위험 평가에 활용합니다. 금융에서는 주가 예측과 신용평가에, 제조에서는 품질 관리와 고장 예측에 도움을 줍니다.
선형 회귀는 통계와 머신 러닝에서 변수 간 관계를 모델링하는 데 사용하는 기본 기법입니다. 간단히 말해, 하나 이상의 영향 요인을 바탕으로 결과를 예측할 수 있게 해줍니다. 부동산 가격 책정, 매출 예측, 리스크 평가 등 다양한 분야에서 널리 활용됩니다.
이 튜토리얼에서는 scikit-learn의 선형 회귀를 살펴보며, 작동 방식과 유용성, 구현 방법을 다룹니다. 끝까지 따라오시면 데이터 기반 예측을 위해 선형 회귀 모델을 구축하고 평가할 수 있습니다.
주택 가격 vs 방 개수 산점도
선형 회귀와 머신 러닝
주택 가격 산정에 바로 활용되는 것 외에도, 선형 회귀는 머신 러닝에서 중요한 역할을 합니다.
단순하지만, 선형 회귀는 효율성, 해석 용이성, 범용성 덕분에 머신 러닝에서 없어서는 안 될 도구로 남아 있습니다.
선형 회귀와 scikit-learn 라이브러리
scikit-learn 라이브러리를 사용하면 선형 회귀를 손쉽게 구현할 수 있습니다. 이 라이브러리는 여러 장점이 있습니다.
model.fit(X_train, y_train)한 줄이면 됩니다.scikit-learn이 처음이라면, Python 라이브러리를 직접 다뤄보는 Machine Learning with scikit-learn 코스를 확인해 보세요.
선형 회귀 이해하기
앞서 본 것처럼, 단순 선형 회귀에서는 데이터를 "최적 적합선"으로 모델링합니다. 이 선의 공식은 다음과 같습니다.
여기서 m은 기울기, b는 절편입니다.
"다중 선형 회귀"는 하나의 예측 변수를 여러 예측 변수(방 개수, 해안까지의 거리, 동네의 중간소득 등)로 일반화한 것입니다. 공식은 다음과 같이 확장됩니다.
여기서 각 xi는 독립 변수이며, 해당하는 bi는 그 계수입니다. 3차원에서는 선이 평면으로 일반화되고, 더 높은 차원에서는 "초평면"이 됩니다.
계수와 절편은 어떻게 해석할까요? 절편은 모든 독립 변수가 0일 때의 y 예측값, 즉 예측 변수가 기여하지 않을 때 종속 변수의 기준선 값입니다. 각 계수 bi는 다른 독립 변수를 고정했을 때 xi가 한 단위 변할 경우 종속 변수 y가 얼마나 변하는지를 나타냅니다.
환경 설정
scikit-learn 설치는 간단합니다.
pip install scikit-learn명령을 사용하세요. 특정 버전(예: 1.2.2)을 설치하려면 다음처럼 버전을 포함해 실행합니다:pip install scikit-learn==1.2.2.Anaconda를 사용한다면 scikit-learn이 이미 설치되어 있을 가능성이 큽니다. Anaconda 배포판에서 별도로 설치해야 한다면conda install scikit-learn명령을 사용하세요.scikit-learn 사용 시 필수 또는 권장되는 라이브러리가 있습니다.
numpy는 특성과 레이블을 저장하는 데 필요합니다.pandas는 데이터셋 로딩, 전처리, 탐색에 권장됩니다.scikit-learn을 사용한다면 데이터 준비를 위해 이미 pandas를 사용할 가능성이 큽니다. 결과를 시각화하려면
matplotlib또는seaborn혹은 둘 다를 사용하게 될 것입니다. 위 예시처럼 pip install을 통해 이들 라이브러리를 설치할 수 있습니다. 하나의 명령으로 여러 라이브러리를 한꺼번에 설치할 수도 있습니다.pip install scikit-learn numpy pandas matplotlib seaborn.sklearn에서 선형 회귀 구현
데이터셋을 로드하기 전에, 흔히 사용하는 라이브러리를 임포트해 봅시다.
데이터셋 로딩
널리 알려진 California housing 데이터셋을 사용해 보겠습니다.
데이터 준비
데이터를 학습/테스트 세트로 나눕니다.
sklearn.model_selection의train_test_split()메서드를 임포트한 뒤, 테스트 세트 비율과random_state를 지정해 호출합니다. 또한 평균 방 개수 특성 하나만 사용하는 단순 선형 회귀를 적용하겠습니다.테스트/학습 세트로 분할했으니, 이제 특성을 표준화해 보겠습니다. 이 과정은 모든 변수가 동일한 스케일을 갖도록 하여, 모델 성능과 수치적 안정성을 높일 수 있습니다.
이 코드에서
StandardScaler는 평균을 제거하고 단위 분산으로 스케일링하는 전처리 도구입니다. 스케일 차이로 인해 특정 특성이 모델을 지배하지 않도록 도와줍니다.스케일러는
fit_transform()메서드로 학습 데이터에 적합 및 변환됩니다. 테스트 데이터는 동일한 스케일링 인자를 사용하도록transform()만 적용해 별도로 변환하여 데이터 누수를 방지합니다.선형 회귀 모델 학습
선형 회귀 모델을 만들려면
sklearn.linear_model에서LinearRegression()을 임포트하고, 인스턴스를 생성해 변수에 할당합니다.학습 데이터로 모델을 적합하는 과정은 간단합니다.
예측 수행
모델 학습을 마쳤으니, 테스트 세트에 대해 예측을 수행합니다.
모델 성능 평가
테스트 세트에 대한 예측을 얻었으니, 실제와 얼마나 잘 맞는지 확인해야 합니다. 회귀 알고리즘의 성능을 평가하는 지표는 여러 가지가 있습니다. 가장 일반적인 지표로 결정계수(R2), 평균제곱오차(MSE), 제곱근 평균제곱오차(RMSE)가 있습니다.
결정계수 R2는 회귀 모델이 목표 변수의 변동성을 얼마나 잘 설명하는지를 측정합니다. 즉, 예측 변수가 목표 변수의 변동성 중 얼마나 많은 부분을 설명하는지를 정량화하며, 적합도(goodness of fit)로 알려져 있습니다.
이를 더 잘 이해하기 위해 공식을 살펴봅시다.
여기서 yactual은 목표 변수의 실제 값, ypredicted는 모델에서 예측된 값, ȳ는 실제 값의 평균입니다. 이 공식은 목표 변수의 분산 중 모델이 설명하는 비율을 이해하는 데 도움을 줍니다. 분모는 데이터의 총분산, 분자는 회귀 모델 적용 후에도 설명되지 않은 분산을 나타냅니다. 따라서 그 비율은 모델이 설명하는 분산의 비율을 제공합니다.
R2는 어떻게 해석할까요?
몇 가지 유의할 점이 있습니다.
scikit-learn을 사용하면 결정계수로 모델 성능을 쉽게 평가할 수 있습니다.
다른 일반적인 지표로 평균제곱오차(MSE)와 제곱근 평균제곱오차(RMSE)가 있습니다. 이 지표들은 모델의 예측이 실제 값에서 얼마나 벗어나는지를 측정합니다.
MSE는 실제 값과 예측 값의 제곱 차이의 평균을 계산합니다.
여기서 n은 전체 관측치 수입니다. 평균을 내기 전에 오차를 제곱하기 때문에 큰 오차가 작은 오차보다 더 크게 페널티를 받아, MSE는 이상치에 민감합니다. MSE가 낮을수록 모델 적합도가 좋다는 뜻입니다.
이 이슈를 보완하기 위해 RMSE를 사용합니다. RMSE는 MSE의 제곱근으로, 목표 변수와 같은 단위를 사용하므로 평균적으로 예측이 얼마나 빗나가는지 더 해석하기 쉽습니다.
scikit-learn으로 MSE와 RMSE를 계산하는 것도 간단합니다.
scikit-learn에서 다중 선형 회귀 다루기
이번에는 평균 방 개수 하나만이 아니라 사용 가능한 모든 특성으로 모델을 다시 실행해 보겠습니다. 결과가 더 좋아질까요, 나빠질까요?
단일 특성만 사용했을 때보다 결과가 훨씬 좋아졌습니다. 하지만 그렇다고 해서 모든 특성이 필요한지는 별개의 문제입니다. 어떤 특성은 다른 것보다 더 중요할 수 있습니다. 데이터셋에서 가장 관련성 높은 특성을 선택하는 작업을 특성 선택이라고 합니다.
특성 선택이 중요한 이유는 여러 가지입니다.
여러 특성 간 상관이 매우 높으면, 본질적으로 같은 정보를 모델에 제공하는 중복 상태가 됩니다. 이를 다중공선성이라고 합니다. 다중공선성이 항상 예측 정확도에 악영향을 주는 것은 아니지만, 특히 선형 회귀 및 관련 모델에서 특성 선택과 해석을 복잡하게 만듭니다.
분산팽창계수(VIF)는 예측 변수 간 다중공선성을 탐지하는 데 쓰이는 지표입니다. 각 예측 변수에 대해 VIF는 다음과 같이 계산합니다.
여기서 Ri2는 예측 변수 Xi를 나머지 모든 예측 변수에 대해 회귀시켰을 때 얻는 R2 값입니다. VIF가 높을수록 해당 예측 변수가 다른 변수들과 강하게 상관되어 있음을 의미합니다.
모델에서 AveBedrms를 제거해 보겠습니다.
결과가 (소폭) 개선되었습니다.
모델 인사이트 도출
회귀 모델을 구축하는 것은 시작일 뿐이며, 출력 결과를 이해하는 것도 똑같이 중요합니다. 모델의 계수를 분석하면 어떤 특성이 예측에 가장 큰 영향을 미치는지 파악할 수 있습니다.
회귀 계수 이해하기
선형 회귀 모델을 학습한 후에는
model.coef_로 계수에,model.intercept_로 절편에 접근할 수 있습니다.LinearRegression()으로 학습된 선형 회귀 모델은
model.coef_로 계수,model.intercept_로 절편을 확인할 수 있습니다.모델 결과 요약
Scikit-Learn은 Statsmodels처럼 내장된
summary()메서드를 제공하지 않으므로, 회귀 계수를 사용해 각 특성의 중요도를 수동으로 추출하고 시각화할 수 있습니다. 계수의 절댓값이 클수록 목표 변수에 미치는 영향이 더 큽니다. 다음 코드를 참고하세요.계수 값을 기반으로 한 특성 중요도 그래프
이제 잔차와 회귀 적합도를 시각화해 봅시다.
잔차와 회귀 적합도 시각화 플롯
잔차 분포(왼쪽 플롯)는 0을 중심으로 분포하는 것이 이상적이며, 이는 오차가 무작위로 분포함을 의미합니다. 잔차가 정규분포를 따른다면 모델이 잘 맞는 것이고, 왜도나 추세가 보이면 체계적인 오차가 있음을 시사합니다. 회귀 적합도(오른쪽 플롯)는 실제 값과 예측 값을 비교하며, 붉은 점선은 완벽한 적합선을 나타냅니다. 점들이 선을 밀접하게 따른다면 예측이 정확한 것이고, 곡선 같은 패턴이 보이면 실제 관계가 선형이 아닐 수 있습니다.
이러한 시각화는 과적합/과소적합을 진단하고, 누락된 관계를 시사하는 잔차 패턴을 드러내며, 모델 효과성을 명확히 평가하는 데 도움을 줍니다.
현업 활용 사례
선형 회귀는 다양한 산업에서 예측과 의사결정에 널리 사용됩니다. 부동산에서는 면적, 위치 같은 요인을 바탕으로 주택 가격을 추정합니다.
영업과 마케팅에서는 수요 예측과 예산 최적화에, 의료에서는 질병 위험 평가에 활용합니다. 금융에서는 주가 예측과 신용평가에, 제조에서는 품질 관리와 고장 예측에 도움을 줍니다.
선형 회귀를 사용할 때
선형 회귀를 사용하지 않을 때
결론
선형 회귀는 머신 러닝과 통계 모델링에서 가장 기본적이면서도 널리 쓰이는 기법 중 하나입니다. 단순하지만, 변수 간 관계를 이해하고 다양한 실제 문제에서 예측을 수행하는 데 강력한 도구입니다.
이번 튜토리얼의 핵심 내용을 정리하면 다음과 같습니다.
Python 문자열 보간에 대한 추가 정보는 DataCamp의 자료를 참고하세요.