튜토리얼

필수 데이터사이언스 방법론 가이드
카테고리는 수준별, 언어별, 분야별, 주제별 순으로 정렬되어 있습니다.

다중 선형 회귀

작성자
sungkenh
작성일
2017-01-12 15:17
조회
372
카테고리 : [ 중급   |   Python   |   마케팅/경영   |   기타 ]

1) 제목


다중 선형 회귀

2) 작성자


컴퓨터정보통신공학과 홍성은

3) 링크 및 출처


Data Science From Scratch

4) 문제 및 개요


5) 데이터


6) 해결방법 및 결과




 6.1 multiple Linear Regression (다중선형회귀)

선형 회귀의 가장 단순한 예제는 한 개의 스칼라 독립 변수 x와 한 개의 스칼라 의존 변수 y의 관계일 것이다. 이를 단순 선형 회귀라 부른다. 여기에서 독립 변수를 여러 개로 확장한 것이 다중 선형 회귀이다. 실세계의 거의 대부분의 문제는 여러 개의 독립 변수를 포함하며, 선형 회귀라 함은 보통 다중 선형 회귀를 일컫는다. 하지만 이러한 경우에도 여전히 응답 변수 y는 한 개의 스칼라 변수이다. 다변량 선형 회귀는 응답 변수 y가 벡터인 경우를 의미한다. 이러한 경우를 일반 선형 회귀라 부른다. 다중 선형 회귀와 다변량 선형 회귀는 다른 의미이므로, 혼동하지 않도록 주의해야 한다.
6.2 Further Assumptions of the Least Squares Model (추정 최소 자승 모델 )

사용자별로 하루에 몇 시간 씩 일하는지, 그리고 박사 학위를 보유하고 있는지 여부를 알고 있습니다. 이 추가 데이터를 사용하여 모델을 개선하고 싶습니다. 따라서보다 독립적 인 변수를 가진 선형 모델을 가정합니다.
더 많은 시간을 보내는 사람들은 사이트에서 보내는 시간을 줄입니다.
친구가 많은 사람들은 더 많은 시간을 일하는 경향이 있습니다. 즉, "실제"모델을 다음과 같이 상상해보십시오.
minutes = α+β1α+β1 friends + β2β2 work hours + εε
그 근무 시간과 친구들은 긍정적 인 상관 관계가 있습니다. 이 경우, 단일 변수 모델의 오류를 최소화 할 때 :
minutes = α+β1α+β1friends + ε
우리는 β1을 과소 평가할 것입니다.

6.3 Fitting the Model

단순 선형 모델에서와 마찬가지로 베타를 선택하여 오류 제곱의 합을 최소화합니다. 정확한 솔루션을 찾는 것은 손으로하는 것만으로 간단하지 않습니다. 즉 그라디언트 디센트를 사용해야합니다. 최소화 할 오류 함수를 만드는 것으로 시작하겠습니다. 확률적인 그래디언트 디센트의 경우, 단일 예측에 해당하는 제곱 된 오차 만 원할 것입니다.
In [1]:
from collections import Counter
from functools import partial
from linear_algebra import dot, vector_add
from stats import median, standard_deviation
from probability import normal_cdf
from gradient_descent import minimize_stochastic
from simple_linear_regression import total_sum_of_squares
import math, random

In [2]:

def error(x_i, y_i, beta):
return y_i - predict(x_i, beta)
def squared_error(x_i, y_i, beta):
return error(x_i, y_i, beta) ** 2
def predict(x_i, beta):
return dot(x_i, beta)

In [3]:

def squared_error_gradient(x_i, y_i, beta):
"""the gradient corresponding to the ith squared error term"""
return [-2 * x_ij * error(x_i, y_i, beta)
for x_ij in x_i]
확률 적 구배 강하를 사용하여 최적의 베타를 찾을 준비가되었습니다.
In [4]:

