Python, Machine Learning 배우기 (w3schools로부터) (4) Linear Regression, 선형 회귀
https://www.w3schools.com/python/python_ml_linear_regression.asp
Regression
Regression(회귀)는 통상 각 변수들의 관계를 찾을 때 사용하는 개념입니다.
이러한 변수들의 관계를 확인하여 미래의 값을 예측하는 것입니다.
Linear Regression
Linear Regression(선형 회귀) 는 가장 기초적인 머신러닝이라 볼 수 있습니다.
w3schools에서 소개하는 아래 그림을 보시면,
위에 분산된 점들의 관계, 경향성을 일정하게 진행하는 직선으로 표현하는 것입니다.
그럼 어떻게 동작하는지 코딩으로 보겠습니다.
일단 분산된 점들에 대한 scatter plot을 그려보겠습니다.
1
2
3
4
5
6
7
|
import matplotlib.pyplot as plt
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]
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
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]
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
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]
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
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]
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
x = [89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
y = [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정도로 거의 무의미하다고 보시면 됩니다.
아마 이정도만으로도 실생활에 어느정도 적용해 볼 만 한 것 같습니다.