https://www.w3schools.com/python/python_ml_linear_regression.asp

 

Python Machine Learning Linear Regression

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

Regression

Regression(회귀)는 통상 각 변수들의 관계를 찾을 때 사용하는 개념입니다.

이러한 변수들의 관계를 확인하여 미래의 값을 예측하는 것입니다.

Linear Regression

Linear Regression(선형 회귀) 는 가장 기초적인 머신러닝이라 볼 수 있습니다.

w3schools에서 소개하는 아래 그림을 보시면,

위에 분산된 점들의 관계, 경향성을 일정하게 진행하는 직선으로 표현하는 것입니다.

그럼 어떻게 동작하는지 코딩으로 보겠습니다.

일단 분산된 점들에 대한 scatter plot을 그려보겠습니다.

1
2
3
4
5
6
7
import matplotlib.pyplot as plt
 
= [5,7,8,7,2,17,2,9,4,11,12,9,6]
= [99,86,87,88,111,86,103,87,94,78,77,85,86]
 
plt.scatter(x, y)
plt.show()
cs

위와 같이 x와 y라는 리스트를 작성하고 각 리스트의 동일한 순서의 값들이 결국 짝을 이뤄 (x, y) 값을 구성하게 되고 이를 그래프로 그려봅니다.

이제 본격적으로 scipy 라이브러리를 임포트 하여 선형 회귀의 선을 그려봅시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt
from scipy import stats
 
= [5,7,8,7,2,17,2,9,4,11,12,9,6]
= [99,86,87,88,111,86,103,87,94,78,77,85,86]
 
slope, intercept, r, p, std_err = stats.linregress(x, y)
 
def myfunc(x):
  return slope * x + intercept
 
mymodel = list(map(myfunc, x))
 
plt.scatter(x, y)
plt.plot(x, mymodel)
plt.show()
cs

이제 구체적으로 각 코드의 설명을 봅니다.

 

import matplotlib.pyplot as plt
from scipy import stats

scipy의 stats 라이브러리를 특정하여 임포트합니다. matplotlib는 물론 그래프를 그리기 위한 라이브러리겠지요.

 

x = [5,7,8,7,2,17,2,9,4,11,12,9,6]
y = [99,86,87,88,111,86,103,87,94,78,77,85,86]

각 좌표들의 x, y축 값을 확인합니다. 앞서 말했듯이 각 리스트의 동일한 순서의 값이 짝을 이루어 좌표값을 만듭니다.

 

slope, intercept, r, p, std_err = stats.linregress(x, y)

scipy 라이브러리의 stats.linregress(x,y) 함수를 이용하여 한번에 선형회귀 머신러닝을 수행할 수 있습니다.

x와 y리스트를 이용하여 총 5개의 변수를 생성해 낼 수 있고 이중 선을 구성하는 것은 slope(경사)값과 intercept(절편)값입니다. 일단 이어서 코드를 보면,

 

def myfunc(x):
    return slope * x + intercept

'경사' 곱하기 'x값' + '절편'을 구성하는 함수를 만들고 여기서 절편은 y절편입니다.

myfunc(x) = y 가 되는 것입니다.

 

mymodel = list(map(myfunc, x))

일단 여기서는 list(map(함수, 리스트)) 라는 정형화된 공식같이 사용하는 코드라고 보시면 되고 결국 x값에 대응하는 선형회귀 선의 y값 리스트를 만든다고 보시면 됩니다.

 

plt.scatter(x, y)

plt.plot(x, mymodel)

plt.show()

두번째 plt.plot()을 이용하여 그래프를 그립니다.

 

R for Relationship

위에서 설명한 stats.linregress(x,y)를 이용하여 선형회귀에 대한 정보를 얻을 수 있는데 slope, intercept 다음의 r은 relationship을 의도하여 r로 표현하였습니다. x축 값들과 y축 값들간의 관계의 정도를 의미하고 실제 각 값들의 관계가 없다면 이러한 선형 회귀를 통한 예측이 전혀 의미가 없습니다.

 