def estimate_beta(x, y):
beta_initial = [random.random() for x_i in x[0]]
return minimize_stochastic(squared_error,
squared_error_gradient,
x, y,
beta_initial,
0.001)
x = [[1,49,4,0],[1,41,9,0],[1,40,8,0],[1,25,6,0],[1,21,1,0],[1,21,0,0],[1,19,3,0],[1,19,0,0],[1,18,9,0],[1,18,8,0],[1,16,4,0],[1,15,3,0],[1,15,0,0],
[1,15,2,0],[1,15,7,0],[1,14,0,0],[1,14,1,0],[1,13,1,0],[1,13,7,0],[1,13,4,0],[1,13,2,0],[1,12,5,0],[1,12,0,0],[1,11,9,0],[1,10,9,0],[1,10,1,0],[1,10,1,0],
[1,10,7,0],[1,10,9,0],[1,10,1,0],[1,10,6,0],[1,10,6,0],[1,10,8,0],[1,10,10,0],[1,10,6,0],[1,10,0,0],[1,10,5,0],[1,10,3,0],[1,10,4,0],[1,9,9,0],[1,9,9,0],
[1,9,0,0],[1,9,0,0],[1,9,6,0],[1,9,10,0],[1,9,8,0],[1,9,5,0],[1,9,2,0],[1,9,9,0],[1,9,10,0],[1,9,7,0],[1,9,2,0],[1,9,0,0],[1,9,4,0],[1,9,6,0],[1,9,4,0],
[1,9,7,0],[1,8,3,0],[1,8,2,0],[1,8,4,0],[1,8,9,0],[1,8,2,0],[1,8,3,0],[1,8,5,0],[1,8,8,0],[1,8,0,0],[1,8,9,0],[1,8,10,0],[1,8,5,0],[1,8,5,0],[1,7,5,0],
[1,7,5,0],[1,7,0,0],[1,7,2,0],[1,7,8,0],[1,7,10,0],[1,7,5,0],[1,7,3,0],[1,7,3,0],[1,7,6,0],[1,7,7,0],[1,7,7,0],[1,7,9,0],[1,7,3,0],[1,7,8,0],[1,6,4,0],
[1,6,6,0],[1,6,4,0],[1,6,9,0],[1,6,0,0],[1,6,1,0],[1,6,4,0],[1,6,1,0],[1,6,0,0],[1,6,7,0],[1,6,0,0],[1,6,8,0],[1,6,4,0],[1,6,2,1],[1,6,1,1],[1,6,3,1],
[1,6,6,1],[1,6,4,1],[1,6,4,1],[1,6,1,1],[1,6,3,1],[1,6,4,1],[1,5,1,1],[1,5,9,1],[1,5,4,1],[1,5,6,1],[1,5,4,1],[1,5,4,1],[1,5,10,1],[1,5,5,1],[1,5,2,1],
[1,5,4,1],[1,5,4,1],[1,5,9,1],[1,5,3,1],[1,5,10,1],[1,5,2,1],[1,5,2,1],[1,5,9,1],[1,4,8,1],[1,4,6,1],[1,4,0,1],[1,4,10,1],[1,4,5,1],[1,4,10,1],[1,4,9,1],
[1,4,1,1],[1,4,4,1],[1,4,4,1],[1,4,0,1],[1,4,3,1],[1,4,1,1],[1,4,3,1],[1,4,2,1],[1,4,4,1],[1,4,4,1],[1,4,8,1],[1,4,2,1],[1,4,4,1],[1,3,2,1],[1,3,6,1],[1,3,4,1],
[1,3,7,1],[1,3,4,1],[1,3,1,1],[1,3,10,1],[1,3,3,1],[1,3,4,1],[1,3,7,1],[1,3,5,1],[1,3,6,1],[1,3,1,1],[1,3,6,1],[1,3,10,1],[1,3,2,1],[1,3,4,1],[1,3,2,1],[1,3,1,1],
[1,3,5,1],[1,2,4,1],[1,2,2,1],[1,2,8,1],[1,2,3,1],[1,2,1,1],[1,2,9,1],[1,2,10,1],[1,2,9,1],[1,2,4,1],[1,2,5,1],[1,2,0,1],[1,2,9,1],[1,2,9,1],[1,2,0,1],[1,2,1,1],
[1,2,1,1],[1,2,4,1],[1,1,0,1],[1,1,2,1],[1,1,2,1],[1,1,5,1],[1,1,3,1],[1,1,10,1],[1,1,6,1],[1,1,0,1],[1,1,8,1],[1,1,6,1],[1,1,4,1],[1,1,9,1],[1,1,9,1],[1,1,4,1],
[1,1,2,1],[1,1,9,1],[1,1,0,1],[1,1,8,1],[1,1,6,1],[1,1,1,1],[1,1,1,1],[1,1,5,1]]
daily_minutes_good = [68.77,51.25,52.08,38.36,44.54,57.13,51.4,41.42,31.22,34.76,54.01,38.79,47.59,49.1,27.66,41.03,36.73,48.65,28.12,46.62,35.57,32.98,35,26.07,
23.77,39.73,40.57,31.65,31.21,36.32,20.45,21.93,26.02,27.34,23.49,46.94,30.5,33.8,24.23,21.4,27.94,32.24,40.57,25.07,19.42,22.39,18.42,46.96,23.72,26.41,26.97,
36.76,40.32,35.02,29.47,30.2,31,38.11,38.18,36.31,21.03,30.86,36.07,28.66,29.08,37.28,15.28,24.17,22.31,30.17,25.53,19.85,35.37,44.6,17.23,13.47,26.33,35.02,
32.09,24.81,19.33,28.77,24.26,31.98,25.73,24.86,16.28,34.51,15.23,39.72,40.8,26.06,35.76,34.76,16.13,44.04,18.03,19.65,32.62,35.59,39.43,14.18,35.24,40.13,
41.82,35.45,36.07,43.67,24.61,20.9,21.9,18.79,27.61,27.21,26.61,29.77,20.59,27.53,13.82,33.2,25,33.1,36.65,18.63,14.87,22.2,36.81,25.53,24.62,26.25,18.21,
28.08,19.42,29.79,32.8,35.99,28.32,27.79,35.88,29.06,36.28,14.1,36.63,37.49,26.9,18.58,38.48,24.48,18.95,33.55,14.24,29.04,32.51,25.63,22.22,19,32.73,
15.16,13.9,27.2,32.01,29.27,33,13.74,20.42,27.32,18.23,35.35,28.48,9.08,24.62,20.12,35.26,19.92,31.02,16.49,12.16,30.7,31.22,34.65,13.13,27.51,33.2,31.57,
14.1,33.42,17.44,10.12,24.42,9.82,23.39,30.93,15.03,21.67,31.09,33.29,22.61,26.89,23.48,8.38,27.81,32.35,23.84]
random.seed(0)
beta = estimate_beta(x, daily_minutes_good)
minutes = 30.63+0.972 friends−1.868 work hours+0.911 phd
6.4 Goodness of Fit (적합도)

