wget는 정말 편리한 명령줄 유틸리티지만, 안타깝게도 OS X에는 포함되지 않았다. 물론 Curl은 적절한 대체물이 될 수 있지만, 종종 wget로 스크립트가 쓰여지고, curl을 사용하는 것으로 변환하는 것은 어렵고 시간이 오래 걸릴 수 있어서 wget이 선호되는 경향이 있다.
homebrew로 wget을 설치하면 된다.
1
!brew install wget
Updating Homebrew...
[34m==>[0m [1mAuto-updated Homebrew![0m
Updated 2 taps (homebrew/core and homebrew/cask).
[34m==>[0m [1mUpdated Formulae[0m
plenv postgresql@11 swiftformat tomee-webprofile
postgresql postgresql@9.5 tomee-plume
postgresql@10 postgresql@9.6 tomee-plus
[34m==>[0m [1mUpdated Casks[0m
cryo switchresx
[33mWarning:[0m wget 1.20.3_2 is already installed and up-to-date
To reinstall 1.20.3_2, run `brew reinstall wget`
Uninstalling node... (4,660 files, 60.3MB)
[31mError:[0m Refusing to uninstall /usr/local/Cellar/icu4c/66.1
because it is required by graphviz, harfbuzz and pango, which are currently installed.
You can override this and force removal with:
brew uninstall --ignore-dependencies icu4c
Unlinking /usr/local/Cellar/icu4c/66.1... 0 symlinks removed
[33mWarning:[0m Refusing to link macOS provided/shadowed software: icu4c
If you need to have icu4c first in your PATH run:
echo 'export PATH="/usr/local/opt/icu4c/bin:$PATH"' >> /Users/wglee/.bash_profile
echo 'export PATH="/usr/local/opt/icu4c/sbin:$PATH"' >> /Users/wglee/.bash_profile
For compilers to find icu4c you may need to set:
export LDFLAGS="-L/usr/local/opt/icu4c/lib"
export CPPFLAGS="-I/usr/local/opt/icu4c/include"
Updating Homebrew...
[34m==>[0m [1mDownloading https://homebrew.bintray.com/bottles/node-14.3.0.catalina.bottle[0m
[34m==>[0m [1mDownloading from https://akamai.bintray.com/e3/e34c4c25365bc0f5cc245d791dd93[0m
######################################################################## 100.0%
[34m==>[0m [1mPouring node-14.3.0.catalina.bottle.tar.gz[0m
[34m==>[0m [1mCaveats[0m
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
[34m==>[0m [1mSummary[0m
🍺 /usr/local/Cellar/node/14.3.0: 4,659 files, 60.8MB
** 필자가 갑자기 hexo가 작동되지 않아 적잖이 당황하던 중 해결법을 찾아서 이것도 공유해.
!brew uninstall --force node
!brew uninstall icu4c && brew install icu4c
!brew unlink icu4c && brew link icu4c --force
!brew install node
노드 언인스톨 후 재설치하면 문제 없이 작동한다.
어때? 쉽지? 물론 특정 라이브러리를 잡아서 하는 방법도 있지만, 여기서 소개하는 방법은 설치된 모든 라이브러리의 버전을 확인할 수 있는 방법이야. 파이썬 라이브러리 종류가 매우 많은데 이 명령어 하나로 모든 설치된 라이브러리의 버전을 확인할 수 있으니까 상당히 편리한 것 같네.
[숫자는 거짓말하지 않는다: 왜 축구 클럽들이 그렇게 애널리틱스를 중요하게 생각할까(The numbers don’t lie: why football clubs place such importance on analytics)]
웨스트 햄의 로리 캠벨은 빅 클럽에서 핵심 결정에 정보를 제공하는 떠오르는 축구 애널리스트들 중의 하나이다.
선수들이 떠난 한참 후의 웨스트 햄 유나이티드의 채드웰 헬스 훈련장의 조용한 구석에서 로리 캠벨은 컴퓨터 화면을 응시하고 있다. 이것이 보비 무어와 제프 허스트 경의 두 번째 집이었던 이래로 그 주변의 거주지들은 오직 피상적으로 변했을 뿐이나, 필드 밖의 준비의 복잡성은 완전히 바뀌고 있다.
캠벨은 웨스트 햄의 기술 스카우트이자 분석가이다. 옥스포드 졸업생이자, 알라스테어 캠벨의 아들들 중 하나인 그는 성공적인 포커 선수였으며, 약간의 선수 경험과 코칭 배경을 가졌다. 그의 초점은 축구에 관한 무한한 통계적이 데이터들을 이해하는 것이며, 그래서 클럽의 핵심적인 의사 결정자들에게 무엇이 정말 중요한지를 전달하는 것이다.
은골로 칸테는 올시즌의 영입이고 축구 애널리틱스의 승리이다.
더구나, 축구의 가장 효과적인 분석 작업들 중 몇몇과 단순히 구매력을 거의 반영하지 않고 있는 프리미어 리그 테이블 사이의 잠재적인 상관 관계는 분명하다. 레스터 시티와 웨스트 햄은 오늘 만나 경기를 갖지만, 예를 들어 어떻게 그들이, 만체스터 유나이티드가 마루앙 펠라이니, 안더 에레라 그리고 바스티안 슈바인슈타이거에 7천만 파운드를 쏟아부을 때, 은골로 칸테, 디미트리 파예 그리고 리야드 마레즈를 천 6백만 파운드에 발견해냈을까? 그리고 무엇이 토튼햄 핫스퍼가 델리 알리와 에릭 다이어로 이끌었는지 혹은 사우스햄튼을 사디오 마네와 버질 반 다이크로 이끌었을까? 왜 팀들이 전에 없이 적은 크로스를 하고 있을까? 무엇이 레스터의 독특한 특징일까? 왜 펩 과르디올라와 같은 감독들이 먼 거리에서의 슈팅을 장려하지 않을까? 그리고 모든 시즌들 중에서 가장 놀라운, 테이블이 거짓말을 하지 않는다는 것은 정말 사실일까?
캠벨은 웨스트 햄의 기술 스카우트이자 애널리스트이다.
애널리틱스는 최소한 부분적인 답을 제공한다. 비록 캠벨이 분석의 가치가 여전히 의사결정의 기저를 구성하고 있는 경험, 직관, 본질적인 지식과 접촉들을 대체한다기 보다는 보조하는 것이라고 확신하지만 말이다. 그는 “비효율적인 어떤 시장도 기회입니다.”라고 말한다. “축구가 재능을 가치 평가하는 세트나 동의된 방식을 갖고 있지 않고 너무나 임의적이라는 사실은 기회입니다. 통계와 애널리틱스는 차이가 있습니다. 통계는 당신에게 일어난 사건들에 대해서 말해줍니다. 그들은 맥락없이는 아무 것도 의미하지 않습니다.
레스터의 직접적인 스타일은 그들을 뚜렷한 프리미어 리그 아웃라이어로 만들었다.
“애널리틱스는 그러한 통계들을 미래의 퍼포먼스를 예측하기 위해 해석하는 것입니다. 당신은 모든 것을 측정할 수 있습니다. 어려운 것은 무엇이 중요한지를 알아내는 것입니다. 한가지 좋은 것은 축구는 꽤 단순하다는 것입니다. 모든 것은 결국에는 어떻게든 골과 연관되어 있습니다, 그것이 우리의 득점 기회를 늘려주거나 아니면 실점을 막아주거나요. 그것은 또한 감독이 팀이 어떻게 플레이하기를 원하는 틀 안에서 통합니다.”
보다 더 많은 통찰들이 사우스햄튼의 훈련시설에서 발견될 수 있다. 가장 놀라운 곳은 클럽의 34세의 스카우팅과 선수선발 이사인 로스 윌슨이 자리잡고 있는 방이다. 그의 바로 앞에는 15개의 일련의 화면 앞에서 젊은 스태프들의 팀이 정보들을 처리하고 있다. 몇몇은 축구 분석의 특정 분야에서의 학위를 보유한 인턴들이다. 윌슨의 오른쪽에는 보다 희끗희끗한 머리를 가진 관계자인 로드 루딕과 같은 사람이 있다. 그는 뉴포트의 필드에서 뛰던 8살의 가레스 베일을 발견한 스카우트이다. 윌슨의 왼쪽에는 “블랙 박스”라는 단어가 미스테리하게 걸려있는 문이 있다.
폴 미첼은 사우스햄튼에서 토튼햄으로 이동해서 선수선발 및 분석 팀장이 되었다.
사우스햄튼은 이 미니-시네마에 쓰이는 맞춤형 소프트웨어를 꾸준히 수정하고 있다. 그 소프트웨어는 몇번의 클릭들 만으로 전세계에 있는 어떤 선수에 대한 것도 볼 수 있다. 다른 클럽들은 비슷한 기술을 개발 중이며, 수학적으로 재능들을 골라내는 사람들 사이에서, 이적 시장이 떠오르고 있다. 아스날은 올 해 벤 뤼글워스를 레스터로부터 빼냈고, 미국 기반의 분석 회사인 statDNA를 2백만 파운드에 사들였다. 마우리시오 포체티노와 함께, 토튼햄은 그들의 선수선발과 분석 팀장인 폴 미첼을 사우스햄튼에서 선발했다. 부상으로 27세에 선수 커리어를 끝냈던 미첼은 이렇게 말한다. “저는 한 번 좋은 경기를 가질 때 다른 80경기에서는 그렇게 좋지 않다는 간단한 이론을 발견했습니다.”
포커에서처럼, 캠벨은 선수 선발을 “당신의 베팅의 경제적인 리스크를 가용한 정보를 가지고 관리하는 것”이라고 부른다. 하지만 다른 점은 그의 산업의 다른 멤버들과의 미팅이 분명히 핵심적이라는 것을 강조한다. 과거의 축구에서의 혁신의 시도가 주저앉은 곳에는 종종 의사소통의 실수나 개인간의 충돌들에 기반한다.
클라이브 우드와드 경은 보통 생각되는 것보다 해리 레드납과 더 나은 관계를 가지고 있다. 하지만 거기에 루퍼트 로, 데이브 바셋, 데니스 와이즈와 사이먼 클리포드를 더하면 당신이 그것이 어디서 잘못되었는지 파악하기 위해서 에르큘 포와드의 추리력까지 필요하지도 않다. 애널리틱스가 차이를 만들어내는 곳에는 주로 문화가 정립된다. “당신이 플레이할 필요가 있는 클럽들 중에는 전통이 깊이 배어있는 클럽들이 있을 것입니다. 하지만 운이 좋게도 내가 있었던 클럽들은 사고방식이 매우 열려있었습니다.” 윌슨이 말한다.
캠벨은 이렇게 더한다: “애널리틱스 세계가 힘겨워하는 부분은 전통적인 축구 세계로의 다리를 놓는 것입니다. 정보를 더 침투시키기 위해서요. 수학적인 측면에서는 완벽히 논리적으로 말이되는 많은 정보들을 주고 수십년간 발전해 온 스포츠가 그것을 하루 아침에 받아들이기를 기대하는 것은 사실 꽤 건방진 것이다. 나는 이것이 가장 큰 도전으로 남아있다고 말하고 싶다. 정보를 전달할 수 있기 위해서는 당신은 역학관계와 당신과 함께 일하는 사람들의 성격들을 이해해야만 한다. 나는 그것이 왜 애널리틱스가 다른 비지니스에서 그랬던 것처럼 축구에 침투하지 못한 이유라고 생각한다.”
아스날 감독 아슨 벵거는 또한 애널리틱스를 수용해오고 있다.
하지만 이것은 변하고 있다. 캠벨은 그가 슬래븐 빌리치와 선수 선발 디렉터인 토니 헨리 아래에서 일할 수 있어서 매우 운이 좋았다고 말한다. 그리고 모두의 역할에 분명함이 있었다. 그들이 원하는 것은 간단히 그들의 결정을 도와줄 정보에 대한 믿을만한 평가였다. 나이 많은 감독들 역시 접근하고 있다. 클라우디오 라니에리는 한 예이다. 아슨 벵거는 올 시즌 공식자리에서 아스날의 “기대 골 값 (xG)”에 대해 언급하면서 충격을 촉발시켰다. 그것은 팀이 통계적으로 얼마나 자주 득점할 수 있는지에 대한 스포츠 베팅과 애널리틱스에서 핵심적인 측정값이다.
보루시아 도르트문트의 코치 토마스 투헬은 xG에 대해 더 배우기 위해 매튜 베넘을 찾아갔다. 베넘은 스포츠 베팅에서 수백만을 벌었고 그 이후로 브렌트포드와 FC밋츌란을 사들였다. 선수를 개인적으로 관찰하기 위해 폭넓게 움직이는 캠벨과 마찬가지로, 베넘은 축구처럼 낮은 득점을 가진 스포츠에서의 어떤 수학 모델의 뚜렷한 변동성을 보완하기 위한 “눈으로 하는 스카우팅”의 중요성을 강조한다. 포커처럼, 랜덤과 통제불가능한 사건들이 판단들을 형성하는데 서두르는 가운데에 종종 간과하는 부분적인 역할을 한다.
캠벨은 이렇게 말한다. “이것은 축구를 흥미롭게 만드는 것입니다만 예측불가능은 항상 심각한 비효율을 동반합니다. 운을 불평하는 프로 포커 선수들은 편협한 것입니다. 운이라는 것은 그들이 사는 것을 가능케하는 것입니다. 만약 내가 정말 나쁜 선수와 포커를 친다면, 그는 100번 중에 40번을 이길 것입니다. 만약 내가 개리 카스파로프와 체스를 둔다면 그가 100번을 이기겠죠. 체스 선수들은 베팅으로 돈을 벌지 않습니다. 왜냐하면 아무도 그들에게 돈을 걸지 않으니까요.”
레스터의 동화같은 시즌은 통계적인 모델들이 틀렸음을 입증해오고 있다.
애널리틱스는 점점 더 많은 의견들로 가득찬 현재 지형 안에서 목소리를 내기 위해 싸우고 있다. 캠벨은 이렇게 말한다. “아슨 벵거는 우리가 수직적에서 수평적인 사회로 움직이고 있다고 말했습니다. 수직적인 것은 꼭대기에 리더가 있고 모두가 따르는 것입니다. 수평적인 것은 정보와 의견들에 폭격을 당하는 리더를 가진 것입니다. 그것이 리더가 어떤 것이 중요하고 어떤 것이 노이즈인지를 구분하는 것이 정말 중요한 부분입니다.”
그러면 처음 질문으로 돌아가 보자. 칸테, 마네 그리고 파예는 궁극적으로 기민한 축구적인 결정들이었다. 하지만 애널리틱스 커뮤니티의 기저에 있는 퍼포먼스 지표들의 승리였다. 분명한 통계적인 증거는 크로스들이 스루 볼 보다 적은 확률의 전술이라는 것이고 먼 거리에서의 슈팅은 더 나은 포지션으로 패스하는 것 보다 적은 골을 생산한다는 것이다.
수학 교수이자 사커매틱스의 저자 데이빗 섬터에 따르면, 레스터와 리그의 다른 팀들과의 충격적인 차이는 어떻게 그들이 상대적으로 길고 직선적인 패스들로 볼을 전방으로 빠르게 움직이는지이다.
그러면 테이블은 절대 거짓말하지 않는다는 클리셰는 거짓일까? 글쎄, 아마도 그것은 진실 전부를 말하지는 않는다. 거의 모든 xG모델은 아스날이 사실 엄청난 기회를 놓쳤고 선두에 있었어야 한다고 말하고 있다. 대부분의 모델은 만약 이번 시즌이 무한한 경기 수를 가졌을 때 레스터가 4위에서 8위 사이에 놓고 있다. 분산과 운은, 38경기 프로그램에서 상당한 양으로 남아있다. 여전히 그 차이들은 좁고, 만약 지난 해가 어떤 것도 새로 증명하는 것이 아니라면, 열심히 일하는 것과 스마트함이 클럽의 은행 계좌의 사이즈 보다 더 중요할 수 있다.
독립변수의 전체 데이터가 아닌 개별적인 데이터 표본 하나하나가 회귀분석 결과에 미치는 영향력은 레버리지 분석이나 아웃라이어 분석을 통해 알 수 있다.
레버리지(leverage)는 실제 종속변수값 𝑦 가 예측치(predicted target) 𝑦̂ 에 미치는 영향을 나타낸 값이다. self-influence, self-sensitivity 라고도 한다.
레버리지 값은 RegressionResults 클래스의 get_influence 메서드로 다음과 같이 구할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
from sklearn.datasets import make_regression
# 100개의 데이터 생성 X0, y, coef = make_regression(n_samples=100, n_features=1, noise=20, coef=True, random_state=1)
# 레버리지가 높은 가상의 데이터를 추가 data_100 = (4, 300) data_101 = (3, 150) X0 = np.vstack([X0, np.array([data_100[:1], data_101[:1]])]) X = sm.add_constant(X0) #상수항 추가 y = np.hstack([y, [data_100[1], data_101[1]]])
plt.figure(figsize=(14,6)) plt.scatter(X0, y, s=30) plt.xlabel("x") plt.ylabel("y") plt.title("가상의 회귀분석용 데이터") plt.show()
1 2 3
model = sm.OLS(pd.DataFrame(y), pd.DataFrame(X)) result = model.fit() print(result.summary())
OLS Regression Results
==============================================================================
Dep. Variable: 0 R-squared: 0.936
Model: OLS Adj. R-squared: 0.935
Method: Least Squares F-statistic: 1464.
Date: Thu, 14 May 2020 Prob (F-statistic): 1.61e-61
Time: 14:22:53 Log-Likelihood: -452.71
No. Observations: 102 AIC: 909.4
Df Residuals: 100 BIC: 914.7
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
0 3.2565 2.065 1.577 0.118 -0.840 7.353
1 78.3379 2.048 38.260 0.000 74.276 82.400
==============================================================================
Omnibus: 16.191 Durbin-Watson: 1.885
Prob(Omnibus): 0.000 Jarque-Bera (JB): 36.807
Skew: -0.534 Prob(JB): 1.02e-08
Kurtosis: 5.742 Cond. No. 1.14
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
선형회귀 결과에서 get_influence 메서드를 호출하면 영향도 정보 객체를 구할 수 있고, 이 객체는 hat_matrix_diag 속성으로 레버리지 벡터의 값을 가지고도 있어
1 2 3 4 5 6 7 8
influence = result.get_influence() hat = influence.hat_matrix_diag
plt.figure(figsize=(14,6)) plt. stem(hat) plt.axhline(0.02, c = 'g', ls = '--') # c = color , ls = linestyle plt.title('각 데이터의 레버리지 값') plt.show()
/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:5: UserWarning: In Matplotlib 3.3 individual lines on a stem plot will be added as a LineCollection instead of individual lines. This significantly improves the performance of a stem plot. To remove this warning and switch to the new behaviour, set the "use_line_collection" keyword argument to True.
"""
그래프를 그리는 코드에서 0.02의 값은 레버리지 평균값을 구하는 공식 독립변수의 갯수 / 데이터의 갯수 로 구하면 된다
그래프를 토대로 해석을 하자면, 데이터가 혼자만 너무 작거나 너무 크게 단독으로 존재할수록 레버리지가 커짐을 알 수 있어. 이 말은 저런 데이터은 전체 회귀분석 결과값에 큰 영향을 미친다는 말이야
아웃라이어(outlier)
데이터와 동떨어진 값을 가지는 데이터, 즉 잔차가 큰 데이터를 아웃라이어(outlier)라고 하는데, 잔차의 크기는 독립 변수의 영향을 받으므로 아웃라이어를 찾으려면 이 영향을 제거한 표준화된 잔차를 계산해야 한다고 해. 무슨말인지 잘 모르겠지만 그래
statsmodels를 이용한 표준화 잔차 계산
잔차는 RegressionResult 객체의 resid 속성에 있다.
1 2 3 4
plt.figure(figsize=(14, 6)) plt.stem(result.resid) plt.title("각 데이터의 잔차") plt.show()
/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: UserWarning: In Matplotlib 3.3 individual lines on a stem plot will be added as a LineCollection instead of individual lines. This significantly improves the performance of a stem plot. To remove this warning and switch to the new behaviour, set the "use_line_collection" keyword argument to True.
표준화 잔차는 resid_pearson 속성에 있고, 보통 표준화 잔차가 2~4보다 크면 아웃라이어로 보는게 일반적이야
/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: UserWarning: In Matplotlib 3.3 individual lines on a stem plot will be added as a LineCollection instead of individual lines. This significantly improves the performance of a stem plot. To remove this warning and switch to the new behaviour, set the "use_line_collection" keyword argument to True.
Cook’s Distance
회귀 분석에는 레버리지 따로, 잔차의 크기가 큰 데이터가 아웃라이어가 되고 그것을 보는 따로따로의 기능도 있지만 이 두개를 동시에 보는 방법이 바로 Cook's Distance야. 아마도 Cook이라는 사람이 만들었을 가능성이..
넘어가자
동시에 보는 기준이라고 생각하면 되고, 둘중 하나만 커지더라도 이 Cook's distance 값은 커지게 돼
모든 데이터의 레버리지와 잔차를 동시에 보려면 plot_leverage_resid2 명령을 사용하는데, 이 명령은 x축으로 표준화 잔차의 제곱을 표시하고 y축으로 레버리지값을 표시한다.
그리고 데이터 아이디가 표시된 데이터들이 레버리지가 큰 아웃라이어 야
OLS Regression Results
==============================================================================
Dep. Variable: MEDV R-squared: 0.812
Model: OLS Adj. R-squared: 0.806
Method: Least Squares F-statistic: 156.1
Date: Thu, 14 May 2020 Prob (F-statistic): 2.41e-161
Time: 15:14:52 Log-Likelihood: -1285.2
No. Observations: 485 AIC: 2598.
Df Residuals: 471 BIC: 2657.
Df Model: 13
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 18.8999 4.107 4.602 0.000 10.830 26.969
CRIM -0.0973 0.024 -4.025 0.000 -0.145 -0.050
ZN 0.0278 0.010 2.651 0.008 0.007 0.048
INDUS -0.0274 0.046 -0.595 0.552 -0.118 0.063
CHAS 0.9228 0.697 1.324 0.186 -0.447 2.292
NOX -9.4922 2.856 -3.323 0.001 -15.105 -3.879
RM 5.0921 0.371 13.735 0.000 4.364 5.821
AGE -0.0305 0.010 -2.986 0.003 -0.051 -0.010
DIS -1.0562 0.150 -7.057 0.000 -1.350 -0.762
RAD 0.1990 0.049 4.022 0.000 0.102 0.296
TAX -0.0125 0.003 -4.511 0.000 -0.018 -0.007
PTRATIO -0.7777 0.098 -7.955 0.000 -0.970 -0.586
B 0.0107 0.002 5.348 0.000 0.007 0.015
LSTAT -0.2846 0.043 -6.639 0.000 -0.369 -0.200
==============================================================================
Omnibus: 45.944 Durbin-Watson: 1.184
Prob(Omnibus): 0.000 Jarque-Bera (JB): 65.791
Skew: 0.679 Prob(JB): 5.17e-15
Kurtosis: 4.188 Cond. No. 1.59e+04
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.59e+04. This might indicate that there are
strong multicollinearity or other numerical problems.
R-squared 의 성능점수가 올라간 것을 볼 수 있어.
이렇게 어떤 특정 데이터를 가지고 회귀분석 모델링을 할 때에는 하기 전에 레버리지가 큰 데이터와 아웃라이어의 값을 이러한 절차에 의해 뽑아서 제거하고 모델링을 한다면 더욱 성능이 좋은 회귀분석 모델링을 할 수 있는거야
분산 분석
선형회귀분석의 결과가 얼마나 좋은지는 단순히 잔차제곱합(RSS: Residula Sum of Square)으로 평가할 수 없다. 변수의 단위 즉, 스케일이 달라지면 회귀분석과 상관없이 잔차제곱합도 달라지기 때문이야 ( ex.1km와 1000m)
분산 분석(ANOVA: Analysis of Variance)은 종속변수의 분산과 독립변수의 분산간의 관계를 사용하여 선형회귀분석의 성능을 평가하고자 하는 방법이다. 분산 분석은 서로 다른 두 개의 선형회귀분석의 성능 비교에 응용할 수 있으며 독립변수가 카테고리 변수인 경우 각 카테고리 값에 따른 영향을 정량적으로 분석하는데도 사용할 수 있게 돼
여러 수식들이 존재하지만 내가 이해를 못하겠고 결론은 다음과 같아.
모형 예측치의 움직임의 크기(분산,ESS)은 종속변수의 움직임의 크기(분산,TSS)보다 클 수 없어 그리고 모형의 성능이 좋을수록 모형 예측치의 움직임의 크기는 종속변수의 움직임의 크기와 비슷해진다는 점이야
F 검정을 사용한 변수 중요도 비교
F검정은 각 독립변수의 중요도를 비교하기 위해 사용할 수 있다. 방법은 전체 모형과 각 변수 하나만을 뺀 모형들의 성능을 비교하는 것인데, 이는 간접적으로 각 독립 변수의 영향력을 측정하는 것이라고 할 수 있다. 예를 들어 보스턴 집값 데이터에서 CRIM이란 변수를 뺀 모델과 전체 모델의 비교하는 검정을 하면 이 검정 결과는 CRIM변수의 중요도를 나타낸다.
1 2 3 4 5 6
model_full = sm.OLS.from_formula( "MEDV ~ CRIM + ZN + INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + CHAS", data=df0) model_reduced = sm.OLS.from_formula( "MEDV ~ ZN + INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + CHAS", data=df0)
/opt/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py:903: RuntimeWarning: invalid value encountered in greater
return (a < x) & (x < b)
/opt/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py:903: RuntimeWarning: invalid value encountered in less
return (a < x) & (x < b)
/opt/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py:1912: RuntimeWarning: invalid value encountered in less_equal
cond2 = cond0 & (x <= _a)
df_resid
ssr
df_diff
ss_diff
F
Pr(>F)
0
493.0
11322.004277
0.0
NaN
NaN
NaN
1
492.0
11078.784578
1.0
243.219699
10.801193
0.001087
anova_lm 명령에서는 typ 인수를 2로 지정하면 하나 하나의 변수를 뺀 축소 모형에서의 F 검정값을 한꺼번에 계산할 수 있다.
아노바 분석 - F검정
1 2 3 4
model = sm.OLS.from_formula( "MEDV ~ CRIM + ZN + INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + CHAS", data=df0) result = model.fit() sm.stats.anova_lm(result, typ=2)
sum_sq
df
F
PR(>F)
CRIM
243.219699
1.0
10.801193
1.086810e-03
ZN
257.492979
1.0
11.435058
7.781097e-04
INDUS
2.516668
1.0
0.111763
7.382881e-01
NOX
487.155674
1.0
21.634196
4.245644e-06
RM
1871.324082
1.0
83.104012
1.979441e-18
AGE
0.061834
1.0
0.002746
9.582293e-01
DIS
1232.412493
1.0
54.730457
6.013491e-13
RAD
479.153926
1.0
21.278844
5.070529e-06
TAX
242.257440
1.0
10.758460
1.111637e-03
PTRATIO
1194.233533
1.0
53.034960
1.308835e-12
B
270.634230
1.0
12.018651
5.728592e-04
LSTAT
2410.838689
1.0
107.063426
7.776912e-23
CHAS
218.970357
1.0
9.724299
1.925030e-03
Residual
11078.784578
492.0
NaN
NaN
각각의 독립변수들의 전체와 비교했을 때 얼마만큼 중요도를 가지는데 정량적으로 나온 결과값이야. 여기서 주목해야할 부분은 PR>(>F)부분으로 summary에서도 나오는 p-value값을 디테일하게 풀어놓은 값이고 예를 들어 LSTAT, RM의 경우 10의 -23승, 10의 -18승으로 수치가 제일 낮은걸 알 수 있어. 그러면 이 2가지의 독립변수가 종속변수에 가장 큰 영향을 미쳤다고 해석하면 되는거야
표의 F값을 보고도 알 수 있지만 F값은 확률의 의미는 없기 때문에 단순 순위를 매기는거 라면 결정할 수 있지만 만약 귀무가설/대립가설을 accept 하냐 reject 하냐의 확률적 의미를 판단한다면 F값만으로는 불가능해
1 2
범주형을 사용한 비선형성
독립변수의 비선형성을 포착하는 또 다른 방법 중 하나는 강제로 범주형 값으로 만드는 것이다. 범주형 값이 되면서 독립변수의 오차가 생기지만 이로 인한 오차보다 비선형성으로 얻을 수 있는 이익이 클 수도 있다.
보스턴 집값 데이터에서 종속변수와 RM 변수의 관계는 선형에 가깝지만 방의 갯수가 아주 작아지거나 아주 커지면 선형모형에서 벗어난다.
OLS Regression Results
==============================================================================
Dep. Variable: MEDV R-squared: 0.484
Model: OLS Adj. R-squared: 0.483
Method: Least Squares F-statistic: 471.8
Date: Thu, 14 May 2020 Prob (F-statistic): 2.49e-74
Time: 19:28:18 Log-Likelihood: -1673.1
No. Observations: 506 AIC: 3350.
Df Residuals: 504 BIC: 3359.
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -34.6706 2.650 -13.084 0.000 -39.877 -29.465
RM 9.1021 0.419 21.722 0.000 8.279 9.925
==============================================================================
Omnibus: 102.585 Durbin-Watson: 0.684
Prob(Omnibus): 0.000 Jarque-Bera (JB): 612.449
Skew: 0.726 Prob(JB): 1.02e-133
Kurtosis: 8.190 Cond. No. 58.4
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
이렇게 RM 데이터 전체를 놓고 보면 종속변수 y와 아주 큰 상관관계가 있는것으로 보이지만 위에 그래프에서 봤듯이, 방의 갯수가 아주 적거나, 많으면 선형성을 보이지 않는 구간에 대해 조금 더 디테일하게 상관관게를 보고 싶다면 RM 데이터를 강제로 범주화 시켜 RM 데이터가 가지는 비선형성을 잡을 수 있다.
1 2 3 4 5 6 7
rooms = np.arange(3,10) labels = [str(r) for r in rooms[:-1]] df0['CAT_RM'] = np.round(df['RM'])
OLS Regression Results
==============================================================================
Dep. Variable: Demand R-squared: 0.031
Model: OLS Adj. R-squared: 0.028
Method: Least Squares F-statistic: 11.58
Date: Thu, 14 May 2020 Prob (F-statistic): 0.000739
Time: 19:35:40 Log-Likelihood: -1709.7
No. Observations: 365 AIC: 3423.
Df Residuals: 363 BIC: 3431.
Df Model: 1
Covariance Type: nonrobust
==================================================================================
coef std err t P>|t| [0.025 0.975]
----------------------------------------------------------------------------------
Intercept 221.2775 1.374 160.997 0.000 218.575 223.980
scale(Ordinal) -4.6779 1.374 -3.404 0.001 -7.381 -1.975
==============================================================================
Omnibus: 43.105 Durbin-Watson: 0.677
Prob(Omnibus): 0.000 Jarque-Bera (JB): 96.485
Skew: 0.614 Prob(JB): 1.12e-21
Kurtosis: 5.199 Cond. No. 1.00
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
하지만 시간 독립변수는 이 외에더 다양한 특징들을 숨기고 있다. 예들 들어 연도, 월, 일, 요일 데이터를 별도의 독립변수로 분리하거나 한 달 내에서 몇번째 날짜인지 월의 시작 또는 끝인지를 나타내는 값은 모두 특징값이 될 수 있다. 판다스에서는 dt 특수 연산자를 사용하여 이러한 값을 구할 수 있다.
OLS Regression Results
==============================================================================
Dep. Variable: MEDV R-squared: 0.333
Model: OLS Adj. R-squared: 0.329
Method: Least Squares F-statistic: 83.39
Date: Wed, 13 May 2020 Prob (F-statistic): 8.62e-44
Time: 16:03:11 Log-Likelihood: -1737.9
No. Observations: 506 AIC: 3484.
Df Residuals: 502 BIC: 3501.
Df Model: 3
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -0.0038 0.000 -8.543 0.000 -0.005 -0.003
CRIM -0.1567 0.046 -3.376 0.001 -0.248 -0.066
ZN 0.1273 0.016 7.752 0.000 0.095 0.160
INDUS -0.1971 0.019 -10.433 0.000 -0.234 -0.160
CHAS 0.0034 0.000 12.430 0.000 0.003 0.004
NOX -0.0023 0.000 -9.285 0.000 -0.003 -0.002
RM 0.0267 0.002 14.132 0.000 0.023 0.030
AGE 0.1410 0.017 8.443 0.000 0.108 0.174
DIS -0.0286 0.004 -7.531 0.000 -0.036 -0.021
RAD 0.1094 0.018 6.163 0.000 0.075 0.144
TAX 1.077e-15 2.66e-16 4.051 0.000 5.55e-16 1.6e-15
PTRATIO -0.1124 0.011 -10.390 0.000 -0.134 -0.091
B 0.0516 0.003 19.916 0.000 0.046 0.057
LSTAT -0.6569 0.056 -11.790 0.000 -0.766 -0.547
==============================================================================
Omnibus: 39.447 Durbin-Watson: 0.863
Prob(Omnibus): 0.000 Jarque-Bera (JB): 46.611
Skew: 0.704 Prob(JB): 7.56e-11
Kurtosis: 3.479 Cond. No. 1.19e+17
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.19e+17. This might indicate that there are
strong multicollinearity or other numerical problems.
조건수(Conditional No.)가 1000조 수준으로 증가한 것을 볼 수 있지? 오른쪽 제일 상단에 보이는 R-squared라는 값으로 표시되는 성능지표도 크게 감소한것을 볼 수 있어. R-squared 는 이 모델 성능에 대해 몇점인지를 알려주는 기능이라고 보면 되(0.333으로 나왔으니 100점 만점에 33.3점이라는 소리야)
statsmodels에서는 scale() 이라는 명령을 사용하여 스케일링을 할 수 있는데, 이 방식으로 스케일을 하면 스케일링에 사용된 평균과 표준편차를 저장하였다가 나중에 predict() 라는 명령을 사용할 때도 같은 스케일을 사용하기 때문에 편리한 것을 알 수 있어. 다만! 스케일링을 할 때에는 카테고리 변수, 즉 범주형 데이터는 스케일링을 하지 않는다는 것에 주의 해주면 되.
1 2 3 4 5 6
feature_names = list(boston.feature_names) feature_names.remove("CHAS") feature_names = ['scale({})'.format(name) for name in feature_names] + ['CHAS'] model3 = sm.OLS.from_formula("MEDV ~ " + "+".join(feature_names), data=df2) result3 = model3.fit() print(result3.summary())
이번에는 연속형 데이터가 아닌 범주형 데이터의 회귀분석을 하는 방법에 대해 알아보자! 범주형 데이터는 측정 결과가 몇 개의 범주 또는 향목의 형태로 나타나는 자료를 말하는데 그것을 숫자로 표현한 것이라고 할 수 있어. 예를 들면 남자는 1 여자는 0 이런식이지!
아무튼..
여기서 다룰 학습은 그러한 범주형 독립변수(데이터)의 회귀분석 모델링 시 에는 앞서 배운 더미변수화가 필수라는 거야. 풀랭크(full-rank) 방식과 축소랭크(reduced-rank) 방식이 있는데 풀랭크방식에서는 더미변수의 값을 원핫인코딩(one-hot-encoding) 방식으로 지정을 하는거야
예를 들어서..
남자는 1 이고 여자는 0 이면
남자 : d1=1, d2=0
여자 : d1=0, d2=1 이런식으로 쓴다는 거지
축소랭크 방식에서는 특정한 하나의 범주값을 기준값(reference, baseline)으로 하고 기준값에 대응하는 더미변수의 가중치는 항상 1으로 놓아 계산 하는 방법이지
무슨 말인지 어렵지? 그럼 실 데이터로 예를 들어보도록 할게.
아래의 데이터는 1920년부터 1939년까지 영국 노팅험 지역의 기온을 나타낸 데이터야. 이 데이터에서 독립 변수는 월(monath)이며 범주값으로 처리를 할거야 그리고 value로 표기된 값이 종속변수인 해당 월의 평균 기온이라고 할 수 있지. 분석의 목적은 독립변수인 월 값을 이용하여 종속변수인 월 평균 기온을 예측하는 것이야.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import datetime from calendar import isleap
defconvert_partial_year(number): #연 단위 숫자에서 날짜를 계산하는 코드 year = int(number) d = datetime.timedelta(days=(number - year) * (365 + isleap(year))) day_one = datetime.datetime(year, 1, 1) date = d + day_one return date
plot_partregress(endog, exog_i, exog_others, data=None, obs_labels=True, ret_coords=False)
endog: 종속변수 문자열
exog_i: 분석 대상이 되는 독립변수 문자열
exog_others: 나머지 독립변수 문자열의 리스트
data: 모든 데이터가 있는 데이터프레임
obs_labels: 데이터 라벨링 여부
ret_coords: 잔차 데이터 반환 여부
하지만! 다른 독립변수에 영향을 받은 AGE가 집값에 영향을 미쳤는지에 대한 부분을 확인해보면 그래프는 다음과 같아.
AGE 데이터에 대한 부분회귀인셈이지.
CCPR 플롯
CCPR(Component-Component plus Residual) 플롯도 부분회귀 플롯과 마찬가지로 특정한 하나의 변수의 영향을 살펴보기 위한 것이야
부분회귀분석과 비슷하지만 다른점이 하나 있는데 그것은 위에서 언급한 다른 변수에 영향을 받은 AGE가 아니라 AGE 데이터 그 자체와 집값의 상관관계를 보기위한 방법이라고 보면 되
선형회귀분석 정리 오늘의 데이터 사이언스 스쿨에서는 본격적으로 제대로 된 선형회귀분석에 대해 배울 수 있었어. 또 배운 내용을 바탕으로 파이썬을 이용하여 패키지를 이용해 직접 구현해볼 수도 있었는데, 요약된 정보들이 가지는 함축적인 의미가 있어. 길고, 어려운 내용들이었지만 간신히 맥락은 잡고 있는 것 같아 잊기 전에 빠른 정리를 통해 복습을 하려고 해. listen.
우선 선형회귀분석이란, 종속 변수 y와 한 개 이상의 독립 변수 x와의 선형 관계를 모델링하는 방법이야. 사실 이런 단어들을 이용해 설명하면 쉬운 것도 어렵게 느껴지기 마련인데, 내가 수업시간에 깨달은 선형회귀분석 내용은 아래와 같아.
seaborn 데이터셋에 있는 tip 데이터를 가져와봤어. 총 지출 비용, 팁의 금액, 팁을 준 사람의 성별과 흡연 여부, 요일 시간, 함께 온 인원들의 정보 나열되어 있네. 막무가내로 서로 연관성 없이 나열되어 있는 것 같은 이 데이터들 속에서 그 어떤 상관성이 있을까? 가령, 식사 인원이 많으면 많을 수록 팁의 비용이 커지거나, 저녁 타임에 오는 손님이 팁을 더 많이 준다 등 데이터를 통해 이러한 인사이트를 얻어 내야 하는 것인데, 이러한 선형회귀분석은 이러한 데이터의 성별, 흡연여부, 식사 시간대 등과 같은 데이터(독립변수, x)들이 팁(종속변수, y)에 영향을 주는지, 혹은 영향을 주지 않는지, 영향을 주면 어떤 항목이 가장 영향을 많이 주는지 알 수 있는 방법 중에 하나라고 할 수 있지.
그렇다면 팁 데이터를 벡터값 y로 놓고 나머지 벡터들, 즉 나머지 행렬 데이터를 x로 놓고 일반적으로 알고 있는 ‘y = wx’를 만들 수 있겠지? 여기서 기울기에 해당하는 ‘w’가 바로 우리가 알고 싶어 하는 가중치라는 것이야. x의 항목들(성별, 흡연여부, 식사시간대 등) 중 어떤 항목이 팁이 많고 적음에 상관이 있는지, 즉 팁에 긍정적인 영향을 미쳐서 팁의 금액이 올라가게 하는지, 혹은 부정적인 영향을 미쳐서 팁의 금액을 내려가게 하는지, 혹은 전혀 상관이 없는지 말야.
이 때 wx를 x에 대한 함수로 나타난다면 y와 x 의 관계는 이렇게 정리할 수 있어.
(어렵다 참)
아무튼!
여기서 y 위의 ^와 물결표가 붙으면서 좀 더 깊게 들어가게 되는데, ^가 붙은 y를 y hat이라고 해. y는 우리가 마주하고 있는 현실 세계에서 일어난 실제 데이터이고, y hat은 예측한 가중치, w의 영향을 받은 ‘예측값’이라고 할 수 있어. 때문에 우리가 원하는 것은 어떤 값을 가질 지 모르는 가중치 w의 값을 조정하여 우리가 예측한 예측치 y hat과 실제 발생한 데이터 값 y의 차이(잔차)를 줄이는 것이라고 할 수 있지.
언급했던 y, y hat, w 모두는 스칼라 값이 아니라 벡터 혹은 행렬의 형태를 갖추고 있어. 위의 사진에서 가중치 값 w는 이 선형회귀 모형의 모수 즉 parameter 야. 그리고 x1, x2 … 는 tip 데이터에서는 종속 변수 tip데이터를 제외한 나머지, 즉 성별, 흡연여부, 식사 시간대 등이 되는거야.
우선 선형회귀분석에 결정론적 방법과 확률론적 방법이라는 2가지 방법이 있어. 결정론적 방법은 단순하게 독립변수 x에 대응하는 종속변수 y 값을 계산하는 함수를 만들어 내는 것인 반면 확률론적 방법은 이름 그대로 x, y 뒤에 어떤 ‘확률 모형’이 숨어져 있다는 가정이 ‘추가’되는데, 이 가정이 추가됨으로써 결정론적 방법보다 더 많은 정보를 가지고 시작하게 된다고 할 수 있지.(비록 가정이라 할지라도) 더 많은 정보를 가지고 시작함으로써 결정론적 방법보다 조금 더 깊은 인사이트를 도출할 수 있어.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
import matplotlib from matplotlib import font_manager, rc import platform
try : if platform.system() == 'windows': # windows의 경우 font_name = font_manager.FomntProperties(fname="c:/Windows/Font") rc('font', family = font_name) else: # mac의 경우 rc('font', family = 'AppleGothic') except : pass