회귀방정식의 해석에서는 더하여 회귀방정식의 해석에서는 변수간 상관성, 다중공선성,교란변수, 상호작용에 대해서 다룬다.
회귀진단에서는 특이값, 영향값, 이분산성, 비정규성, 오차 간의 상관, 편잔차그림과 비선형성을 다룬다.
다항회귀와 스플라인회귀는 선형회귀에서 다항식,스플라인, 일반화가법모형 등 응용하는 방법을 다룬다.
2.1 교란변수의 정의
책에서는 교란변수를 "중요한 예측변수이지만 회귀방정식에서 누락되어 결과를 잘못되게 이끄는 변수" 라고 설명하고 있다. 의학통계에서 얘기하는 교란변수는 조금 다른 의미인 것 같아 정리해보려한다.
흔히 교란변수(confounder)는 독립변수간이 관계를 살피는 상황 속에서 교호작용(interaction)과 함께 언급된다. 예컨대 상관계수 분석을 하다보면 자주 주는 예시가 아이스크림 판매량이 높으면 상어에 물리는 사람들이 많다. 라는 이야기로 상관관계와 인과관계의 구분이 필요하다는 얘기를 한다. 이게 무슨말이냐면 두 측정 변수가 상관관계가 있다고 해서 원인-결과로 직결적으로 해석하면 안된다는 것이다. 이 과정에서 각 변수(X,Y) 영향을 주는 변수, 교란변수가 바로 여름이라는 특징이다.
이런 점에서 "누락되어"라는 말이 어쩌면 합리적이면서도 데이터가 없는데 어떻게 누락된지 아닌지 알아요 라는 질문이 들기도 한다.
어쩌면이 포인트
결국 제대로된 모델을 만들려면 교란변수를 데이터화하고 모델링을 하는데 일조해야한다는 것인데.. 만약 그런 통찰이 없다면? 통찰이 있다해도 데이터가 없다면? 곤란해질 것 같긴하다.
2.2 스플라인과 일반화가법모형
- 스플라인은 몇몇 제어점을 이용하여 부드러운 곡선을 만들어내는 수학적 도구이다. 이때 매듭점(knot)개념이등장하고 이 매듭점을 충분히 연결해주는 함수가 스플라인이다. 다항회귀(x^2, x^3)는 어느정도 곡률을 담아낼 수 있지만 고차항을 추가하는 것은 회귀방정식에 바람직하지 않은 결과를 초래한다.
흔히 x의 의 구간을 여러부분으로 나누어 회귀모델을 각각 구현할 수 있으며 다항식의 차수와 매듭의 위치를 설정하여 만든다. 선형회귀보다 해석하기 어렵기 때문에 산점도와 같은 시각화 방법을 이용하는 것이 바람직하다.. 곡선은 직선의 연속
여기서 등장하는 것이 일반화 가법모형(Generalized Additive Model, GAM)이다. GAM은 스플라인 매듭을 자동으로 결정할 수 있는 장점이 있다. 요즘 같은 ML기법이 많이 등장한 이후 가법모형이 애매한 포지션을 가지고 있지않은가 생각이 되면서도 매우 좋은 예측력과 통계적 추론이가능하며 모형의 구조를 이해할 수 있어서 사용된다. 예를들어 각 요소에 대한 유의성검정, 신뢰구간 계산, 효과 크기 추정이 여전이 가능하다.
GAM의 특징은 다음과 같다.
비선형성: 각 독립 변수에 대해서 비선형함수를 사용하여 복잡한 관계를 모델링
GAM의 예시
가법성: 모델은 여러개의 스무딩 함수의 합으로 구성, 독립적으로 해석 가능
유연성: 다양한 분포에 적용 가능(이항, 포아송 분포 등)
이런 상황에서 GAM은 데이터 포인트를 부드럽게 연결하는 도구로 되는 특성 때문에 주로 GAM에서는 스플라인을 활용하여 독립변수의 비선형효과를 모델링한다. 대표적은 스플라인 방법은 ① 선형 스플라인 ② 큐빅스플라인 ③ B-스플라인
일반적으로 귀무가설은 믿어지고 있는 본래 사상, 주제이고 대립가설으 새로운 주장이다. 귀무가설이 참인데도 불구하고 귀무가설을 채택하지 않는 오류인 1종 오류를 관리하는게 일반 적이다.
예컨데, 새로운 고혈압약을 개발했다고 하자. 이를 검정한 결과가 실제로는 고혈압약이 효능이 없었는데도 불구하고 고혈압치료가 된다고 시판하면 국민의 위해성이 걱정된다. 따라서 이를 관리하는 지표로 놓고 엄격하게 관리한다. 이를 유의수준(significance level)이라고 한다.
반면 2종오류는 실제로 효능이 있는데고 불구하고 효능이 없다라고 판단하는 오류이다. 이 오류는 국민의 위해성에는 관련이없기 때문에 1종오류보다 덜 엄격하게 관리한다. 사실 이 1종오류, 2종오류는 trade off가 있어서 둘 다 낮은 수준으로 관리할 수 없다.
여기서 하나 등장하는 용어는 바로 검정력(Statistical Power)이다. 이는 대립가설(약이 효과가 있다)가 사실일때 사실로 결정할 확률이다. 검정력은 표본 크기(sample size)를 얼만큼 수집해야하는가를 결정해줍니다.
단계별 절차:
효과 크기 계산:
두 그룹의 클릭률 p1, p2가 있다고 가정합니다.
효과 크기 (effect size, d)를 계산합니다:
𝑑=𝑝1−𝑝2d=p1−p2
유의수준 (alpha) 및 검정력 (power) 설정:
일반적으로 alpha는 0.05, power는 0.8로 설정합니다.
표본 크기 계산 공식:
이항 분포를 따르는 두 그룹의 비교를 위해 표본 크기를 계산하는 공식은 다음과 같습니다
여기서 Z_alpha/2는 정규분포의 상위, Z_beta는 검정력의 하위 백분위수
4. 계산 수행
p1, p2, alpha, power를 사용하여 각 값을 계산합니다.
일반적으로 사용되는 임계값 (Z 값)
from scipy.stats import norm
import numpy as np
# 입력 변수
p1 = 0.1
p2 = P + 0.02 # 2퍼 크기를 감지할 수 있는 표본 크기 생성
alpha = 0.05
power = 0.8
# Z 값 계산
Z_alpha = norm.ppf(1 - alpha / 2)
Z_beta = norm.ppf(power)
# 효과 크기
d = p2 - p1
# 표본 크기 계산
n = ((Z_alpha + Z_beta) ** 2 * (p1 * (1 - p1) + p2 * (1 - p2))) / d ** 2
n = np.ceil(n) # 반올림
n
#3839
본 단원에서는 통계석 실험에 대한 본격적인 설명을 시작하며 A/B 테스트시작한다. 일반적으로 실험이라함은 어떤 가설을 확인하거나 기각하기 위한 목표를 가지고 수행하는 방법을 말한다. 예컨데 약품A가 기존 약품보다 낫다 라는 가설을 세울 수도 있을 것이며, 가격A가 가격B보다 수익성이 높다 라는 가설을 세울 수 도 있을 것이다.
3.1. A/B 테스트
A/B 테스트는 두가지 처리방법/제품/절차 중 어느 것이 더 우월하다는 것을 입증하기 위하여 실험군을 두 그룹으로 나누어서 진행하는 실험이다. 일반적으로 아무런 처리도 하지 않은 것을 대조군 처리한 그룹을 처리군(실험군)이라고한다.
용어정리
처리(treatment): 어떤 대상에게 주어지는 특별한 환경이나 조건(약, 가격, 제목)
처리군(처리그룹, treatment group): 특정 처리에 노출된 대상들의 집단
대조군(대조그룹, control group): 어떤 처리도 하지 않은 대상들의 집단
임의화(랜덤화, randomization): 처리를 적용할 대상을 임의로 결정하는 과정
대상(subject): 처리를 적용할 대상(유의어: 피 실험자)
검정통계량(test statistics): 처리 효과를 측정하기 위한 지표
클릭률이라는 목적변수를 통해서 다음 예시를 들어보자.
목적 설정: 웹사이트의 클릭률을 높이는 것
두 가지 버전 만들기: 두 가지 다른 디자인이나 콘텐츠를 가진 웹페이지를 만든다. 예를 들어, A 버전은 파란색 버튼을 사용하고, B 버전은 빨간색 버튼을 사용하는 것
사용자 그룹 나누기: 웹사이트 방문자를 무작위로 두 그룹으로 나눈다. 한 그룹은 A 버전을 보고, 다른 그룹은 B 버전을 보게 할당
데이터 수집: 일정 기간 동안 각 버전의 클릭률을 측정. 예를 들어, A 버전은 1000명의 방문자 중 50명이 클릭, B 버전은 1000명의 방문자 중 70명이 클릭
그룹 A: [1, 1, ..., 1, 0, 0, ..., 0] (1이 50개, 0이 950개
그룹 B: [1, 1, ..., 1, 0, 0, ..., 0] (1이 70개, 0이 930개)
베르누이분포는 1회 실행하였을 때, 결과를 0 또는 1로 표현한 분포이다. 반면, 이항분포는 각 시행마다 성공확률(p)가 정해져있을때 주어진 시행 횟수(n) 중에서 성공한 횟수(x)의 도수 분포를 말한다. 따라서 n,p에 따라 다양한 이항분포가 존재한다.
이항분포의 평균은 n * p 이며 분산은 n * p * (1-p) 이다. N이 커지면 정규분포로 근사할 수 있다.
관련용어
시행(trial): 독립된 결과를 가져오는 하나의 사건(예: 동전 던지기)
성공(sucees): 시행에 대한 관심의 결과(유의어:1, 즉 0에 대한 반대)
이항식(binomial): 두 가지 결과를 갖는다.(유의어: 예/아니요, 0/1, 이진)
이항시행(bionmial trial): 두 가지 결과를 가져오는 시행(유의어: 베르누이 시행)
이항분포(binomial distribution): n번 시행에서 성공한 횟수에 대한 분포(유의어: 베르누이 분포)
2.10. 카이제곱분포
표준정규분포를 따르고 서로 독립인 m개의 확률변수 Z1, ...Zm 을 각각 제곱하여 합치면 그 합은 자유도 m인 카이제곱 분표를 따른다. 카이제곱통계량을 이용해 자료가 어떤 특정한 확률 모형으로 나온 것인지 검정할 수 있다.
카이제곱검정은 상자의 내용 구성이 알려져 있을 때, 관측된 자료를 이 상자로부터 무작위 추출한 결과로 볼 수 있는지 그 판단 근거를 제공한다. z-검정, t-검정은 상자의 평균이 주어져있을 때 관측된 자료를 이 상자로부터 무작위를 추출한 결과로 볼 수 있는지 그 판단 근거를 제공한다.
여러 범주에 거쳐 관측된 도수와 기대도수의 차이는 카이제곱통계량으로 측정한다.
가설
귀무가설 : H0 = 범주형 데이터가 나타날 확률이 다 같다(차이가 없다).
대립가설 : H1 = 범주형 데이터가 나타날 확률이 같지 않다(차이가 있다).
카이제곱 분포의 확률 밀도 함수
정규분포의 합이 카이제곱분포임을 보여주는 수행과정
5개의 표준 정규분포 샘플을 10000개 생성합니다.
각 샘플의 제곱합을 계산합니다.
그 결과의 히스토그램을 그리고, 이론적인 카이제곱 분포와 비교합니다.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import norm, chi2
# Set the parameters
num_samples = 10000
num_normals = 5
# Generate num_samples samples of num_normals standard normal variables
normal_samples = np.random.normal(0, 1, (num_samples, num_normals))
# Sum of squares of the samples
sum_of_squares = np.sum(normal_samples**2, axis=1)
# Plot the histogram of the sum of squares
plt.figure(figsize=(10, 6))
sns.histplot(sum_of_squares, bins=50, kde=True, color='blue', stat='density', label='Sum of Squares of Normals')
# Plot the theoretical chi-squared distribution
x = np.linspace(0, 20, 1000)
plt.plot(x, chi2.pdf(x, df=num_normals), 'r-', lw=2, label=f'Chi-squared (df={num_normals})')
plt.xlabel('Value')
plt.ylabel('Density')
plt.title('Sum of Squares of Standard Normal Distributions vs. Chi-squared Distribution')
plt.legend()
plt.show()
재표본추출(재표집, 리샘플링, resampling): 관측 데이터로부터 반복해서 표본추출하는 과정. 부트스트랩과 순열(셔플링) 과정을 표현
부트스트랩(Bootstrap): 통계량이나 모수를 추정하는 방법 중 하나로, 현재 있는 표본에서 추가적으로 표본을 복원추출하고 각 표본에 대한 통계량과 모델을 다시 계산하는 방법, 데이터나 표본통계량이 정규분포를 따라야한다는 가정이없는 장점
부트스트랩 표본(Booststrap sample): 관측 데이터 집합으로 얻는 복원 추출 표본
부트스트랩 알고리즘 1. 샘프 값을 하나 뽑아서 기록하고 다시 제자리에 놓는다. 2. n 번 반복한다. 3. 재표본추출된 값의 평균을 기록한다. 4. 1~3 단계를 R번 반복한다. 5. R 개의 결과를 사용하여 - 표준편차(표본평균의 표준오차)를 계산 - 히스토그램 또는 상자그림 그리기 - 신뢰구간 찾기
부트스트랩은 다변량 데이터에서도 적용될 수 있으며, 해당 데이터로 모델을 돌려 의사결정 트리에 적용할때 이 Bagging (Boostrapping + aggregating) 이라고 부릅니다. 랜덤포레스트 모델이 대표적입니다. 부트스트랩을 공부하다보니 자꾸 순열(permutaion)이라는 단어가 등장해서 찾아보았습니다. 사실 순열이라는 것은 우리가 흔히 알듯 구별이 되는 N개의 데이터를 뽑아서 순서대로 놓는 것이라고 알고 있습니다만 여기서 등장하는 것은 정확히는 순열검정에 대한 방법입니다.
부스트랩 vs 순열검정
순열검정정의: 두 개 이상이 표본에서 그룹 간 차이가 우연에 발생한 것인지 결정하기 위한 비모수 검정 방법. 관찰된 순서나 구성을 임의로 바꾸어 샘플링하여 검정. 임의로 바꾸기 때문에 두 집단이 동일한 모집단에서 나왔다는 가정이 있어야함.
결국 t검정과 같이 한 모집단에서 등장했다는 가정을 하는 이표본 독립검정에서 확인 방법 중 하나라는 것을 알게되었습니다. 재밌군요!
2.5. 신뢰구간
신뢰수준(confidence level): 같은 모집단으로부터 같은 방식으로 얻는 관심 통계량을 포함할 것으로 예상되는 신뢰구간의 백분율입니다. 신뢰수준은 일반적으로 95%, 99%와 같이 표현되며 값이 높을수록 신뢰구간은 넓어지는 특징을 가지고 있습니다. 아무래도 엄격한 기준일 수록 더 브로드하게 표현하는게 인간 삶과 닮아있죠?
구간 끝점(interval endpoint): 신뢰구간의 최상위, 최하위 끝점을 말합니다.
부트스트랩 신뢰구간 구하기 1. 데이터에서 복원추출로 크기 n인 표본을 뽑는다.(재표본추출) 2. 재표본추출한 표본에 대해 원하는 통계량을 기록 3. 1-2단계를 R번 반복 4. x% 신뢰구간을 구하기 위하여 R개의 재표본 결과의 분포 양쪽에서 [(100-x)/2] %만큼 잘라내기 5. 절단한 점들은 x% 부트스트랩 신뢰구간의 양 끝점
다음 그래프는 tip 데이터를 바탕으로 성별에 따른 팁이 얼마나 나오는지 보여주는 막대그래프입니다.
barplot에서는 errorbar라는 옵션 중 하나로 신뢰구간을 넣을 수 있습니다. 비모수적 방법인 부트스트래핑을 적용한다고 적혀있네요.
부트스트래핑이 기본적인 옵션으로 설정된 이유는 부트스트래핑은 유연하고 강력하기 때문입니다. 데이터에 대한 기본적인 가정이 적아서 정규분포와 같은 가정을 하지도 않고도 신뢰구간을 계산할 수 있는 장점이 있기 때문이죠. 따라서 작은 샘플의 크기나 비정규분포에 유용하다고 할수 있습니다.
Seaborn에서 제공하는 errorbar 옵션에 대한 정리ci는 부트스트래핑을 사용함
열심히 부트스트래핑을 보니 이런 생각이듭니다. 아니 그럼 t분포를 통한 신뢰구간의 계산은 필요없나?
t 검정의 경우 ① 데이터가 정규분포를 따르고, 분산이 알려져 있거나 두 샘플간의 등분산성을 가정할때 유효한 제한 점이 있으나, 당연히 가정 까다로우니 신뢰구간추정이 좀 더 정확하게 작동합니다. 또한 계산식이 아주 단순한 장점이 있고 통계소프트웨어에서도 모두 지원하는 장점이 있습니다.
2.6. 정규분포
해당 소단원에서는 정규분포를 아주 간단하게 소개합니다. 사실 정규분포만으로도 족히 책 반을 덮을 수 있을텐데 2단원에서 충분히 분포를 하나씩 설명하는게 필요하다고 생각하는 것 같네요. 등장하는 용어는 다음과 같습니다.
오차(error): 데이터 포인트와 예측값 혹은 평균 사이의 차이
표준화(standardize)하다: 평균을 빼고 표준편차로 나누다.
z 점수(z-score): 개별 데이터 포인트를 정규화한 결과
표준정규분포(standard normal distribution): 평균 0, 표준편차 1 인 정규분포
QQ 그림(QQ plot): 표본 분포가 특정 분포(정규분포)에 얼마나 가까운지 보여주는 그림
2.7. 긴꼬리분포
꼬리(tail): 적은 수의 극단 값이 주로 존재하는, 도수분포의 길고 좁은 부분
왜도(skewness): 분포의 한쪽 꼬리가 반대쪽 꼬리보다 긴 정도
2.8. 스튜던트 t 분포
t분포는 윌리엄 고셋이 기네스에 근무 때 고안한 방법입니다. 통계에서는 3형제의 분포가 등장하는데 t분포, 카이제곱분포, F분포 각 분포는 집중하는 통계량이 표본의 평균, 분산, 그리고 분산의 비를 구하는데 관심이 있습니다.
t분포는 정규분포처럼 좌우 대칭인 종모양이지만 그 꼬리가 더 두껍다는 특징을 가지고 있습니다. 모분산을 모를 떄 표본분산을을 대신 사용하여 모평균을 추정하는 방법을 사용합니다. 대표적으로 일표본 검정(모평균을 검정), 이표본 검정(두 모집단의 평균을 검정)하는 방법들이 있습니다. 꽤나 자주 쓰이여 아마 통계검정을 떠올린다면 Z검정 다음으로 생각할 수 있는 검정 방법입니다.
커널밀도추정(Kernel Density Estimation): 밀도 추정이란 관측된 데이터로 원래 변수의 확률 분포 특성을 추정하는 것이다. 여기서 밀도 추정 방법에서도 Parametric 한 방법과 Non-Parametric 한 방법으로 나누어진다. Parametric 방법은 정규분포와 같은 분포를 가정하고 밀도를 추정하는 것이다.
반면 현실에서는 이렇게 모델이 미리 주어지는 경우가 없으므로 순수하게 관측된 데이터만으로 확률밀도함수를 추정행해야하는데 이를 Non Parametric 추정이라고하며 대표적으로 histogram 방법, 커널밀도추정이 있다.
이상치의단점으로 인해 평균이 대표성이 약해진다는 것은 널리 알려진 사실이다. 이를 보완하기 위한 가중평균은 어떤경우에 잘사용되는지 궁금해졌다.
- 가중평균의 활용
중학교 남자의 평균점수가 30점이고 여자의 평균점수가 50점이라면 전체 평균점수는 40점인가? 이는 산술평균의 큰 함정이다. 두 값을 1:1로 생각하고 평균을 내려면 남자와 여자의 수가 같다는 전제가 있어야한다. 따라서 가중평균을 사용할 필요성이 있다. 즉 더 무거운 무게중심에 보정을 해주는 것이다.
가중평균 = 남자 학생의 평균점수 x 남자학생의 비율 + 여자학생의 평균점수 x 여자학생의 비율 여기서 남학생과 여학생의 비율의 합은 1이 되는 것이 합리적일 것이다.
가중평균식
- 가중 통계량의 장단점
장점
데이터별 가중치를 반영하여 합리적인 통게량 제공
가중치를 이용한 패턴 발굴
이상치에 덜 민감
구현이 쉬움
단점
어떤 가중치가 더 좋은 것인지 판단하는 작업이 필요(주관)
3. 조화평균의 활용성
평균에는 산술평균 기하평균 조화평균이 있다. 대부분 산술평균을 평균이라는 대명사로 쓰긴 하지만 실제로이런 산술평균이 잘 먹히지 않는 경우가 있다.
A지점과 B지점를 왕복하는데 걸리는 시간을 계산해보고자 한다. 갈때 6km/h 올때 12km/h로 온다고 했으니 각각 2시간,1시간이 걸려 총 3시간이 걸린다.
반면 산술평균을 이용해서 9km/h 평균속도를 구하고 24km를 나누면 2.7시간이 나온다. 산술평균은 이처럼 비율의 평균을 구하는데 적합하지 않다. 이 경우 조화평균을 이용하여 계산하면 정답이 도출된다.
조화 평균은 머신러닝에서 분류문제를 평가하는 F1-score에서도 등장한다. F1 score는 실제 정답데이터를 맞춘 비율(재현율)과 정답을예측한 데이터를 맞춘비율(정밀도) 2가지 지표를 고려한다.
이경우 산술평균을 이용하면 둘 중 하나의 지표가 압도적으로 좋아 극단값으로 작용하면 실제 반대 지표가 높지 않음에도 과대평가될 위험이 있다. 이를 위해서 조화평균을 사용하게 된다. 조화평균은 기본적으로 비율의 평균을 낼때 사용하게 되며 둘 중 하나의 값이 극단값이라고해도 전체 값은 변동이 덜한편이다. 반면 두 지표가 모두 높거나 혹은 낮을때 잘 작동하는 특징이 있다.
데이터 수집부터 시작하고자하는 데이터 직무라면 파이프라인에 대해서 고민하게 될 것이다. 다양한 방법이 있겠지만 나는 그렇게 부지런한편이 아니니 가장 간단하게 자동화하고 싶은 마음에 GCP을 사용하기로 했다.
가장 무난하게 할 수 있는 데이터 파이프라인
본 글에서는 GCP 서버를 세팅하여(자동화), kamis API에서 데이터를 주기적으로 데이터를 수집하고(수집, 전처리), 이를 데이터베이스에 저장하고(적재) 시각화하여, 제철과일을 싸게 먹겠다(액션 플랜) 라는 목적으로 시작된 사이드 프로젝트이다. 이를 위한 빌드업은 다음 글에 작성하였다.
우측: 현재 기본 세팅으로 했을 때 나오는 예상 가격이다. 당연하지만 성능이 좋아질수록 가격이 올라간다.
구글로부터 컴퓨터를 "대여" 하는 것이기 때문에 빌리는 것만으로도 비용이 나온다. 마치 집에 있지 않아도 나가는 우리집 관리비 처럼 ~_~
중앙: 인스턴스를 셋업하기 위한 상세 설정이다. 사양 등 세부 설정을 할 수 있다.
인스턴스 생성 형태
예상 가격
인스턴스 세부 설정에서 확인할만한 사항은 다음과 같다.
리전(Regions) : Google Cloud Platform 서비스들이 제공되는 서버의 물리적인 위치
영역(Zones) : 리전(Regions) 내 Google Cloud Platform 리소스의 배포 영역
리전과 영역 설정에 따라 예상가격이 달라진다. 서울권을 설정하면 Latency와 같은 부분이 더 좋아질 수 있다고는 하나 공급이 다른 지역보다 적기 때문에 가격이 올라간다. 우리의 경우 Latency가 그렇게 큰 부분은 아니기 때문에 기본지역으로 설정했다.
인스턴스 세부 설정 & 리전
머신 구성: 인스턴스 자원 변경 가능
부팅디스크: 디스크와 운영체제(리눅스 배포판)을 선택 가능
머신 구성부팅 디스크
이후 방화벽에서 HTTP 트래픽 허용을 누르고 만들기를 클릭하면 수분 내 인스턴스가 생성된다.
방화벽 설정 & 인스턴스 생성
생성이 완료되면 다음과 같이 뜨며, 내부IP, 외부IP와 연결 부분이 생성된다. 내부IP는 말그대로 내부 네트워크(Google 서버내)에서만 접근 가능 하기 때문에 보안이 우수하다. 또한 지연속도가 적고(속도가 빠름) 비용이 저렴한 특징을 가지고 있다. (외부 인터넷을 사용하지 않아도 되니)한 장점이 있습니다. 외부 IP는 우리가 사용하는 인터넷 IP이다.
인스턴스 생성 완료
위해서 연결부분의 점 세개를 누르면 브라우저 창에서 열기를 통해 접속이 가능하다.
초기 인스턴스 화면
무료 크레딧으로 인해 과금은 안되지만 추가 비용을 막거나 인스턴스를 내리고 싶다면 같은 방법으로 중지/정지/삭제가 가능하다.
중지: 일시정지에 해당하며 OS, 메모리를 그대로 유지하는 상태, 60일 이후 정지로 변경
기본적으로 GCP 인스턴스를 생성하면 Python은 깔려있다. 그 외에 필요한 유틸리티는 apt를 통해 직접 설치해야한다.
python3 --version
기본적인 리소스 확인도 가능하다. top 유틸리티는 조금 못생겨서, htop을 설치한다.
#기본 자원관리자
top
#htop 설치
sudo apt-get install htop
htop
✅ 빅쿼리 연결
같은 Google 제품이다보니 gcloud 명령어가 설정되어있고 손쉽게 bigquery를 연동할 수 있다.
gcloud auth login
#이후 나오는 링크를 통해 인증
#현재 기본프로젝트가 설정되어있지 않다면
#현재 계정에 있는 프로젝트 리스트 확인
gcloud projects list
#프로젝트 선택
gcloud config set project <프로젝트명>
나는 kamis.str 데이터를 이미 빅쿼리에 올려놓아서 설정하여 볼 수 있다.
#bq명령어는 빅쿼리를 볼때 사용하는 명렁어
#현재 데이터 셋 확인
bq ls
#현재 데이터셋의 테이블 명확인
# bq ls <데이터셋 명>
bq ls kamis
#SQL 쿼리날리기
# bq query 'SQL 명령어'
bq query --use_legacy_sql=false 'SELECT * FROM `kamis.str`'
3. 자동화 익히기
✅ Linux 스케줄러 Cron 알아보기
gcp 설정을 마쳤다면 Linux 의 스케쥴러인 Cron을 익혀볼 차례다. Cron이란 스케쥴링을 담당하는 Linux 유틸리티로, Crontab은 Cron table의 약자로, 실행할 명령어를 담고있는 파일이다.
Cron 주기
* * * * * {실행 명령}
순서대로 분(0-59), 시(0-23), 일(0-31), 월(21), 요일(0-6)
요일은 0(일), 1(월)… 6(토)
*은 모든 이라는 뜻이므로
예시
* * * * * {실행명령} : 매 분 마다 실행
*/10 * * * * {실행명령} : 매 10분 마다 실행
0 12 * * * {실행명령} : 매일 정오 12시에 실행
crontab 관련 명령어
which crontab : crontab 위치경로 확인
crontab -e : 편집
crontab -l : 작업 내용 확인
crontab -r : 전체 작업 삭제
Cron 스스로 작동하는게 아니고 sytemctl 이라는 리눅스 서비스 관리프로그램으로 시작과 종료를 시킨다. 따라서 다음 명령어를 사용해야한다. 관리자 권한 sudo 가 필요하다. 또한 Crontab 설정을 변경할 때마다 재시작 해줘야 한다.
systemctl restart cron: cron 재시작
systemctl start cron : cron 시작
systemctl stop cron : 중지
systemctl status cron : 작동확인
✅ Hello world 출력하는 실행파일 만들기
Linux에서 문자를 출력하는 쉘파일(.sh)를 만드는 것은 nano 편집기를 이용해서 .sh 실행파일에서의 출력문인 echo 를 사용하면된다.
#nano 편집기로 만들기
#이름을 정하면 알아서 해당 이름의 파일을 생성
nano hello.sh
#hello.sh 파일에서 다음 내용을 입력
echo "Hello World!"
이후 CTL + X -> Y를 이용해서 nano 편집기 저장 후 나오기를 하면 된다. 이후 .sh 파일을 실행하는 것은 sh 명령어를 사용하면 된다.
sh hello.sh
✅ 매분마다 출력하는 실행파일 만들기
sh 파일을 만들었으니 이를 cron 에 태워서 주기적으로 실행하게 만들면 된다. 이때 설정해야하는 것은 (1) crontab에 해당 sh파일 위치 알려주기 (2) systemlctl을 이용해서 crontab 실행해 주는 것이다.
# 현재 경로확인
pwd
# crontab 편집
crontab -e
# crontab에 매분 해당 파일을 실행하도록 입력
# 동시에 출력을 .log 파일로 보내고
# 2>&1 구문에 따라 오류 메세지도 동일한 파일로 보냄
* * * * * /home/jayjunglim/hello.sh >> /home/jayjunglim/hello.log 2>&1
# crontab 나와서 현재 변경내역 확인
crontab -l
#설정한 내용 저장하기 위하여 재부팅
sudo systemctl restart cron
# cron 시작하기
sudo systemctl start cron
# 상태확인
sudo systemctl status cron
cron이 실행되고 있음을 확인
이후 로그 파일을 열어보면 잘 작성됨을 확인할 수 있다.
# 로그 확인
nano hello.log
# cron 종료
sudo systemctl stop cron
4. OPEN API 데이터 빅쿼리에 저장 자동화하기
이제 이모든 것을 합쳐 OPEN API 로부터 데이터를 가져오고 이를 빅쿼리에 저장할 것이다. 또한 이를 자동화를 태울 것이다. 엄격히 말하면 매일 자동화를 시켜서 누적되는 데이터를 보아야겠지만, 데이터 삭제 & 새로 생성 하는식으로 자동화를 테스트해볼 생각이다.
이전에 환경세팅해줄 것이 몇가지 있다. 먼저 git을 설치하여 github 에 있는 코드 뭉치를 가져올 것이며, python 가상환경 설치를 해야한다.
✅ 깃 설치 및 환경설정
깃 설치
# 깃 설치
sudo apt-get install git
#폴더생성
mkdir wheresisplanb
#리포지토리 파일 복사
git clone https://github.com/bellepoque7/whereisplanb.git
#(선택) 만약 repository를 이미 clone하였고, 업데이트 사항이 있다면
git pull https://github.com/bellepoque7/whereisplanb.git
해당 리포지토리에서는 데이터를 불러오고 전처리하는 web_api_kamis.py 파일과 이를 빅쿼리에 kamis2bq.py 적재하는 파일을 사용할 예정이다. 만약 빅쿼리가 어색하고 파이썬으로 데이터 적재하는 법을 알고 싶다면 다음 글을 참고한다.
web_api_kamis 는 농수산물 데이터(kamis)를 가져오기 위한 데이터이며, 이를 빅쿼리에 저장하기 위해서 kamis2bq.py 스크립트를 따로 만들었다. 해당 스크립트는 딸기 데이터에 대하여 데이터를 가져오고 빅쿼리에 데이터가 있다면 삭제하고 업로드 하는식으로 최신화 하는 형태이다.
제일 좋은 건 계속 누적해서 데이터를 수집하는 것이지만 일단 prototype을 만들고 추가 적재를 하기위해서 코드을 추가하기로 하였다.
kamis2bq.py 스크립트
#GCP debain 환경에서 실행되는 코드
import pandas as pd
from web_api_kamis import *
from google.cloud import bigquery
from google.cloud.exceptions import NotFound
import time
# df_cd = pd.read_csv('./Data/category_detail_code.csv', encoding = 'euc-kr')
#데이터 불러오기 및 전처리
start = time.time()
df_str = kamis_api_2(itemcode ='226')
df_str = df_str.assign(date = lambda x : df_str['연도'] + '/' + df_str['날짜'])
df_str['date'] = pd.to_datetime(df_str['date'], format = 'ISO8601')
df_str = df_str.assign(price_100g = lambda x: x['가격'].str.replace(',','').str.replace('-','0').astype('int')/20)
df_str.columns = ['itemcode','kindcode','countrycode','market','year','origin_date','tot_price','date','price_100g']
print('1/4 데이터 전처리 완료')
#빅쿼리 연결 설정
project_id = 'challenge-a-418407'
client = bigquery.Client(project=project_id)
dataset_id = 'kamis'
table_id = 'str'
full_dataset_id = "{}.{}".format(client.project, dataset_id)
print('2/4 빅쿼리 연결 설정 완료')
#스키마 설정(빅쿼리에 올라갈 데이터 형태)
schema = [
bigquery.SchemaField("itemcode", "STRING"),
bigquery.SchemaField("kindcode", "STRING", mode="NULLABLE"), # NULL 값을 허용
bigquery.SchemaField("countrycode", "STRING"),
bigquery.SchemaField("market", "STRING", mode="NULLABLE"), # NULL 값을 허용
bigquery.SchemaField("year", "STRING"), # 연도가 숫자로만 구성되어 있더라도, 여기서는 문자열로 처리
bigquery.SchemaField("origin_date", "STRING"), # 날짜를 문자열로 처리할 수 있지만, DATE 타입을 사용하는 것이 더 적합할 수 있음
bigquery.SchemaField("tot_price", "STRING"),
bigquery.SchemaField("date", "DATE"), # datetime64[ns] 타입은 BigQuery의 DATE 타입으로 매핑
bigquery.SchemaField("price_100g", "FLOAT64"), # float64 타입은 BigQuery의 FLOAT64 타입으로 매핑
]
job_config = bigquery.LoadJobConfig(schema=schema)
dataset_ref = client.dataset(dataset_id)
# 데이터셋이 없을 경우, 데이터셋 생성
try:
client.get_dataset(dataset_ref)
print("{} 데이터셋 이미 존재".format(full_dataset_id))
except NotFound:
dataset = bigquery.Dataset(full_dataset_id)
dataset.location = "asia-northeast3"
client.create_dataset(dataset)
print("{} 데이터셋 생성".format(full_dataset_id))
print('3/4 dataset 생성체크 완료')
# 테이블 존재 여부 확인
table_ref = client.dataset(dataset_id).table(table_id)
try:
client.get_table(table_ref)
client.delete_table(table_ref)
print("{} 테이블이 존재하여 삭제.".format(table_id))
except NotFound:
print("{} 테이블이 없어 생성필요".format(table_id))
job = client.load_table_from_dataframe(df_str, table_ref, job_config = job_config)
job.result()
end = time.time()
print("4/4 작업완료, {}초 소요".format(round(end-start)))
또한, cert_info.py을 생성해야하는데 이 부분은 kamis api를 사용하기 위한 인증키 파일이다.
Debian Linux에서는 글로벌 파이썬 패키지 설치가 불가능하고 권장되지 않으므로 가상환경을 설정한다.
sudo apt install python3.11-venv
#가상환경 생성(이름:env11)
python3 -m venv env11
#가상환경 실행
source env11/bin/activate
# 가상환경 종료
# deactivate
#설치된 리스트 보기
pip3 list
# 가상환경 활성화 되어있을 때
# Python 모듈 통합설치
pip3 install -r requirements.txt
#혹은 개별 설치
pip3 install pandas requests matplotlib pyarrow pandas-gbq
#google모듈 import 에러 해결
pip3 install --upgrade google-api-python-client
pip3 install google-cloud-bigquery
#설치확인
pip3 list
위 설정이 모두 마무리가 되었다면 준비는 끝났다.
✅ 스크립트 실행 및 자동화 태우기
python3 kamis2bq.py
위와 같이 뜨면 성공.
빅쿼리스튜디오에서도 테이블 세부정보를 보면 잘 작동했음을 확인할 수 있다.
Big query Studio 화면
자동화를 태우고 싶으면 crontab 파일을 설정해주면 되며, 이때 중요한 점은 가상환경으로 설정했기 때문에 가상환경 경로의 Python 디렉토리를 구체적으로 작성해주어야 정상적으로 실행된다.
#cron 접속
crontab -e
# 다음 텍스트 삽입
# (매일 정오 마다) / (가상환경의 파이썬3으로)
# (다음 경로의 파일을 실행해라) / (로그를 남겨라)
0 12 * * * /home/jayjunglim/env11/bin/python3 /home/jayjunglim/whereisplanb/kamis_api/kamis2bq.py >> /home/jayjunlimg/kamis.log 2>&1
# 설정변경했으니 재시작
sudo systemctl restart cron
# 스케쥴링 시작
sudo systemctl start cron
정상적으로 실행되는 모습
이후 대시보드에 연결해서 100g당 도매 가격현황을 볼 수 있다.다음은 딸기의 가격이다. 도매 기준으로 100g당 1000원에 정착하고 있으므로 마트 구매에 참고하시라. 요즘 1000원대로 많이 내려온 걸 실제로 확인할 수 있었다.
이렇게 해서 미루고 미뤘던 데이터 적재 자동화 프로토타입 만들기까지 완성했다. 작년초부터 만들어야지 하면서 미뤘던 건데, Linux에 익숙하지도 못했어서 삽질을 많이 했는데 이번에는 반나절정도에 해결할 수 있어서 매우 뿌듯하다. 이제 해야할일은 주기적으로 데이터 적재해서 현재 적절한 가격을 볼 수있게 만드는 것! 아무래도 간단하게 steamlit으로 구현하면 되지 않을까 싶다.
부트캠프에서 자동화 강의를 준비하다보니 생각보다 컴퓨터 기본 하드웨어 지식이 부족한 사람들이 많다. 컴퓨터 내에 덕지덕지 RAM을 차지하고 있는 프로그램이 있는지 모르고 쓴다던지... 컴퓨터를 어떤 사양의 기준으로 사야할지 등등 그래서 GCP 서버 구축하는 법을 알려줄 겸 기본적인 하드웨어 지식과 함께 강의한 내용을 정리 해보려고 한다.
예상독자
Computer Science 지식이 전무한사람
1. 운영체제란
회사를 입사하게 된다면 IT직군에 한하여 맥북 vs 윈도우 노트북의 양자택일 선택지가 주어진다. (물론 선택지가 없는 경우도 많지만). 사실 이 경우 운영체제가 가장 중요한 기준이 될 것이다. 근데 운영체제가 뭐냐고 한다면..
운영체제(OS, Operating System): 컴퓨터 하드웨어의 리소스를 관리해주면서 동시에 여러 어플리케이션이 작동할 수 있는 환경을 제공해주는 소프트웨어. 개인용 데스크탑에서는 Windows를 가장 많이쓰고, Linux, Mac 등이 존재
운영체제 종류
아마 우리에게는 두가지 선택지가 있으니 이 부분을 기술 하자면 다음과 같다.
Windows
어릴때부터 학습된 운영체제
그래픽인터페이스(GUI)의 편리함
제어판, 탐색기 등 대부분의 기본 프로그램에 익숙
MacOS
애플에서 개발한 운영체제
기본적으로 GUI는 이질적이지 않으나 후술할 Linux기반 파일 디렉토리 때문에 분석가들 환경 설정의 어려움
프로그래밍 or 디자인 기능 특화
그래서 무엇을 쓸까? 를 고민한다면 거의 모든 대부분의 경우에는윈도우를 추천하는 편이다. 이유는 1. 따로 운영체제에 대한 학습이 필요하지 않으며 2. MS가 제공하는 3신기(Docs, Excel PPT) 활용도가 좋기 때문이다.
반면 맥북이 갖는 장점은 1. 이쁘다 간지난다. 2. Linux 계열 컴퓨터 언어를 조금 이해할 수 있다.(강제로 학습하게 된다)3. 운영체제 관리가 잘되어서 적은 램으로도 잘 돌아간다는 점이다.
사실 나는 위 장점/단점을 고른다기보다는 단 하나의 맥북의 단점으로 고르게 되었는데 그것은 맥북에서 편집한 파일의 윈도우에서 자-모음 분리현상 때문이다. 정말 사소하지만 메일로 일하는 나에겐 너무 프로페셔널 해보지 않아서 윈도우로 갈아타는 계기가 되었다. 물론 Google Drive 업로드 후 첨부 등 우회방법이 있지만 굳이 그걸 신경쓸만큼 맥북이 이득이 없다라고 판단했다.
본인이 분석가면 대부분의 경우의 윈도우가 정답이다.
2. 하드웨어
✅ 컴퓨터 하드웨어 설명
예산이 되어있는 개인 구입일 때는 비용도 제한하게 되는데, 이때 고민하는 것이 하드웨어 사양이다. 사실 서버를 돌릴 때도 간단한 작업은 비싼 장비는 필요 없을 뿐더러 비용만 더 많이 나가기 때문에 적당한 걸 선택한다. 보통은 무료 tier에 가까운걸로..?
간단 정리하자면 CPU, RAM, 디스크가 있고 요즘은 딥러닝 혹은 그래픽 작업에 의해서 GPU까지 얘기하지만 서버를 대여할때는 딥러닝까지 한다면 빌려야겠지만 비용이 상당하기 때문에 개인 입장에서는 GPU까지 고민하면서 서버를 쓸 정도면 이미 이 부분은 잘 알거라 생각한다.
CPU(Central Proceesing Unit)은 중앙처리장치로 모든 연산을 담당
메모리는 일시 기억을 담당
데이터 분석 툴은 대부분 램에 데이터를 담기 떄문에 클수록 선호
재부팅하면 날라감
혹은 프로그램을 끄면 날라감(왜? 메모리는 모든 프로그램에서 써야하니까 방빼!)
저장공간(HDD, SSD)는 영구 기억을 담당
역시 클수록 좋습니다.
그래픽카드는 부동소수점 연산을 담당
쉽게 말하면 그래픽을 담당
최근에는 딥러닝 수행에 아주아주 큰 역할
대부분의 데이터분석은 그래픽카드는 필수 요건은 X
여기서 CPU와 RAM을 묶어서 컴퓨터 자원이라고 명명한다. 대부분 분석가들은 최적화는 신경 잘 안쓰고 컴퓨팅 파워에 맡기나 별로 좋은습관은 아니다. 특히 대용량 데이터를 다룰때는 굉장히 중요해진다.
✅ 컴퓨터 사양 확인 방법
위 내용을 현실적으로 이해하려면 본인의 컴퓨터 사양을 확인해보면 될 것이다.
윈도우의 경우는
기본 사양: window 키 + R → dxidag 입력
컴퓨터 자원확인: CTL + SHIFT + ESC
맥북의 경우는
기본사양: 왼쪽 상단 애플마트 - 이 Mac에 관하여
컴퓨터 자원 확인: Command + space -> 활성 상태 보기
3. Linux
GCP를 셋업하기로 했으면 제3의 운영체제 Linux에 대해서 알아야한다. 사실 모든 운영체제의 조상 UNIX으로부터 태어난 운영체제이기 때문에 우리가 알게 모르게 사용하는 컴퓨터 자원은 거의 Linux로 구동된다. 개인용 컴퓨터 PC가 아무래도 현실에 자주 마주하는 컴퓨터다 보니까 입문자들이 이런 부분을 모르는게 대부분이다.
✅ Linux란 ?
Linux는 1991년 Linus Torvals가 Unix 운영체제 기반으로 개발한 무료소프트웨어 운영체제로 현재 전세계적으로 300여가지의 배포판이 존재하여, 사용자에 따라 결정할 수 있는 폭이 넓음 (ex 개인용컴퓨터, 모바일. 여러분들이 사용하는 PC 외에 대부분 SaaS 서비스가 리눅스 기반 (Colab도!) 배포판 분류로 회사에서 관리하는 레드햇, 우분투 커뮤니티 관리하는 데비안, 젠투, 페도라가 있다.
✅ Linux 용어 정리
커널(Kerenel)은 운영체제의 핵심으로 메모리관리, 프로세스 관리, 장치 관리 등 컴퓨터의 모든 자원을 제어하는 유틸리티이다. 또한, 디렉토리(Directory)는 윈도우로 따지자면 파일 구조(탐색기)이며 파일 시스템에 의해 관리 되고 있다. 아무래도 리눅스를 처음 접할 때 파일 구조가 달라서 많이 혼동하곤 한다. 사실 윈도우에 파일시스템도 샅샅이 아는 사람은 드물 것...
경로별 간단 설명을 하자면
/ : 파일 시스템의 가장 최상단 디렉토리(Root 디렉토리)
/bin: 리눅스의 기본적인 명령어가 저장된 디렉토리
/home: 일반 사용자의 홈 디렉토리(자주 접근)
/boot: 운영체제 구동시 부팅 설정 파일이 존재
/usr : 일반 사용자를 위한 프로그램 파일(윈도우의 Program files)
/usr/bin: 일반 사용자들이 사용가능한 명령어 파일이 존재하는 디렉토리
/usr/local: 새로운 프로그램이 설치되는 공간
이때 디렉토리 경로를 표현하는 방식은 2가지가 있다.
절대경로
이름 그대로 절대적인 경로
Root 부터 시작하는 경로를 지정하며 어느 파일에 넣든 정확한 경로를 전달함
예시
(ex 경기도 관양시 관평로 OOO번길 OO, 101-202) → 어디서 찍든 동일한 집임
상대 경로
현재 내 위치 기반 상대 경로
. : 현재 디렉토리
.. : 상위 디렉토리
예시
우리집 윗층 → 우리집이 어디냐에 따라 윗층이 달라짐
✅ 쉘(Shell)
쉘은 Linux 사용하기 위한 인터페이스이며 기본적으로 키보드만 사용 가능하다. 마우스와 같은 UI가 익숙한 사람들 여기서 숨이 턱막힌다. 쉘은 사용자가 입력한 명령어를 실행하여 다른 프로그램이나 커널로 전송하는 기능을 하는 유틸리티이며, 사용자와 커널의 중간다리로 리눅스는 Bash 를 기본으로 사용한다. 분석가 기준으로 대표적인 명령어로 pip(파이썬 패키지 관리자)가 있다. Python 패키지를 설치하는 리눅스 명령어이자 유틸리티 이름이 pip인 것이다. 윈도우에서는 명령프롬프트(Command)가 있으며 명령어는 다르다. 반면 Linux Shell 명령어와 유사한 Powershell 이 기본으로 탑재되어 있다.
회사 다니면서 알음알음 알아왔던 지식이여서 나름 다들 공통적으로 아는 내용이라고 생각했는데 생각보다 정리해보니 알려줄 내용이 꽤 많다. 암묵지의 형태는 생각보다 방대하고 정리할 가치가 있는 것 같다. 다음 글로는 GCP을 세팅하고 Crontab을 이용해 데이터 적재를 자동화하는 글을 작성할 예정이다. GoGo