회귀 변수에 새 변수를 추가하면 반드시 R 제곱이 증가합니다. 결국, 단순 회귀 모델은 "근무시간"과 "PhD"의 계수가 모두 0인 다중 회귀 모델의 특수한 경우에 불과합니다.

In [5]:

def multiple_r_squared(x, y, beta):
sum_of_squared_errors = sum(error(x_i, y_i, beta) ** 2
for x_i, y_i in zip(x, y))
return 1.0 - sum_of_squared_errors / total_sum_of_squares(y)

6.5 Digression : The Bootstrap

일부 (우리에게 알려지지 않은) 분포에 의해 생성 된 n 개의 데이터 포인트 샘플을 가지고 있다고 가정 해보십시오.data = get_sample (num_points = n)
5 장에서 관찰 된 데이터의 중앙값을 계산하는 함수를 작성했습니다.이 함수는 분포 자체의 중앙값을 추정하는 데 사용할 수 있습니다. 그러나 우리가 우리의 견적에 대해 얼마나 확신 할 수 있습니까? 샘플의 모든 데이터가 100에 매우 가깝다면 실제 중앙값은 100에 가깝습니다. 샘플의 데이터의 약 절반이 0에 가까우며 나머지 절반이 200에 가까울 경우 중간 값에 대해서는 거의 확실하지 않습니다.
우리가 반복적으로 새로운 표본을 얻을 수 있다면, 각 표본의 중간 값을 계산하고 그 중앙값 분포를 관찰 할 수 있습니다. 보통은 할 수 없습니다. 우리가 대신 할 수있는 것은 데이터에서 대체 된 n 개의 데이터 포인트를 선택하여 새로운 데이터 세트를 부트 스트랩 (bootstrap) 한 다음 해당 합성 데이터 세트의 중앙값을 계산하는 것입니다.

In [9]:
def bootstrap_sample(data):
return [random.choice(data) for _ in data]
def bootstrap_statistic(data, stats_fn, num_samples):
return [stats_fn(bootstrap_sample(data))
for _ in range(num_samples)]

6.6 Standard Errors of Regression Coefficients (회귀 계수의 오류 수준)

우리는 회귀 계수의 표준 오차를 추정하는 데 동일한 접근법을 사용할 수 있습니다. 우리는 반복적으로 데이터의 bootstrap_sample을 가져 와서 샘플을 기반으로 베타를 추정합니다. 독립 변수 중 하나 (예 : num_friends)에 해당하는 계수가 표본에서 크게 변하지 않는다면 우리는 우리의 추정치가 상대적으로 엄격하다고 확신 할 수 있습니다. 계수가 표본간에 크게 다르다면 우리는 우리의 추정에 확신을 가질 수 없습니다.

In [*]:
def estimate_sample_beta(sample):
x_sample, y_sample = zip(*sample)
return estimate_beta(x_sample, y_sample)

random.seed(0)
bootstrap_betas = bootstrap_statistic(list(zip(x, daily_minutes_good)),
estimate_sample_beta,
100)

각 계수의 표준 편차를 추정 할 수 있습니다

In [8]:

bootstrap_standard_errors = [
standard_deviation([beta[i] for beta in bootstrap_betas])
for i in range(4)]