• 해당 분석은 여러 변수를 활용하여 "종류"를 예측하는 이진분류 모델을 voting classifier를 통해 구현해 본 것입니다.

  • 순서는 아래와 같습니다.


Step 1.

전처리


Step 2. 

모델링


Step 3. 

모델 서빙



데이터 import 진행


데이터 split 진행





데이터의 outlier를 잡기 위하여 

min-max가 아닌 robust scaling을 진행 




타겟 변수인 예측을 위한 모델링 진행




이전 실험에서 가장 높은 정확도를 보인 

Random Forest와 XGBoost에 대한 cross validation 진행


SVM / RF / XGB에 대한 grid search와 

"soft" voting classifier 구현 




"soft" voting classifier 구현 - 확률을 예측할 것이기 때문



sql server와 연동하여 model serving

- 예측치(확률)을 결과값으로 받을 수 있게



Confusion matrix(혼동 행렬)?

  • 모델링 성과를 평가하는 지표 중 하나
  • (당연하지만) 분류에 한정되어 사용

  • 여기서 Actual은 실제 값을 뜻하며, Predicted는 예측한 결과물을 뜻한다.
  • 즉, TP(True Positive)와 TN(True Negative)가 높을수록 좋은 성능을 보여준다

Precision
  • TP / TP+FP
  • 즉, 내가 예측한 값 중에서 정답이 있을 경우(1에 가까울수록 좋다)

Recall(= sensitivity 민감도)
  • TP / TP+FN
  • 즉, 실제 1인 값 중에서 1이라고 예측한 것이 있을 경우(1에 가까울수록 좋다)


Accuracy 

  • TP + TN / TP+FP + TN + FN
  • 전체 경우의 수 중에서 정답으로 분류한 비율(1에 가까울수록 좋다)

F1 Score?


  • 왜 사용하는가? --> Precisoin 과 Recall의 밸런스를 고려하여 정확도 측정
  • Precison과 Recall이 한쪽만 높게 될 경우 문제가 된다. 
  • 하지만 특별한 상황의 경우 두 지표중 한쪽에 weight 를 두고 평가하게 된다. 아래의 예시 참고


Precision vs Recall?

  • 만약 탐정이 "도둑"을 예측한다고 해보자.
  • 이 때, Precision이 30%(== 탐정이 "도둑"이라고 예측한것 중, 진짜 도둑인 것의 비율)은 용납할 수 있다.
  • 하지만, Recall이 30%라면(진짜 도둑들중에서 탐정이 도둑이라고 예측한 것의 비율), 이 부분은 용납되기 어렵다. 
  • 안타깝게도, precision과 recall은 일종의 trade-off 관계를 가지게 되어, precision이 높으면 recall이 낮고.. 하는 관계를 가진다.


  • 그림에서 볼 수 있는 것처럼, recall은 우하향하게 되면 끊임없이 낮아지고, 상승하게 되면 꾸준히 완만하게 상승한다
  • 하지만, Precision은 꾸준히 상승하지만 "일시적으로" 낮아질 수 있다.


Intro

오늘 포스팅에서 다룰 주제는 Seaborn 라이브리러를 활용한 데이터 시각화 튜토리얼 (2)입니다.

해당 라이브러리에 대한 자료는 아리 링크에서 확인하실수 있습니다.

  • http://seaborn.pydata.org/index.html

참고자료

  • http://seaborn.pydata.org/tutorial.html (공식 홈페이지 튜토리얼)

  • https://datascienceschool.net/view-notebook/4c2d5ff1caab4b21a708cc662137bc65/


Plotting with categorical data

  • 데이터가 2차원이고 실수 값, categorical값이 섞여 있다면 기존의 플롯 이외에도 다음과 같은 분포 플롯들을 이용할 수 있다.


Boxplot

  • Boxplot은 사분위수 Quantile를 함께 표시해준다.
  • Quantile(사분위수)는 지나치게 범주에서 벗어나는 값들을 제외하고 핵심적인 범주의 데이터만 범위로 지정할 수 있는 방법중 하나

  • 사분위수에 대한 자세한 설명은 이곳으로


  • day는 categorical 범주형 data, total_bill은 numeric 실수형 data
  • 1Q - 3Q, 최대값 최소값 표시, 그 외 점들은 outlier 


Barplot

  • 가장 자주 쓰이는 형태중 하나

  • data 확인


  • x와 y축 뿐만 아니라 hue로 categorial 형의 hue에 따른 분포 확인 가능 


Plotting subsets of data with semantic mappings

  • x와 y가 numeric일 때 사용 

  • data 확인


  • line 형태로 time point 에 따른 signal 변화 확인 가능 


  • line 형태로 event별 time point 에 따른 signal 변화 확인 가능 


Visualizing the distribution of a dataset

  • univariate distribution 일변량(종속변수가 한 개인 데이터)의 분포 확인 가능

distplot

  • seaborn의 dist는 matplot의 hist를 (히스토그램)을 기반으로 하고있다.
  • x축은 변수 - 여기서는 랜덤으로 부여한 숫자 / y축은 커널 밀도 추정(Kernel Density Estimation)을 거친 정규화된 수치

  • Kernel Density Estimation이란 히스토그램을 구한 후 구해진 히스토그램을 정규화하여 확률밀도함수로 사용하는 것

  • KDE에 대한 자세한 자료는 해당 링크 참고: http://scikit-learn.org/stable/modules/density.html


  • kdf=False를 해주게 되면 y축에 해당 분포에 대한 절대치가 출력된다
  • rug = True로 해줄시 선분으로 해당 데이터의 위치가 표시된다


