선형 회귀(Linear Regression)는 머신러닝에서 가장 기본적이면서도 강력한 도구 중 하나로, 두 변수 사이에 양의 관계 또는 음의 관계가 존재하는지를 파악하는 데 사용됩니다.
또한 선형 회귀는 빠른 예측 분석에 활용할 수 있는 몇 안 되는 유용한 도구이기도 합니다. 이 글에서는 Python의 pandas 패키지를 사용해 데이터를 불러오고, 선형 회귀 모델을 구축·해석·시각화하는 과정을 단계별로 살펴보겠습니다.
회귀(Regression)란 무엇인가?
회귀는 종속 변수(dependent variable)와 독립 변수(independent variable) 사이의 관계를 모델링하여 예측하는 대표적인 예측 분석 기법입니다. 즉, 하나 이상의 독립 변수 값을 바탕으로 종속 변수의 값을 예측하는 통계적 방법이라고 할 수 있습니다.
회귀의 주요 유형
- 선형 회귀 (Linear Regression)
- 로지스틱 회귀 (Logistic Regression)
- 다항 회귀 (Polynomial Regression)
- 단계적 회귀 (Stepwise Regression)
선형 회귀는 어디에 활용될까?
- 추세 분석 및 매출 추정
- 가격 변화가 미치는 영향 분석
- 리스크(Risk) 평가
선형 회귀 모델 구축 절차
- 개발 환경을 설정하고 데이터셋과 Jupyter Notebook(또는 Anaconda 등 다른 IDE)을 준비합니다.
- 필요한 라이브러리와 데이터셋을 불러옵니다.
- 데이터를 탐색하고 특성을 파악합니다.
- 데이터를 활용해 선형 회귀 모델을 학습시킵니다.
- 변수와 시간대(Time of Day) 간의 관계를 추가로 분석합니다.
- 전체 내용을 요약합니다.
환경 설정
아래 링크에서 실습에 사용할 데이터셋을 다운로드할 수 있습니다.
https://en.openei.org/datasets/dataset/649aa6d3-2832-4978-bc6e-fa563568398e/resource/b710e97d-29c9-4ca5-8137-63b7cf447317/download/building1retail.csv
이 데이터셋은 외기 온도(Outdoor Air Temperature, OAT)를 설명 변수로 사용하여 건물의 전력 소비량(Power)을 모델링하는 데 활용됩니다.
다운로드한 CSV 파일은 Jupyter Notebook 또는 IDE가 실행되는 동일한 폴더에 저장해 주세요.
필요 라이브러리 및 데이터셋 불러오기
먼저 필요한 라이브러리를 임포트한 후, pandas를 사용해 데이터셋을 읽어옵니다.
# 필요한 라이브러리 임포트
import pandas as pd
# 수치 연산에 필요한 라이브러리
import numpy as np
from scipy import stats
from datetime import datetime
from sklearn import preprocessing
from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression
# 그래프 그리기를 위한 라이브러리
import matplotlib.pyplot as plt
%matplotlib inline
# 데이터 읽기
df = pd.read_csv('building1retail.csv', index_col=[0],
date_parser=lambda x: datetime.strptime(x, "%m/%d/%Y %H:%M"))
df.head()실행 결과

데이터셋 탐색하기
pandas의 plot 기능을 사용해 데이터를 시각화하며 살펴보겠습니다.
df.plot(figsize=(22,6))
실행 결과

x축은 2010년 1월부터 2011년 1월까지의 데이터를 나타냅니다.
위 그래프에서 두 가지 특이한 점을 발견할 수 있습니다.
결측치(missing data)가 없어 보입니다. 확인하려면 아래 코드를 실행하세요:
df.isnull().values.any()
실행 결과
False
False라는 결과는 데이터프레임에 결측값(null)이 존재하지 않는다는 것을 의미합니다.
데이터에 일부 이상치(anomaly, 아래로 길게 뻗은 스파이크)가 존재합니다.
이상치 또는 '아웃라이어(outlier)'는 보통 실험 오차에서 비롯되거나, 실제 값일 수도 있습니다. 하지만 이상치는 회귀 직선의 기울기에 심각한 영향을 미치므로, 이번 실습에서는 제거하기로 합니다.
이상치를 제거하기 전에, 먼저 우리 데이터가 어떤 분포를 따르는지 확인해 보겠습니다:
df.hist()
실행 결과