그렇기 때문에 로또는 이후 어떠한 머신러닝 기법을 통해서라도 번호를 예측할 수 없습니다. 1회차 당첨 번호와 100회차 당첨 번호간에는 실제 어떠한 관계도 없기 때문입니다.😅

 

코드로 r값을 보면,

1
2
3
4
5
6
7
8
from scipy import stats
 
= [5,7,8,7,2,17,2,9,4,11,12,9,6]
= [99,86,87,88,111,86,103,87,94,78,77,85,86]
 
slope, intercept, r, p, std_err = stats.linregress(x, y)
 
print(r)
cs

r값은 약 0.75이고 한마디로 위의 값들의 관계의 정도는 0.75 즉 75%정도로 볼 수 있고 이 정도가 1에 가까울수록, 100%에 가까울수록 예측값의 정확도가 올라간다는 말입니다.

 

하지만 다시 한번 더 보자면 로또 당첨번호의 경우, 각 값들의 예측값의 관계 정도 r값이 1에 가깝게 나왔더라도 이는 순전히 우연일 뿐이지 이를 이용한 예측값이 맞으리라는 보장은 없습니다.

 

Predict Future Values

이제 진짜 머신러닝을 이용한 첫 예측을 해봅시다.

x = [5,7,8,7,2,17,2,9,4,11,12,9,6]
y = [99,86,87,88,111,86,103,87,94,78,77,85,86]

x리스트 값들은 자동차들의 연식입니다. (출시후 몇년이 지났는지)y리스트 값들은 자동차들의 현재 속도입니다.그렇다면 10년된 자동차의 속도는 어느정도 될 것인가?

 

가장 먼저 생각해 볼 것은 x값과 y값이 실제로 관계가 있는지를 확인해야 합니다. 차가 오래될 수록 속도의 변화가 있다. 이는 충분히 가능한 관계이기 때문에 이후 진행하는 선형회귀 예측이 어느정도 유효하다고 볼 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
from scipy import stats
 
= [5,7,8,7,2,17,2,9,4,11,12,9,6]
= [99,86,87,88,111,86,103,87,94,78,77,85,86]
 
slope, intercept, r, p, std_err = stats.linregress(x, y)
 
def myfunc(x):
  return slope * x + intercept
 
speed = myfunc(10)
 
print(speed)
cs

각설하고 myfunc(x) = y 함수를 만들어서 x값을 넣으면 예측되는 y값을 도출해 내는 것이고 10년된 차의 속도는 약 85.59308314937454 약 86정도의 속도로 예상되는 것입니다.

그래프로 그려보면 위와 같습니다.

아까 언급한대로 r값은 약 0.75로 75%의 신빙성이 있다고 보면 됩니다.

 

위의 흩뿌려진 점들의 배치를 보았을 때 컴퓨터와 같이 정확한 선을 그리기는 힘들겠지만 어느정도 분포의 경향을 보면 추정할 수 있다는 점을 알 수 있습니다. 하지만 뒤이어 나오는 다음의 scatter plot의 경우는 선형회귀 선을 그리는 것이 거의 무의미하다고 보면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt
from scipy import stats
 
= [89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
= [21,46,3,35,67,95,53,72,58,10,26,34,90,33,38,20,56,2,47,15]
 
slope, intercept, r, p, std_err = stats.linregress(x, y)
 
def myfunc(x):
  return slope * x + intercept
 
mymodel = list(map(myfunc, x))
 
plt.scatter(x, y)
plt.plot(x, mymodel)
plt.show()
cs

실제 scatter plot을 보시면 어떠한 직선으로 그릴 수 있는 경향성을 찾기 힘들고(컴퓨터는 거의 어거지로 그린것 같긴 합니다.😅) 앞서말한 관계 r값 역시 0.013정도로 거의 무의미하다고 보시면 됩니다.

 

아마 이정도만으로도 실생활에 어느정도 적용해 볼 만 한 것 같습니다.

+ Recent posts