jointplot


  • 두 데이터가 모두 연속형의 실수값 numeric 이라면 두 변수간 관계를 jointplot을 통해 표시할 수 있다
  • 상단 부분과 오른쪽 부분에 해당 변수의 히스토그램도 함께 출력하게 된다 

Visualizing linear relationships

  • 선형 관계 확인 

lmplot

  • data 정보 확인 


  • 직선으로 x축과 y축에 선형 관계를 표시할 수 있다 


  • regplot과 lmplot은 단독으로 사용하였을때는 큰 차이가 없다

  • 하지만 lmplot을 주로 사용하는데 그 이유는 아래서 다시 설명하겠다



  • 이런식으로 깔끔하게 표시할 수 있다(outlier를 제외하고 표시해줌)


  • regplot과 달리 lmplot은 hue 파라미터로 categorial 변수를 지정하여 카테고리별로 각각 데이터의 분포와 선형 관계를 표시할 수 있다

  • 위 그래프는 smoker별로 total_bills에 따른 tip의 관계를 표시한 것 


Intro

오늘 포스팅에서 다룰 주제는 Seaborn 라이브리러를 활용한 데이터 시각화 튜토리얼입니다.

해당 라이브러리에 대한 자료는 아리 링크에서 확인하실수 있습니다.

  • http://seaborn.pydata.org/index.html

참고자료

  • http://seaborn.pydata.org/tutorial.html (공식 홈페이지 튜토리얼)

  • https://datascienceschool.net/view-notebook/4c2d5ff1caab4b21a708cc662137bc65/


Scatter plot 산포도

replot()는 아래와 같은 경우에 사용할 수 있습니다

  • 분석하고자 하는 데이터가 모두 numeric 실수 값인 경우데이터가 2차원이고 모두 연속적인 실수값


  • 라이브러리 import 및 데이터셋 확인


  • 기본적인 scatterplot 형태 - x축과 y축을 인자로 지정가능
  • total_bills에 따라 tip이 얼마나 분포되어 있는지 확인가능


  • 카테고리형 데이터가 섞여 있는 경우에는 hue 파라미터에 카테고리 변수 이름을 지정한다
  • 이를 통해 카테고리 값에 따라 색상을 다르게 할 수 있다
  • smoker 여부에 따라 total_bills에 따라 tip이 얼마나 분포되어 있는지 확인가능

  • style 파라미터를 통해 모양을 다르게 줄 수 있다


  • hue에는 numeric data 실수형 데이터도 줄 수 있다 
  • 이 때, 점의 색 혹은 크기로 hue 표시
  • size 크기에 따라 total_bills에 따라 tip이 얼마나 분포되어 있는지 확인가능


  • 점(scatter)의 크기로 hue를 설정할수 있다.


  • 분석하고자 하는 데이터가 categorical 이라면 아래와 같은 함수를 이용할 수 있다 

  • 라이브러리 import 및 데이터셋 확인

  • 기본적인 scatterplot 형태 - x축과 y축을 인자로 지정가능
  • 요일에 따라 total_bills가 어떻게 분포되어 있는지 확인 가능 


  • jitter 파라미터를 활용해 데이터 분포 출력 방법을 조절할 수 있음(위 그림과 비교)

  • scatterplot과 마찬가지로 hue로 categoril 변수를 줄 수 있으며 다른 색으로 구분 가능 


  • kind="swarm" 파라미터를 활용해 데이터 분포 출력 방법을 조절할 수 있음(위 그림과 비교)



  • smoker에 따라 tip을 얼마나 주는지 표시 - smoker은 yes/no 두 개 output으로만 구분되는 변수이다.



Intro

오늘 포스팅에서 다룰 주제는 Facebook에서 공개한 FBprophet 라이브러리를 활용한 시계열 데이터 예측입니다.

해당 라이브러리에 대한 자료는 아리 링크에서 확인하실수 있습니다.

  • https://facebook.github.io/prophet/docs/quick_start.html

해당 데이터는 캐글에 공개된 아보카도의 가격 관련 데이터입니다.

  • https://www.kaggle.com/neuromusic/avocado-prices

오늘 사용할 데이터 셋의 구성과 설명은 아래와 같습니다. 




예측 진행 과정 

FBprophet 라이브러리는 학습을 위해서 

  1. 시간(Timeline)
  2. 예측값

데이터를 필요로 합니다.

따라서 아래와 같이 Date 칼럼과 오늘의 예측값인 AveragePrice를 준비해 줍니다.



  • region을 grouping하여 해당 그룹들을 기준으로 Data에 따른 AveragePrice를 가지고 옴
  • 여기선 TotalUS(즉 모든 그룹들)의 자료를 가지고 옴

결과 해석 


  • 모델을 불러온 후 위에서 처리한 data_price를 파라미터로 줌
  • make_future_dataframe를 통해 기간 설정하며 predict를 통해 예측 진행 - periods=365는 향후 365일을 예측하겠다는 뜻


  • 위 그래프를 통해 가격에 대한 향휴 365일의 예측값을 확인할 수 있음. 
  • 중간 그래프를 통해 큰 틀에서의 트랜드를, 아래 그래프를 통해 최근 1년동안의 트랜드를 파악할수 있음 