위 히스토그램을 보면 데이터가 대체로 정규분포(normal distribution)를 따르는 것을 알 수 있습니다.
따라서 평균으로부터 3 표준편차 이상 벗어난 값들을 모두 제거한 후, 새로운 데이터프레임을 다시 그려보겠습니다.
std_dev = 3 df = df[(np.abs(stats.zscore(df)) < float(std_dev)).all(axis=1)] df.plot(figsize=(22, 6))
실행 결과

위 결과에서 확인할 수 있듯이, 스파이크 형태의 이상치를 상당 부분 제거하여 데이터를 깨끗하게 정제했습니다.
선형 관계 검증하기
OAT(외기 온도)와 Power(전력 소비량) 사이에 선형 관계가 있는지 확인하기 위해 간단한 산점도(scatter plot)를 그려보겠습니다:
plt.scatter(df['OAT (F)'], df['Power (kW)'])
실행 결과

선형 회귀 모델 학습
모델을 학습하고 성능을 평가하기 위해 Scikit-learn 모듈을 사용하겠습니다. 또한 k-폴드 교차 검증(k-folds cross validation, k=3)을 적용해 모델의 성능을 평가합니다.
X = pd.DataFrame(df['OAT (F)'])
y = pd.DataFrame(df['Power (kW)'])
model = LinearRegression()
scores = []
kfold = KFold(n_splits=3, shuffle=True, random_state=42)
for i, (train, test) in enumerate(kfold.split(X, y)):
model.fit(X.iloc[train,:], y.iloc[train,:])
score = model.score(X.iloc[test,:], y.iloc[test,:])
scores.append(score)
print(scores)실행 결과
[0.38768927735902703, 0.3852220878090444, 0.38451654781487116]
위 코드에서 model = LinearRegression()은 선형 회귀 모델 객체를 생성하며, for 반복문은 데이터셋을 3개의 폴드(fold)로 나눕니다. 반복문 안에서는 각 폴드에 대해 모델을 학습(fit)한 후, 테스트 데이터에 대한 점수(score)를 리스트에 추가하여 성능을 평가합니다.
그런데 결과 점수가 약 0.38 수준으로 만족스럽지 않습니다. 모델 성능을 더 개선할 여지가 있습니다.
시간대(Time of Day) 변수 활용하기
전력 소비량은 하루 중 시간대에 크게 좌우됩니다. 이 정보를 활용해 원-핫 인코딩(one-hot encoding) 방식으로 시간대 변수를 회귀 모델에 추가하면 성능을 크게 향상시킬 수 있습니다.
model = LinearRegression() scores = [] kfold = KFold(n_splits=3, shuffle=True, random_state=42) for i, (train, test) in enumerate(kfold.split(X, y)): model.fit(X.iloc[train,:], y.iloc[train,:]) scores.append(model.score(X.iloc[test,:], y.iloc[test,:])) print(scores)
실행 결과
[0.8074246958895391, 0.8139449185141592, 0.8111379602960773]
점수가 약 0.38에서 약 0.81로 크게 향상되었습니다. 시간대 정보를 모델에 반영하는 것만으로 이토록 큰 차이가 생긴 것입니다.
마무리 및 요약
이번 글에서는 데이터셋을 탐색하고 회귀 모델에 적합한 형태로 전처리하는 기본 과정을 배웠습니다. 또한 모델의 성능을 평가하고, 한계점을 진단한 뒤, 시간대 변수를 추가하여 성능을 개선하는 방법까지 살펴보았습니다. 이러한 과정은 실제 머신러닝 프로젝트에서 데이터 기반 의사결정을 내릴 때 매우 유용하게 활용될 수 있습니다.