일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Machine Learning
- node.js
- 빅 데이터
- 김양재
- R
- 확률
- Big Data
- data science
- MongoDB
- Artificial Intelligence
- 빅데이타
- nodeJS
- WebGL
- 빅 데이타
- 몽고디비
- 김양재 목사
- No SQL
- 김양재 목사님
- 인공지능
- probability
- 빅데이터
- Statistics
- 데이터 과학
- c++
- Deep learning
- 주일설교
- 딥러닝
- 통계
- 우리들교회
- openCV
- Today
- Total
Scientific Computing & Data Science
[Data Mining with R] R / Simple Linear Regression - Part 1. 본문
[Data Mining with R] R / Simple Linear Regression - Part 1.
cinema4dr12 2014. 11. 23. 14:45by Geol Choi |
이번 글에서는 Linear Regression에 대한 기초 통계 이론에 대한 소개와 이에 대한 R 프로그래밍에 대해 알아보기로 한다.
Linear Regression은 간단하게 말해, 관찰된 데이터들의 변수들 간 관계를 1차원적인 Graph로 표현(이를 fitting이라고 함)하는 것이다. Linear Regression은 통계학의 역사관점에서 볼 때, 특정 변수가 다른 변수와 어떤 상관관계인지를 알아보기 위한 수단으로 발전해 왔다. 데이터를 관찰하여 이에 대한 모델을 세우고 이 모델을 통해 데이터에 대한 예측을 하고자 하는 것이 목표이며, 더 나아가 이에 대한 신뢰도를 어떻게 평가할 수 있는가가 이 이론에 대한 거의 전부라고 할 수 있다.
물론 모든 데이터의 경향이 1차원적이지 않다. 아니 1차원적이 아닌 것이 훨씬 많다. 다만, 경향성을 평가하기 위한 모델을 공부하는 데 있어 Linear Regression의 이해는 필수적이며, 향후 Non-linear Regression이라든가 Multi-variable Linear Regression으로의 이해를 하기 위한 기본 단계라고 보면 된다. 다중 변수에 대한 Linear Regression과 구분짓기 위하여 단일 변수에 대해서는 Simple Linear Regression이라고 칭하도록 한다. 그러나 이 글에서는 편의상 "Simple"을 생략하기로 한다.
Theoretical Background
다음과 같이 n개의 관찰된 데이터가 있다고 하자:
\((x_1,y_1),...,(x_n,y_n)\)
여기서 \(y_i\)는 랜덤변수 \(Y_i\)로부터 관찰된 데이터로서 기울기(slope) \(\beta_1\)와 절편(Intercept) \(\beta_0\)를 갖는 Linear Regression 모델은
\(y_i=\beta_0+\beta_1x_i+\epsilon_i\)
와 같이 표현되며, Error Term \(\epsilon_{i}\)는 평균 0, 표준편차 \(\sigma^{2}\)의 정규분포를 따른다. 즉,
\(\epsilon_{i}\sim N(0,\sigma^{2})\)
이며, 실제 관측된 데이터 \(y_{i}\)와 Linear Regression 모델을 이용하여 Fitting된 \(\hat{y}_{i}\)의 차이를 의미한다. 즉,
\(\epsilon_{i}=y_{i}-\hat{y}_{i}=y_{i}-(\beta_{0}+\beta_{1}x_{i})\)
또한 랜덤변수 \(Y_{i}\)는 다음과 같은 정규분포를 따른다.
\(Y_{i}\sim N(\beta_{0}+\beta_{1}x_{i},\sigma^{2})\)
그러면 \(\beta_{0}\)와 \(\beta_{1}\)는 어떻게 구해지는지 알아보자.
Basic Idea는 매우 단순하다. 각 변수 \(X_{i}\)에 대하여 관측된 값 \(y_i\)와 Fitting된 값 \(\hat{y}_{i}\)의 차이의 제곱의 합을 최소화하는 Line을 찾아내는 것이다. 제곱을 하는 이유는, 두 값의 상대적 차이에 따라 0보다 크거나 작을 수도 있기 때문이며, 이러한 모델을 Least Squares Model이라고 한다. 이를 수학적으로 표현하면,
\(Q=\sum_{i}^{n}\epsilon_{i}^{2}=\sum_{i}^{n}[y_{i}-(\beta_{0}+\beta_{1}x_{i})]^2\)
Q를 Linear Squares Fit이라고 한다. 이를 최소화하는 \(\beta_{0}\) 및 \(\beta_{1}\)는 Q를 각각에 대해 편미분한 값이 0이 되도록 하여 구할 수 있다. (이에 대한 자세한 내용은 Optimisation 이론을 참고하기 바란다. 사실 편미분한 값이 0인 위치에서 최소값을 갖는 것에 대해서는 Convexity 조건을 만족하는지도 확인하는 것이 맞으나 일단 이 조건에 대한 설명은 생략하도록 한다.)
\(\frac{\partial Q}{\partial \beta_{0}}=-\sum_{i}^{n}2[y_{i}-(\beta_{0}-\beta_{1}x_{i})]=0\)(*)
그리고
\(\frac{\partial Q}{\partial \beta_{0}}=\sum_{i}^{n}2x_{i}[y_{i}-(\beta_{0}+\beta_{1}x_{i})]=0\) (**)
이며, (*)과 (**)식을 각각 정리하면,
\(n \beta_{0}+(\sum_{i}^{n}x_{i})\beta_{1}=\sum_{i}^{n}y_{i}\) (***)
\((\sum_{i}^{n}x_{i})\beta_{0}+(\sum_{i}^{n}x_{i}^{2}\beta_{1})=\sum_{i}^{n}x_{i}y_{i}\) (****)
(***)과 (****)을 연립하여 풀면,
\(\hat{\beta_{1}}=\frac{n\sum_{i}^{n}x_{i}y_{i}-(\sum_{i}^{n}x_{i})(\sum_{i}^{n}y_{i})}{n\sum_{i}^{n}x_{i}^{2}-(\sum_{i}^{n}x_{i})^2}\)
\(\hat{\beta_{0}}=\frac{\sum_{i}^{n}{y_{i}}}{n} - \hat{\beta_{1}}\frac{\sum_{i}^{n}{x_{i}}}{n} = \bar{y}-\hat{\beta_{1}\bar{x}}\)
가 된다. 여기서 \(\hat{\beta_{0}}\)와 \(\hat{\beta_{1}}\)는 계산된(Estimate) 값을 의미한다. 한편,
\(S_{xx}=\sum_{i}^{n}{(x_{i}-\bar{x})^2}=\sum_{i}^{n}{x_{i}^{2}-n\bar{x}^{2}}=\sum_{i}^{n}{(\frac{\sum_{i}^{n}{x_{i}}}{n})^2}\)
및
\(S_{XY}=\sum_{i}^{n}{(x_{i}-\bar{x})(y_{i}-\bar{y})}=\sum_{i}^{n}{x_{i}y_{i}-n\bar{x}\bar{y}}=\sum_{i}^{n}{\frac{(\sum_{i}^{n}{x_{i}})(\sum_{i}^{n}{y_{i}})}{n}}\)
이므로, \(\hat{\beta_{1}}\)는 다음과 같이 다시 쓸 수 있다.
\(\hat{\beta_{1}}=\frac{S_{XY}}{S_{XX}}\)
오차에 대한 제곱합 SSE는 다음과 같이 정의된다:
\(\mathbf{SSE}=\sum_{i}^{n}{\epsilon_i^2}=\sum_{i}^{n}{(y_{i}-\hat{y}_{i})^2}=\sum_{i}^{n}{(y_{i}-(\beta_{0}+\beta_{1}x_{i}))^2}\)
이를 풀어쓰면,
\(\mathbf{SSE}=\sum_{i}^{n}{y_{i}^{2}}-\hat{\beta_{0}}\sum_{i}^{n}{}-\hat{\beta_{1}}\sum_{i}^{n}{x_{i}y_{i}}\)
이며, 오차 분산 \(\hat{\sigma}_{0}^{2}\)은
\(\hat{\sigma}_{0}^{2}=\frac{\mathbf{SSE}}{n-2}=\frac{\sum_{i}^{n}{y_{i}^{2}}-\beta_{0}\sum_{i}^{n}{y_{i}}-\hat{\beta_{1}\sum_{i}^{n}{x_{i}y_{i}}}}{n-2}\)
이다. n이 아닌 (n-2)로 나누는 이유는 Unbiased Estimator를 위한 것인데, 이에 대한 자세한 내용은 여기를 참고하기 바란다. 지금까지의 파라미터 추정을 계산하는 방법을 정리하면 다음과 같다:
\(S_{XX}=\sum_{i}^{n}{x_i^2}-{\begin{pmatrix}\sum_{i}^{n}{x_i}\end{pmatrix}^2}/{n}\)
\(S_{XY}=\sum_{i}^{n}{x_{i}y_{i}}-{(\sum_{i}^{n}{x_i})(\sum_{i}^{n}{y_i})}/{n}\)
\(\hat{\beta}_{1}=S_{XY}/S_{XX}\)
\(\hat{\beta}_{0}=\bar{y}-\hat{\beta}_{1}\hat{x}\)
\(\mathbf{SSE}=\sum_{i}^{n}{y_i^2}-\hat{\beta}_{0}\sum_{i}^{n}{y_i}-\hat{\beta}_{1}\sum_{i}^{n}{x_i y_i}\)
\(\hat{\sigma}^2=\mathbf{SSE}/(n-2)\)
R Code
linearRegression.R:
# @Title: Linear Regression # @Author: Geol Choi (cinema4dr12@gmail.com) # @Purpose: To calculate intercept(beta0) and slope(beta1) for linear regression model # and also sum of square error linearRegression = function( x, y ) { sum_x = sum(x); sum_y = sum(y); sum_x2 = sum(x * x); sum_y2 = sum(y * y); sum_xy = sum(x * y); # number of data points n = length(x); Sxx = sum_x2 - (sum_x)^2/n; Sxy = sum_xy - (sum_x * sum_y)/n; # slope of linear regression model beta1 = Sxy/Sxx; # intercept of linear regression model beta0 = mean(y) - beta1 * mean(x); # residual error err = (sum_y2 - beta0*sum_y - beta1*sum_xy) / (n-2); return(c(beta0, beta1, err)); }
두 변수의 관계는 대체적으로 음의 상관관계임을 알 수 있다. 이에 대한 R 코드는 다음과 같다:
myPlot.R:
myPlot = function() { library(ggplot2); ggplot() + coord_cartesian() + scale_x_continuous() + scale_y_continuous() + layer( data = mtcars, mapping = aes(x = mpg, y = disp, colour = factor(disp)), stat = "identity", geom = "point", size = 3 ) }
> install.packages("ggplot2")
> lr = linearRegression(mtcars$mpg, mtcars$disp)
> lr
[1] 580.88382 -17.42912 4470.68729
Linear Regression 잘 계산되었음을 알 수 있다. 이에 대한 코드는 다음과 같다(코드가 썩 잘 정리되지는 않은 것 같다):
myPlot.R:
myPlot = function() { library(ggplot2); # linear regression model x1 = min(mtcars$mpg); x2 = max(mtcars$mpg); y1 = 580.88382 - 17.42912*x1; y2 = 580.88382 - 17.42912*x2; vec1 = c(x1,x2); vec2 = c(y1,y2); df = data.frame(x = vec1, y = vec2); ggplot() + coord_cartesian() + scale_x_continuous() + scale_y_continuous() + layer( data = mtcars, mapping = aes(x = mpg, y = disp, colour = factor(disp)), stat = "identity", geom = "point", size = 3 ) + layer( data = df, mapping = aes(x = x, y = y), stat = "identity", geom = "line", size = 1 ) }
> x = mtcars$mpg;
> y = mtcars$disp;
> model = lm(y ~ x);
> model
Call:
lm(formula = y ~ x)
Coefficients:
(Intercept) x
580.88 -17.43
Shiny App
상기 어플리케이션의 코드는 다음과 같다. (코드에 대한 설명은 코드 내 주석으로 대신한다.)
ui.R:
# @title: Linear Regression for mtcars # @author: Geol Choi, ph.D (cinema4dr12@gmail.com) # @date: 2014.11.30 library(ggplot2); shinyUI(fluidPage( title = "Linear Regression of mtcars", theme = "bootstrap.css", # Application title headerPanel(h2("Linear Regression by CINEMA4DR12")), # Sidebar sidebarPanel( h3("mtcars"), selectInput("input_x", label = HTML("<h4>    X</h4>"), choices = list("Miles per Gallon" = 1, "Number of Cylinders" = 2, "Displacement" = 3, "Gross Horsepower" = 4, "Rear Axle Ratio" = 5, "Weight" = 6, "1/4 Mile Time" = 7, "V/S" = 8, "Transmission" = 9, "Number of Forward Gears" = 10, "Number of Carburetors" = 11 ), selected = 1 ), selectInput("input_y", label = HTML("<h4>    Y</h4>"), choices = list("Miles per Gallon" = 1, "Number of Cylinders" = 2, "Displacement" = 3, "Gross Horsepower" = 4, "Rear Axle Ratio" = 5, "Weight" = 6, "1/4 Mile Time" = 7, "V/S" = 8, "Transmission" = 9, "Number of Forward Gears" = 10, "Number of Carburetors" = 11 ), selected = 1 ) ), # Show the generated 3d bivar plot mainPanel( tabsetPanel( tabPanel("Plot", plotOutput("plot")), tabPanel("Summary", verbatimTextOutput("summary")) ) ) ))
server.R:
# @title: Linear Regression for mtcars # @author: Geol Choi, ph.D (cinema4dr12@gmail.com) # @date: 2014.11.30 library(shiny); library(ggplot2); shinyServer(function(input, output, session) { Data = reactive({ # get selection x & y from select box x_val = input$input_x y_val = input$input_y switch(x_val, "1" = { vec1 = mtcars$mpg name1 = "mpg" }, "2" = { vec1 = mtcars$cyl name1 = "cyl" }, "3" = { vec1 = mtcars$disp name1 = "disp" }, "4" = { vec1 = mtcars$hp name1 = "hp" }, "5" = { vec1 = mtcars$drat name1 = "drat" }, "6" = { vec1 = mtcars$wt name1 = "wt" }, "7" = { vec1 = mtcars$qsec name1 = "qsec" }, "8" = { vec1 = mtcars$vs name1 = "vs" }, "9" = { vec1 = mtcars$am name1 = "am" }, "10" = { vec1 = mtcars$gear name1 = "gear" }, "11" = { vec1 = mtcars$carb name1 = "carb" } ) switch(y_val, "1" = { vec2 = mtcars$mpg name2 = "mpg" }, "2" = { vec2 = mtcars$cyl name2 = "cyl" }, "3" = { vec2 = mtcars$disp name2 = "disp" }, "4" = { vec2 = mtcars$hp name2 = "hp" }, "5" = { vec2 = mtcars$drat name2 = "drat" }, "6" = { vec2 = mtcars$wt name2 = "wt" }, "7" = { vec2 = mtcars$qsec name2 = "qsec" }, "8" = { vec2 = mtcars$vs name2 = "vs" }, "9" = { vec2 = mtcars$am name2 = "am" }, "10" = { vec2 = mtcars$gear name2 = "gear" }, "11" = { vec2 = mtcars$carb name2 = "carb" } ) df = data.frame(tmp1 = vec1, tmp2 = vec2); names(df) = c(name1, name2); return(df); }) output$plot = renderPlot({ myPlot(Data()) }) output$summary = renderPrint({ mySummary(Data()) }) }) ################################################ # FUNCTION : myPlot ################################################ myPlot = function(myData) { # extract x & y from myData x = myData[,1]; y = myData[,2]; # calculate linear regression from R build-in function lm(...) myModel = lm(y ~ x); coeff = coefficients(myModel); beta0 = as.numeric(coefficients(myModel)[1]); beta1 = as.numeric(coefficients(myModel)[2]); # construct a line graph from the linear regression model x1 = min(x); x2 = max(x); y1 = beta0 + beta1*x1; y2 = beta0 + beta1*x2; vec1 = c(x1,x2); vec2 = c(y1,y2); df = data.frame(x = vec1, y = vec2); name1 = names(myData)[1]; name2 = names(myData)[2]; aesData = aes_string(x = name1, y = name2); # plotting ggplot() + coord_cartesian() + scale_x_continuous() + scale_y_continuous() + layer( data = mtcars, mapping = aesData, stat = "identity", geom = "point", size = 3 ) + layer( data = df, mapping = aes(x = x, y = y), colour = "red", stat = "identity", geom = "line", size = 1 ) } ################################################ # FUNCTION : mySummary ################################################ mySummary = function(myData) { # extract x & y from myData x = myData[,1]; y = myData[,2]; # calculate linear regression from R build-in function lm(...) myModel = lm(y ~ x); summary(myModel); }
이것으로 Linear Regression Part 1.을 마치도록 하겠다. Part 2.에서는 Linear Regression 모델에 대한 파라미터 추정에 대한 이론을 다루도록 하겠다.
'Data Science > Data Mining with R Programming' 카테고리의 다른 글
[Data Mining with R] R / Deploying Shiny Server on Amazon EC2 (0) | 2015.01.04 |
---|---|
[Data Mining with R] R / Simple Linear Regression - Part 2. (0) | 2014.12.14 |
[Data Mining with R] R과 MongoLab 연동하기 팁 (0) | 2014.11.03 |
[Data Mining with R] ShinyApps / Reactive Output에 대하여 (0) | 2014.11.02 |
[Data Mining with R] R / R에서 한글입력 시 깨짐 현상 해결 팁 (2) | 2014.11.01 |