머신러닝에서 말하는 Batch의 정의

  • 모델을 학습할 때 한 Iteration당(반복 1회당) 사용되는 example의 set 모임
  • 여기서 iteration은 정해진 batch size를 이용하여 학습(forward - backward)를 반복하는 횟수를 말한다
  • 한 번의 epoch를 위해 여러번의 iteration이 필요하다 
  • training error와 validation error가 동일하게 감소하다가 validation error가 증가하기 시작하는 직전 점의 epoch를 선택해야 함 (이는 overfitting을 방지하기 위함이다)

Batch size의 정의 및 Batch Size를 선택하는 방법
  • Batch 하나에 포함되는 example set의 갯수
  • Batch / Mini-Batch /Stochastic  세 가지로 나눌 수 있다.(아래 그림 참고)


  • SGD(Stochastic Gradient Descent) 은 배치 크기가 1, Mini-Batch는 10~1,000 사이지만 보통 2의 지수승 (32 64 128..)으로 구성

Batch별 특징 및 장단점
Batch
  • 여러 개 샘플들이 한거번에 영향을 주어 합의된 방향으로 smooth하게 수렴, 그러나 샘플 갯수를 전부 계산해야 하므로 시간이 많이 소요된다(한 step을 처리하는데 많은 수의 데이터를 계산해야 한다). 즉 모든 Training data set 사용함.
Stochastic Gradient Descent
  • 데이터를 한 개씩 추출해서(한 개 씩 뽑아서) 처리해보고 이를 모든 데이터에 반복하는 것. 오차율이 크다(수렴 속도는 빠르지만 global minimum을 찾지 못할 가능성이 있다 - 위 그림 참고) . 또한 하나씩 처리하기 때문에 GPU 성능을 제대로 활용하지 못하기 때문에 비효율적이다.
Mini-Batch
  • 전체 학습 데이터를 배치 사이즈로 등분하여(나눠) 각 배치 셋을 순차적으로 수행, 배치보다 빠르고 SGD보다 낮은 오차율 
정리
  • Mini-Batch의 사이즈가 전체 Training data 사이즈와 같으면 Batch Gradient Descent, Mini-Batch의 사이즈가 1이면 Stochastic Gradient Descent)
  • 실제로는 Batch Gradient를 잘 쓸 수 없다. 왜나하면 메모리에 모든 데이터를 한번에 올릴수 없기 때문이다.

Python 코드 예시 


  • Training data set이 5528이라고 가정 


  • 학습 셋이 5528개인데 샘플 코드에서는 Batch Size를 32로 설정
  • 즉 epoch가 173번 돌게 된다(5528/32 = 172.75 --> 반올림해서 173)
  • 마지막 epoch을 돌리지 않으면 172*32 = 5504 --> 24개가 버려짐(배치32로 포함 안되니깐)
  • 이를 방지하기 위해 math.ceil을 이용해 반올림 (172.75 반올림하면 173)하게 되면 모든 데이터 처리 가능(32개씩 172번, 마지막 epoch는 24개) 



Voting Classifiers


Voting Classifiers는 "다수결 분류"를 뜻하는 것으로, 두 가지 방법으로 분류할 수 있습니다.


1. Hard Voting Classifier

여러 모델을 생성하고 그 성과(결과)를 비교합니다. 이 때 classifier의 결과들을 집계하여 가장 많은 표를 얻는 클래스를 

최종 예측값으로 정하는 것을 Hard Voting Classifier라고 합니다.



위와 같이 최종 결과를 1로 예측한 모델이 3개, 2로 예측한 모델이 한 개이므로 Hard Voting Classifier의 최종 결과(예측)은 1이 됩니다.


2. Soft Voting Classifier

앙상블에 사용되는 모든 분류기가 클래스의 확률을 예측할 수 있을 때 사용합니다.

각 분류기의 예측을 평균 내어 확률이 가장 높은 클래스로 예측하게 됩니다 (가중치 투표)



위와 같이 예측 확률에 대한 평균이 높게 나오는 클래스를 최종 예측 클래스로 정하게 됩니다. 


3. 사이킷 런 Sklearn을 통한 구현 

해당 데이터는 캐글의 타이타닉 데이터를 이용하였습니다.

*전체 코드 확인 및 copy가 필요하신 분들은 제 커널 페이지에 가시면 됩니다.


1
2
3
4
5
from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import GridSearchCV, StratifiedKFold
 
# Cross validate model with Kfold stratified cross val
k_fold = KFold(n_splits=10, shuffle=True, random_state=0)
cs

검증엔 10 fold cross validation을 사용합니다. 


오늘 만들 Voting Classifier는 총 네 가지 모델을 사용합니다.

1. Random Forest Classifier

2. Gradient Boosting Classifier

3. XGBoost Classifier

4. Support Vector Machine(SVC) 


Random Forest Classifier에 대한 Grid Search 및 모델 학습, 예측 진행 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
RFC = RandomForestClassifier()
 
 
## Search grid for optimal parameters
rf_param_grid = {"max_depth": [None],
              "max_features": [388],
              "min_samples_split": [238],
              "min_samples_leaf": [138],
              "bootstrap": [False],
              "n_estimators" :[100,300],
              "criterion": ["gini"]}
 
 
gsRFC = GridSearchCV(RFC, rf_param_grid, cv=k_fold, scoring="accuracy",  verbose = 1)
#print(score)
 
gsRFC.fit(train_data,target)
 
RFC_best = gsRFC.best_estimator_
 
# Best score
gsRFC.best_score_
cs


OUT:



Gradient Boosting Classifier에 대한 Grid Search 및 모델 학습, 예측 진행 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GBC = GradientBoostingClassifier()
gb_param_grid = {'loss' : ["deviance"],
              'n_estimators' : [100,200,300],
              'learning_rate': [0.10.050.01],
              'max_depth': [48],
              'min_samples_leaf': [100,150],
              'max_features': [0.30.1
              }
 
gsGBC = GridSearchCV(GBC,param_grid = gb_param_grid, cv=k_fold, scoring="accuracy", n_jobs= 4, verbose = 1)
 
gsGBC.fit(train_data,target)
 
GBC_best = gsGBC.best_estimator_
 
# Best score
gsGBC.best_score_
cs


OUT:



Support Vector Classifier에 대한 Grid Search 및 모델 학습, 예측 진행 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
### SVC classifier
SVMC = SVC(probability=True)
svc_param_grid = {'kernel': ['rbf'], 
                  'gamma': [ 0.0010.010.11],
                  'C': [11050100,200,3001000]}
 
gsSVMC = GridSearchCV(SVMC,param_grid = svc_param_grid, cv=k_fold, scoring="accuracy", n_jobs= 4, verbose = 1)
 
gsSVMC.fit(train_data,target)
 
SVMC_best = gsSVMC.best_estimator_
 
# Best score
gsSVMC.best_score_
cs


OUT:



XGBoost Classifier에 대한 Grid Search 및 모델 학습, 예측 진행 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
XGBC = XGBClassifier()
xgb_param_grid = {'max_depth':[3,5,7],
                  'min_child_weight':[3,5,6],
                  'gamma': [ 00.0010.010.11],
                  'learning_rate':[0.10.050.01]}
 
gsXGBC = GridSearchCV(XGBC,param_grid = xgb_param_grid, cv=k_fold, scoring="accuracy", n_jobs= 4, verbose = 1)
 
gsXGBC.fit(train_data,target)
 
XGBC_best = gsXGBC.best_estimator_
 
# Best score
gsXGBC.best_score_
 
cs


OUT:



Voting Classifier를 통한 최종 클래스 결정 


1
2
3
4
5
6
7
8
9
#Voting Classifier - voting 파라미터로 hard/soft 선택가능
votingC = VotingClassifier(estimators=[('rfc', RFC_best), 
('svc', SVMC_best),('gbc',GBC_best), ('xgb', XGBC_best)], voting='hard', n_jobs=4)
 
votingC = votingC.fit(train_data, target)
 
#예측 진행
prediction = votingC.predict(test_data) 
 
cs


Prediction으로 최종 예측값을 받아옵니다.


CSV파일 저장 및 확인


1
2
3
4
5
#케글에 제출할 csv파일 저장
submission = pd.DataFrame({
        "PassengerId": test["PassengerId"],
        "Survived": prediction
    })
cs



해당 대회는 캐글의 워싱턴 공공 자전거 데이터를 바탕으로 수요를 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/bike-sharing-demand


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다 


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling


















해당 대회는 캐글의 워싱턴 공공 자전거 데이터를 바탕으로 수요를 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/bike-sharing-demand


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다 


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling














해당 대회는 캐글의 워싱턴 공공 자전거 데이터를 바탕으로 수요를 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/bike-sharing-demand


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다 


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling








''' 생략 '''


''' 생략 '''





해당 대회는 캐글의 워싱턴 공공 자전거 데이터를 바탕으로 수요를 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/bike-sharing-demand


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다 


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling







.


순서 

- ANN 개념 / 퍼셉트론 / 활성화 함수 / 역전파 - (1)

- 텐서플로우를 활용한 MLP / DNN 구현 - (2)


인공지능 수업시간에 발표했던 PPT




순서 

- ANN 개념 / 퍼셉트론 / 활성화 함수 / 역전파 - (1)

- 텐서플로우를 활용한 MLP / DNN 구현 - (2)


인공지능 수업시간에 발표했던 PPT


해당 데이터는 1990년 캘리포니아 주택 가격 데이터입니다.

Hands-on Machine Learning Chapter 2를 참고하였습니다.


*전체 코드 확인 및 copy가 필요하신 분들은 제 커널 페이지에 가시면 됩니다


전체적인 데이터 정보는 위와 같습니다



우선 P-value부터 확인해 보겠습니다.

필요한 라이브러리 및 모듈을 임포트 해줍니다.

features에는 housing data에 있는 칼럼명들을 + 구분자로 저장합니다.



위와 같이 result 변수에 해당 값을 저장한 후, print해 줍니다.





위 설명에 나와있는 것처럼, multicollinearity가 의심된다고 합니다.

P-value가 0.5가 넘을 경우, 다중공산성을 의심해봐야 하기때문에 total_bedrooms 칼럼을 드랍하였습니다.



VIF를 확인해 보겠습니다. 과정은 위와 흡사합니다.




VIF값이 10이 넘을 경우 다중공산성을 의심해볼 필요가 있습니다.

다만 무조건적으로 feature를 drop하는 것이 아닌, drop 전 후 RMSE값의 변화를 체크해보셔야 합니다.





해당 대회는 캐글의 Iowa 부동산 데이터를 바탕으로 집값을 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/house-prices-advanced-regression-techniques


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling


*Grid search를 통한 hyper parameter 찾는 방법은 추후 포스팅에서 자세히 진행하도록 하겠습니다

** Gradient Boosting Regression, XGBoost, LightGBM 을 사용하였습니다.







해당 대회는 캐글의 Iowa 부동산 데이터를 바탕으로 집값을 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/house-prices-advanced-regression-techniques


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling







해당 대회는 캐글의 Iowa 부동산 데이터를 바탕으로 집값을 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/house-prices-advanced-regression-techniques


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling




















해당 대회는 캐글의 Iowa 부동산 데이터를 바탕으로 집값을 예측하는 모델을 만든 것입니다

대회 링크: https://www.kaggle.com/c/house-prices-advanced-regression-techniques


*코드 복붙이 필요하신 분들은 제 커널 페이지에 가시면 됩니다


순서는 아래와 같습니다.


Step 1.

Data Explore


Step 2. 

Feature Engineering


Step 3. 

Modeling






K-means Clustering에 대한 설명은 위 영상을 참고하면 된다.

간단히 설명하면 K개의 센트로이드를 기준으로 클러스터링을 진행하여 K개의 집단을 만든다는 것이다.

Clustering은 비지도 학습중 하나로 데이터에 대한 라벨링이 없을 때  대략적인 패턴 및 클래스를 파악하기 위하여 진행한다. 

(만약 라벨링이 되어 있으면 SVM등의 classification을 사용한다)


오늘도 사이키 런 라이브러리를 사용한다.

데이터를 임의로 부여한다



이차원 공간에 시각화한 결과 그래프



클러스터링을 진행한다.

kmeans.labels_ 는 각 데이터가 어떤 클러스터에 속하는지 그 결과를 표현한다

이를 cluster_id라는 칼럼에 표시하여 추가해준다.


결과물을 시각화한 결과.



Reference:

https://www.youtube.com/channel/UCxP77kNgVfiiG6CXZ5WMuAQ

지금까지 데이터 전처리를 진행하였다.


이제 K-fold cross validation을 써서 가장 좋은 정확도를 보이는 모델을 찾고, 


해당 모델로 test set의 survived를 예측해 보겠다.



사이키 런 라이브러리를 통해 구현한다

교차검증 코드는 다음과 같다.

K-fold cross validation에 대한 설명은 이곳에.



kNN 구현 코드는 다음과 같다. 

교차검증 결과 평균 정확도 82.6



의사결정나무 구현 코드는 다음과 같다

교차검증 결과 평균 정확도 79.58


랜덤포레스트 구현 코드는 다음과 같다

교차검증 결과 평균 정확도 80.81


나이브베이즈 구현 코드는 다음과 같다

교차검증 결과 평균 정확도 78.78


SVM 구현 코드는 다음과 같다

교차검증 결과 평균 정확도 83.5


*즉 SVM이 제일 정확도가 높기 때문에, Test Set을 SVM으로 예측한다.




Test set을 SVM으로 예측하고, 해당 결과물을 다시 csv로 저장한다 (to_csv 명령어)

SVM에 대한 설명은 여기 참고.

해당 결과물을 캐글에 제출하면 모델의 정확도를 측정해 주는데, 오늘 우리가 만든 모델의 정확도는..


'




정확도는 0.789고 이는 전체 제출 모델의 상위 31퍼.에 해당하는 성적이다.



Reference:

https://www.youtube.com/channel/UCxP77kNgVfiiG6CXZ5WMuAQ

http://scikit-learn.org/stable/index.html


*코드 복붙이 필요하신분은 제 캐글 커널페이지에서 하실 수 있습니다.



지난 포스팅에 이어서 전처리를 마무리해 보겠다.


Embarked 칼럼부터 시작한다.







Cabin에 대해서 좀 더 보충해서 설명하자면, Cabin은 객실을 뜻하는 것인데 알파뱃과 숫자의 조합으로 이루어진다.

여기서 숫자까지 분류를 하기에는 조금 무리가 있기 때문에, 우리는 제일 앞에 있는 알파벳만 추출하여 연관성을 보기 위해

시각화를 진행한 것이다.




기존에 SibSP 랑 Parch 두 개로 나누어져있던 칼럼을 Familysize 하나로 합친다

그리고 해당 두 칼럼을 drop한다.


이제 전처리를 마무리하였고, 모델 학습을 진행해 보겠다.


*코드 복붙이 필요하신분은 제 캐글 커널페이지에서 하실 수 있습니다.



저번 포스팅에 이어 데이터 전처리를 진행해보도록 하겠다.

본문에도 써놨지만 이렇게 전처리를 하는 가장 큰 이유들은


1. 머신러닝 알고리즘은 텍스트를 읽을수 없는 경우가 많음

2. Scale이 클경우 제대로 된 모델 학습이 힘듬


이 두 가지로 요약할 수 있다.


사진을 클릭하면 더 큰 원본 사이즈로 볼 수 있다.

아래 데이터들과 코드를 함께 보자.




화면에 첨부한 웹사이트 주소는 https://regexr.com/ 이며, 해당 홈페이지에서 정규표현식의 시각화를 해주니

쉽게 이해할 수 있다.



Name에 대한 전처리를 끝냈다. 이제 성별로 넘어가보자.



성별도 매핑작업을 해준다



Age는 Nan값을 해당 그룹이 속하는 Median값으로 대체해준다. 

중앙부분 코드 참고 


Age를 Binning하는 코드이다. 설명은 중앙에 있으며 그냥 C언어나 Java시간에 한 점수대별 학점 부여하는

Switch문이나 if else문 생각하면 편하다.



bar chart를 그리면 다음과 같으며, 마지막 그룹에 속하는 사람들은 거의 생존하지 못한 상황을 보여주고 있다.


다음 포스팅에 이어서 전처리를 마무리 하겠다


*코드 복붙이 필요하신분은 제 캐글 커널페이지에서 하실 수 있습니다.



머신러닝을 공부한다면 한번쯤은 들어봤을만한 케글. 

케글에서는 튜토리얼용 대회로 타이타닉 생존자 예측 모형 만드는 대회를 제공하고 있다.


데이터 셋만 보면 만만해 보이지만 의외로 까다로워 적당한 난이도지만, 

유명하기 때문에 이미 100퍼에 가까운 정확도를 가진 모형들의 커널이 공개되어 있기 떄문에,

그만큼 보면서 공부하기 좋다고 생각한다. 


사진을 클릭하면 더 큰 원본 사이즈로 볼 수 있다.



이번 포스팅에서는 데이터 탐색 및 전처리에 대해 다루어보도록 하겠다.

판다스 라이브러리를 이용해 csv를 불러오고, 확인한다



참고로 Data Dictionary는 이렇다.






이제 데이터 시각화를 진행하여 데이터 셋에 대해 대략적인 이해를 해보겠다.





다음 포스팅에서 데이터 전처리를 이어서 해보도록 하겠다.


*코드 복붙이 필요하신분은 제 캐글 커널페이지에서 하실 수 있습니다.








순서 - 선형 SVM / 비선형 SVM / (1)

비선형SVM / 커널트릭 / SVR (2)

인공지능 수업시간에 발표했던 PPT.

서포트 백터들과 하이퍼 플래인의 마진 계산 관련 공식은 중간에 텍스트로만 이루어진 슬라이드를 참고하면 된다.




순서 - 선형 SVM / 비선형 SVM / (1)

비선형SVM / 커널트릭 / SVR (2)

인공지능 수업시간에 발표했던 PPT.

서포트 백터들과 하이퍼 플래인의 마진 계산 관련 공식은 중간에 텍스트로만 이루어진 슬라이드를 참고하면 된다.



정의

- 데이터의 편향 방지 + 편향된(잘못된) 모델 생성 방지

- 모집단의 특정 변수 비율에 맞추어 모집단을 쪼개어 해당 비율만큼 가지고 오는것(표본추출) = 비율을 맞춰줌 

- 층 내는 동질하게, 층끼리는 이질적이게 

- 전체 모집단 및 층별 특성도 효과적으로 추정가능 

- 데이터 셋의 특성 분포를 고르게 해준다 




구현

- 파이선 sklearn 모델을 통한 구현 

- StratifiedshuffleSplit 함수 이용 


이번 포스팅에선 비트파이넥스 API를 활용하여 비트코인 가격데이터를 요청해보겠다.

좀 더 자세한 설명은 코인베이스 API 사용 포스팅에 나와있으니 참고해도 좋다.


우선 비트파이넥스 API관련 링크에 접속한다

https://bitfinex.readme.io/v2/reference#rest-public-stats


왼쪽 candle을 눌러주면 아래와 같은 화면이 보인다.



우선 URL 방식중 GET과 POST방식에 대해서 간단히 설명하겠다.


GET(파란원)은 따로 암호화를 하지 않은 URL방식으로 URL을 보면 직관적으로 그 내용을 알 수 있다. 예시에 나와있는 링크를 봐도 어느정도 직관적으로 이해가 가능하다.


POST는 암호화를 거친 URL로 이상한 특수문자 알파벳 조합으로 이루어지기 떄문에 직관적으로 알 수 없다. 

우리는 GET방식의 URL을 통해 데이터를 요청해 보겠다.


친절하게 파라미터에 대한 예시까지 들어주었으므로, 바로 URL에 적용시켜 보겠다.

예시 URL(GET방식)은 아래와 같다.


https://api.bitfinex.com/v2/candles/trade:6h:tBTCUSD/hist?limit=100&start=&end=&sort=1


라인별로 간단하게 보면 6시간봉으로 이루어진 BTCUSD마켓 데이터를 hist 방식으로(사진 빨간원 참조) 정렬된 상태로 100개 요청하는 것이다.


이제 코드패드로 이동해 보겠다.

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
import requests
from datetime import datetime
import time
 
def unixtime(t): #우리가 쓰는 시간을 유닉스타임으로 바꿈 
    temp = t.split('-')
    return int(time.mktime(datetime(int(temp[0]), int(temp[1]), int(temp[2])).timetuple()))
'''
def unixtime_to_datetime(arr, interval, symbol): #우리가 쓰는 시간을 유닉스타임으로 바꿈 
    temp = t.split('-')
    return int(time.mktime(datetime(int(temp[0]), int(temp[1]), int(temp[2])).timetuple()))    
'''
timeframe = '6h'
symbol = 'tBTCUSD'
section = 'hist'
limit = 100
end = "2018-03-01"
start = "2018-02-25"
sort = 1 
 
= (requests.get("https://api.bitfinex.com/v2/candles/trade:%s:%s/%s?limit=%d&start=%d&end=%d&sort=%d" %(timeframe, symbol, section, limit, unixtime(start)*1000, unixtime(end)*1000, sort)))
 
data = r.json()
print(data)
    
cs


해당 코드를 실행하면 아래와 같다.



이런식으로 데이터를 받아올 수 있다.

이후 csv저장 등 필요한 작업을 진행하면 된다.

LSTM은 RNN에서 파생된 것으로, 순차적인 입력 데이터간 간격이 커도 좋은 성과를 보여주는 것을 특징으로 한다.

이는 RNN이 가지는 Long-term dependency 문제점을 LSTM은 가지고 있지 않기 떄문이다. 해당 문제점은 예측에 필요한 정보와 정보간 간격이 클때 그 예측 능력이 현저하게 감소하는 것을 뜻한다. 

보편적으로, 대부분의 경우에 LSTM은 RNN보다 좋은 퍼포먼스를 보여주는 경향을 가진다.


다만 RNN역시 신경망의 한 종류이기 때문에, 그 과정에 있어서 설명력이 떨어진다는 단점을 가진다.

하지만 우리는 어떤 순서에 의하여 가격 예측을 하는지 그 과정이 필요한 것은 아니기 때문에, LSTM을 선택하기로 하였다.


LSTM의 자세한 수학적 원리는 웹의 여러 매체에 소개되어 있으며, 해당 포스팅에서는 간단하게 작동 원리만

설명하면 아래와 같다.



첫번째 인픗으로 일차 예측을 진행하고, 그 다음 인풋과 기존 인풋을 바탕으로 한 예측값을 조합하여 다시 재예측을 진행한다.

이런식으로 n번째 인풋값 전 n-1번까지의 인풋값을 통해 낸 예측결과는 n번째 인풋을 활용한 예측값에 영향을 주는 것이다.


해당 과정을 계속해서 진행하여 최종 아웃풋을 산출한다.


*딥러닝 부분을 구현하는 것에 있어서 어려움이 있었기 때문에, 도움을 받았음을 알려드립니다.



우리는 예측 모델을 통해 raio(상승/하락 비율)을 예측했고, 그 예측 결과인 비율에 해당 시간의 close(종가)를 곱해주게 되면 예측 가격이 나오게 된다.

칼럼에 대해 설명하자면 2015-03-13 15:00을 기준으로 6시간 뒤는 2015년 3월 13일 21:00, 그 뒤는 14일 03:00 .. 이 되는 것이다.

따라서 칼럼에서 실제 24시간 뒤가 다음 칼럼에서 여섯시간 뒤와 동일한 것을 발견할 수 있다.


따라서 우리는 각 시간대별로 6시간, 12시간, 18시간, 24시간 예측값에 대한 오차율을 구할 수 있으며, 오차율의 절대값 평균은 아래와 같다.


즉 시간이 지날수록 오차율이 높아지는 것을 발견할 수 있다.

사실 일반적인 에측에서 정확도 98퍼센트면 매우 높다고 생각할수도 있으나 트레이딩의 특성상

1퍼센트~2퍼센트의 차이가 큰 돈의 이익과 손실을 불러올 수 있다는 점에서 부족할 수 있다는 생각 역시 든다.


 

특히나 급격한 하락장(패닉셀 등)이 발생할때는 예측치가 크게 어긋나는 모습을 보였는데, 물론 평균치로 보면 크게 문제가 없지만

순간 순간의 오차율이 큰 손실을 불러올 수 있다는 점에서 보완이 필요하다는 생각이 들었다.


 

전처리는 거의 다 끝났고, 이제 학습 데이터와 테스트 데이터로 나눠보도록 하겠다.

비율은 보통 자율적으로 선택하지만 보편적으로 0.7~0.75사이로 학습데이터를, 그 나머지를 테스트 데이터로 부여하게 된다.


코드는 아래와 같다.


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
31
32
33
import numpy as np
import math
import csv
##train set : 3125개 , test: 1041개
= open("./20개씩묶고_컬럼별정규화.csv"'r', newline='')
rdr = csv.reader(f)
 
data = []
for j, i in enumerate(rdr):
    if(j!=0): #label 제외하고 읽어옴.
        data.append(i)
np.random.shuffle(data)
 
ratio = 0.75
count = int(math.ceil(len(data)*ratio))
print(len(data), count)
train = data[:count]
test = data[count:]
 
o1 = open("./trainset.csv"'w', newline='')
wr1 = csv.writer(o1)
for i in train:
    wr1.writerow(i)
 
o2 = open("./testset.csv"'w', newline='')
wr2 = csv.writer(o2)
for i in test:
    wr2.writerow(i)
 
f.close()
o1.close()
o2.close()
'''
cs


해당 코드를 실행시 4163개의 Train data, 3123개의 Test data로 나눠진 것을 확인할 수 있다.




저번 포스팅에 이어서 전처리 작업을 해보겠다.

이번 포스팅해서 진행할 것은 첫번째로 20개를 그램으로 묶으며, 데이터를 정규화할 것이다.

우선 그램에 대해서 간단하게 설명하면 아래와 같다.


input data   /  target(예측)

   b    c          d

b    c    d          e

c    d    e          f


이런식으로 일부분은 중복되지만 완전히 중복되지 않는 인풋데이터를 확보하여 예측값을 구하는 것으로

이번의 경우에는 데이터가 충분하지 않기 때문에 사용하게 된 방법이다.

R실습에서 진행하였던 디시전 트리의 앙상블과 비슷한 개념이라고 할 수 있다.


그램에 대한 코드는 아래와 같다


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
31
import csv
import numpy as np
from sklearn.preprocessing import MinMaxScaler
import warnings
warnings.filterwarnings("ignore")
 
########20gram으로 분류############
= open("./타겟추가데이터2_새로운방식.csv"'r', newline='')
rdr = csv.reader(f)
 
list = []
for i in rdr:
    list.append(i)
list.pop(0#제목줄 지우기
print(len(list))
 
gram_20 = []
for i in range(len(list)+1-20):
    gram_20.append(list[i:i+20])  
gram_20 = np.array(gram_20)
#print(gram_20)
#print(gram_20.shape)
print(gram_20[0].shape)  ## 20개씩 묶어서 진행 - 4163 번 진행 20행 21열 (스샷참고) = 5일  
###########################

o.close()
f.close()
cs


20개씩 묶은 이유는 한 행에 5일치에 속하는 데이터들을 묶기 위함이며(하루에 4bars * 5 일 = 20bars)

해당 그램을 사용해야 뜨는 타임라인이 없이 6시간봉마다 예측을 진행할 수 있다. (우리는 마감시 기준 6, 12, 18, 24시간 뒤 가격을 예측할 것이다)



해당 코드부분만 실행해보면 20행 21열이며 4163번 진행하였음을 알 수 있다. 


이제 칼럼별로 정규화를 진행하겠다.

참고로 우리가 예측할 것은 순수한 가격이 아닌 ratio 즉 가격의 변화율을 예측할 것이며, 이를 close와 곱하여 가격을 유추해낼 것이다.


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
#######노말라이제이션############
= open("./20개씩묶고_컬럼별정규화.csv"'w', newline='')
wr = csv.writer(o)
title = ['time','low''high','open','close','volume','sma5','sma20','ema12','ema26','dn','mavg','up','pctB','rsi14','macd','signal']*20 #20일치
title.append("lastday_close")
title.append('after6ratio')
title.append('after12ratio')
title.append('after18ratio')
title.append('after24ratio')
wr.writerow(title)
 
scaler = MinMaxScaler(feature_range=(0,1)) #scaler 선언
for i in gram_20:
    close = np.array(i[-1][4], np.float64) # -1은 마지막 인덱스를 뜻함 여기서는 19 
    target = np.array(i[-1][-4:], np.float64) # 뒤에서부터 네 개 값 계산해서 타겟으로 넣음 
    ratio = target/close
    
    for j in range(1, i.shape[1]-4): #날짜다음부터 체크해서 타겟4개 제외. / 현재 종가부터 
        col = scaler.fit_transform(np.reshape(i[:,j], (-11)))
        col = np.transpose(col) # 이걸 다시 열로  바꿔서 그대로 붙임 
        i[:,j] = col # 붙임 
    
    #break
    data = i[:, :-4# 타임까지 포함해서 타겟 열 전까지 가지고와서 (ratio 다 떄고 그래서 20 행 17 열 )
    data = np.reshape(data, (-1)) #각 행을 짤라서 하나의 긴 행으로 바꿈 - 1차원 배열로 알아서 펴줌 즉 한게의 긴 행 상태로 바꿈    =  20 * 17 = 340 
    data = np.append(data,close)  # close 1열 추가 
    data = np.append(data,ratio) #  나중에 close 와 ratio 를 곱해가지고 실제 예측 가격 파악가능  - ratio 4개 추가  - 총 345 열 
    
    wr.writerow(data) 
cs


코드를 라이별로 간단하게 설명하면 close는 그램으로 묶은 20행중 마지막 행의 close를 담게 된다.

또한 target은 동일한 행의 마지막 4개 열(after 6 ratio ~ after 24 ratio)


그 후 각 데이터들에 대한 정규화를 진행하게 되며(타겟은 제외하고) 

한 개의 그램에 20행 21열로 구성이 되어 있는것을, 마지막 4개 열을 제외하고 하나의 행으로 길게 늘어뜨리게 된다.

해당 과정을 진행하면 20*17(20행*17열을 한개의 행에 길게 늘어뜨림) 340행이 나오게 되며, 해당 과정이 끝나면

close와 ratio(close -1열 + ratio - 4열 = 총 5열 추가) 한 행당 345개의 열을 가지게 된다.


두번째 포문에 대한 설명을 조금 더 하자면 

i = 

1 2 3 4 5 6 7 

2 3 4 5 6 7 8 

3 4 5 6 7 8 9 

일 때,


i [ : , : -4] 면  

1 2 3 

2 3 4 

3 4 5 


와 같이 선택하는 것이다.

즉 뒤에 4개를 빼고 묶는다고 생각하면 된다.


해당 csv 파일을 열어보면 한 행이 345개의 열로 구성되어 있는것을 확인할 수 있다.



+ Recent posts