Heroku App 배포

개요

Procfile 생성

  • 프로젝트 Root 디렉터리에 Procfile 을 생성한다.
web: gunicorn index:server
  • 이 때, index 파일명을 의미한다.

작업 파일 수정

  • index.py을 열고, 다음 코드를 추가한다.
    • server = app.server 을 추가한다.
app = dash.Dash(__name__, meta_tags=[{"name": "viewport",
                                      "content": "width=device-width"}])

server = app.server

Runtime 파일 추가

  • 어떤 파이썬 버전에서 실행할 것인지 해당 코드를 작성한다. (runtime.txt)
    • 마찬가지로 프로젝트의 Root 디렉토리에서 생성한다.
python-3.8.7

Heroku 로그인 및 App 생성

  • Heroku 회원가입을 안했다면, 진행한다.

Python Sales Dashboard Using Dash and Plotly

개요

  • Sales 데이터를 활용하여 대시보드를 만드는 과정을 제작한다.
  • 기본 파이썬 코딩은 할 줄 안다는 전제하에 작성하며, 세부 내용이 필요하면 참고 자료를 확인할 것을 권한다.
  • 윈도우 10에서 본 프로젝트를 수행하였다.

Chapter 1. Github Repo 생성

  • 필자는 Github 레포를 만들었다. (Repo 명: python_dash_sales)
  • git clone을 통해서 로컬로 가져온다.
$ git clone https://github.com/your_id/python_dash_sales.git

Chapter 2. Python 프로젝트 생성

  • PyCharm을 주 에디터로 사용할 예정이다.

BigQuery ML을 사용한 펭귄 체중 예측

개요

  • BigQuery ML을 소개한다.
  • BigQuery ML을 사용하면, 머신러닝 모델을 만들고 또한 실행할 수 있다.

목표

  • BigQuery ML에서 CREATE MODEL 문을 사용하여 선형회귀 모델 만들기
  • ML.EVALUATE 함수를 사용하여 ML 모델 평가
  • ML.PREDICT 함수를 사용하여 ML 모델 예측

주의 사항

1단계: 데이터 세트 만들기

  • 데이터 세트 ID에 bqml_practice 입력
  • 데이터 위치로 미국 US 선택
  • 나머지는 모두 Default로 설정한다.

Untitled

2단계: 모델 만들기

데이터 소개

  • 먼저 데이터를 소개한다.
  • 데이터 원 자료는 해당 논문에서 확인할 수 있다.
  • 데이터 셋에 대한 설명은 다음과 같다.
    • species — 펭귄의 종(문자열)
    • island — 펭귄이 사는 섬(문자열)
    • culmen_length_mm — 컬멘 길이(밀리미터)(FLOAT64).
    • culmen_depth_mm — 컬멘 깊이(밀리미터)(FLOAT64)
    • flipper_length_mm — 지느러미의 길이(밀리미터)(FLOAT64)
    • sex — 펭귄의 성별(문자열)

모델 만들기 코드 실행

  • CREATE MODEL 명령어를 실행하여 모델을 생성한다.
#standardSQL
CREATE OR REPLACE MODEL `bqml_practice.penguins_model`
OPTIONS
  (model_type='linear_reg',
  input_label_cols=['body_mass_g']) AS
SELECT
  *
FROM
  `bigquery-public-data.ml_datasets.penguins`
WHERE
  body_mass_g IS NOT NULL
  • 실행 결과는 보는 것처럼 Preprocess, Train, Evaluate 작업이 진행 된 것을 확인할 수 있다.

Untitled

GCP Settings 2022 ver

개요

  • GCP 빅쿼리를 연동하는 예제를 구현한다.
  • 먼저 빅쿼리를 통해 데이터를 적재하는 예제를 확인한다.
  • 구글 코랩에서 빅쿼리 데이터를 불러온다.
  • 데이터 스튜디오에서 빅쿼리 데이터를 불러온다.

소개

Google Cloud 회원가입

  • 준비물
    • Google 계정
    • 신용카드나 체크카드 (개인적으로 돈이 없는 체크카드 사용 권장)
  • 구글 클라우드 사이트 접속
  • 무료 서버 받으려면 아래 화면에서 TRY IT FREE 를 클릭한다.

Untitled

Spark Installation on M1 Mac

사전준비

  • M1 Mac에서 스파크를 설치하는 과정을 소개 하려고 한다.
  • 필자의 Python 버전은 아래와 같다.
$ python --version
Python 3.8.7

자바 설치

Screen Shot 2022-01-05 at 12.57.39 AM.png

  • 그 다음 자바 설치를 확정한다.
$ java --showversion
  • 만약 에러가 아래와 같은 에러가 발생한다면, 시스템 환경설정 - Java - 업데이트 항목을 순차적으로 클릭한다.
$ java --showversion
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Screen Shot 2022-01-05 at 12.20.33 AM.png

Spark Installation on Windows 10

사전준비

  • 스파크를 설치하는 과정은 소개 하려고 한다.
  • 사전에 파이썬 3만 설치가 되어 있으면 된다.
  • 만약, 파이썬이 처음이라면 Anaconda를 설치한다.

다운로드 전 필수 확인사항

  • 스파크 설치 전에는 반드시 체크해야 하는 사항이 있다. (System Compatibility)
  • 2022년 1월 기준은 아래와 같다.

Get Spark from the downloads page of the project website. This documentation is for Spark version 3.2.0. Spark uses Hadoop’s client libraries for HDFS and YARN. Downloads are pre-packaged for a handful of popular Hadoop versions. Users can also download a “Hadoop free” binary and run Spark with any Hadoop version by augmenting Spark’s classpath. Scala and Java users can include Spark in their projects using its Maven coordinates and Python users can install Spark from PyPI.

PyCaret Installation on M1 Mac

PyCaret Installation on M1 Mac

개요

  • M1 Mac에서 PyCaret을 설치하고 싶었다.
  • PyCaretAutoML 라이브러리이며, 단 몇줄의 코드로 복잡한 기계학습을 학습 및 비교할 수 있도록 구현한 코드라고 볼 수 있다.
  • M1 Mac에서 해당 라이브러리를 사용하려면 크게 2가지 필수 전제 조건이 있다.
    • LightGBM, XGboost 설치

1. PyCaret 설치 방법

  • 일반 인텔 기반의 Mac의 설치는 매우 쉽다. (Intel Mac)
$ brew install lightgbm
  • 그러나, M1 Mac에서는 생각보다 쉽지 않다.
    • 물론, Rosetta로 터미널을 바꾸면 Intel Mac 처럼 쓸 수 있다. 그러나, M1의 GPU를 활용하려면 기존 설치 방법으로는 적용이 어렵다.

(1) Step 01. Xcode Command Line Tools

(2) Step 02. miniforge 설치

  • 본 블로그에서 가장 중요하다.
  • 2021년 12월 기준 시점에서는 반드시 설치를 해야 한다.
    • GPU를 사용하기 위해서는 LightGBM, XGBoost, PyCaret은 Conda 기반으로만 설치가 가능하다.
  • 설치 파일 주소: https://github.com/conda-forge/miniforge
    • 설치 시, 아래 그림과 같이 arm64 Apple Silicon을 선택해서 다운로드 받아야 한다.

install_01.png

PyCaret, Skorch Using Pipeline

개요

  • Scikit-Learn의 Pipeline은 강력하다.
  • PyCaret, Skorch에도 사용이 가능하다.
  • Google Colab에서 시도해보자.

필수 라이브러리 설치

  • pycaret을 설치 한 후에는 반드시 런타임 재시작을 클릭한다.
!pip install pycaret
Collecting pycaret
  Downloading pycaret-2.3.5-py3-none-any.whl (288 kB)
.
.
Successfully installed Boruta-0.3 Mako-1.1.6 PyYAML-6.0 alembic-1.4.1 databricks-cli-0.16.2 docker-5.0.3 funcy-1.17 gitdb-4.0.9 gitpython-3.1.24 gunicorn-20.1.0 htmlmin-0.1.12 imagehash-4.2.1 imbalanced-learn-0.7.0 joblib-1.0.1 kmodes-0.11.1 lightgbm-3.3.1 mlflow-1.22.0 mlxtend-0.19.0 multimethod-1.6 pandas-profiling-3.1.0 phik-0.12.0 prometheus-flask-exporter-0.18.7 pyLDAvis-3.2.2 pycaret-2.3.5 pydantic-1.8.2 pynndescent-0.5.5 pyod-0.9.6 python-editor-1.0.4 querystring-parser-1.2.4 requests-2.26.0 scikit-learn-0.23.2 scikit-plot-0.3.7 scipy-1.5.4 smmap-5.0.0 tangled-up-in-unicode-0.1.0 umap-learn-0.5.2 visions-0.7.4 websocket-client-1.2.3
!pip install -U skorch
Requirement already satisfied: skorch in /usr/local/lib/python3.7/dist-packages (0.11.0)
Requirement already satisfied: tabulate>=0.7.7 in /usr/local/lib/python3.7/dist-packages (from skorch) (0.8.9)
Requirement already satisfied: scikit-learn>=0.19.1 in /usr/local/lib/python3.7/dist-packages (from skorch) (0.23.2)
Requirement already satisfied: tqdm>=4.14.0 in /usr/local/lib/python3.7/dist-packages (from skorch) (4.62.3)
Requirement already satisfied: numpy>=1.13.3 in /usr/local/lib/python3.7/dist-packages (from skorch) (1.19.5)
Requirement already satisfied: scipy>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from skorch) (1.5.4)
Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.19.1->skorch) (1.0.1)
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.19.1->skorch) (3.0.0)
from pycaret.datasets import get_data
data = get_data("electrical_grid")
tau1tau2tau3tau4p1p2p3p4g1g2g3g4stabf
02.9590603.0798858.3810259.7807543.763085-0.782604-1.257395-1.7230860.6504560.8595780.8874450.958034unstable
19.3040974.9025243.0475411.3693575.067812-1.940058-1.872742-1.2550120.4134410.8624140.5621390.781760stable
28.9717078.8484283.0464791.2145183.405158-1.207456-1.277210-0.9204920.1630410.7666890.8394440.109853unstable
30.7164157.6696004.4866412.3405633.963791-1.027473-1.938944-0.9973740.4462090.9767440.9293810.362718unstable
43.1341127.6087724.9437599.8575733.525811-1.125531-1.845975-0.5543050.7971100.4554500.6569470.820923unstable

PyTorchModel

  • sktorch 라이브러리는 PyTorch 모델과 함께 작동한다.
  • MLP 모델을 작성하는 클래스를 설계한다.
import torch.nn as nn

class Net(nn.Module): 
  def __init__(self, num_inputs=12, num_units_d1 = 200, num_units_d2 = 100):
    super(Net, self).__init__() 

    self.dense0 = nn.Linear(num_inputs, num_units_d1)
    self.nonlin = nn.ReLU()
    self.dropout = nn.Dropout(0.5)
    self.dense1 = nn.Linear(num_units_d1, num_units_d2)
    self.output = nn.Linear(num_units_d2, 2)
    self.softmax = nn.Softmax(dim=-1)

  def forward(self, X, **kwargs):
    X = self.nonlin(self.dense0(X))
    X = self.dropout(X)
    X = self.nonlin(self.dense1(X))
    X = self.softmax(self.output(X))
    return X

Skorch Classifier

  • NeuralNetClassifier 클래스를 PyTorch 클래스와 연동한다.
  • Optimizer 기본값인 SGD를 사용한다. 만약 다른 Optimizer로 변경을 원하면 다음 링크에서 확인한다.
  • Sktorch 5 폴드 교차검증을 수행한다.
    • 학습 데이터는 80%, 나머지 20%는 검증 데이터로 활용한다.
from skorch import NeuralNetClassifier 

net = NeuralNetClassifier(
    module = Net, 
    max_epochs = 30, 
    lr = 0.1, 
    batch_size = 32, 
    train_split = None
)

PyCaret과 신경망 학습 방법

  • SKORCH NN model을 초기화 했다면, 이번에는 PyCaret과 함께 모델을 학습할 수 있다.
  • PyCaret은 기본적으로 Pandas DataFrame을 메인 객체로 사용하다.
  • 그런데, sktorch model을 사용하기 위해서는 pipeline을 구성할 때는 DataFrameTransformer() 함수를 사용해야 한다.
from skorch.helper import DataFrameTransformer
import numpy as np
from sklearn.pipeline import Pipeline

nn_pipe = Pipeline(
    [("transform", DataFrameTransformer()), 
     ("net", net), ]
)

PyCaret Setup

  • Skorch API 대신 PyCaret 모델을 사용해본다.
  • log_experimentTrue를 사용하게 되면 MLFlow를 사용할 수 있다.
  • silentTrue인 경우 중간에 발생하는 press enter to continue 입력 단계를 피할 수 있다.
from pycaret.classification import *
target = "stabf"
clf1 = setup(data = data, 
            target = target,
            train_size = 0.8,
            fold = 5,
            session_id = 123,
            log_experiment = True, 
            experiment_name = 'electrical_grid_1', 
            silent = True)
DescriptionValue
0session_id123
1Targetstabf
2Target TypeBinary
3Label Encodedstable: 0, unstable: 1
4Original Data(10000, 13)
5Missing ValuesFalse
6Numeric Features12
7Categorical Features0
8Ordinal FeaturesFalse
9High Cardinality FeaturesFalse
10High Cardinality MethodNone
11Transformed Train Set(8000, 12)
12Transformed Test Set(2000, 12)
13Shuffle Train-TestTrue
14Stratify Train-TestFalse
15Fold GeneratorStratifiedKFold
16Fold Number5
17CPU Jobs-1
18Use GPUFalse
19Log ExperimentTrue
20Experiment Nameelectrical_grid_1
21USI9626
22Imputation Typesimple
23Iterative Imputation IterationNone
24Numeric Imputermean
25Iterative Imputation Numeric ModelNone
26Categorical Imputerconstant
27Iterative Imputation Categorical ModelNone
28Unknown Categoricals Handlingleast_frequent
29NormalizeFalse
30Normalize MethodNone
31TransformationFalse
32Transformation MethodNone
33PCAFalse
34PCA MethodNone
35PCA ComponentsNone
36Ignore Low VarianceFalse
37Combine Rare LevelsFalse
38Rare Level ThresholdNone
39Numeric BinningFalse
40Remove OutliersFalse
41Outliers ThresholdNone
42Remove MulticollinearityFalse
43Multicollinearity ThresholdNone
44Remove Perfect CollinearityTrue
45ClusteringFalse
46Clustering IterationNone
47Polynomial FeaturesFalse
48Polynomial DegreeNone
49Trignometry FeaturesFalse
50Polynomial ThresholdNone
51Group FeaturesFalse
52Feature SelectionFalse
53Feature Selection Methodclassic
54Features Selection ThresholdNone
55Feature InteractionFalse
56Feature RatioFalse
57Interaction ThresholdNone
58Fix ImbalanceFalse
59Fix Imbalance MethodSMOTE

PyCaret Train Model

  • Random Forest 모델을 사용해본다.
model = create_model("rf")
AccuracyAUCRecallPrec.F1KappaMCC
00.92440.97960.96670.91890.94220.83310.8353
10.92750.97930.95490.93300.94380.84170.8422
20.92250.98100.96080.92110.94060.82940.8309
30.90810.97380.94610.91300.92930.79830.7993
40.90440.97380.94710.90710.92670.78940.7909
Mean0.91740.97750.95510.91860.93650.81840.8197
SD0.00930.00310.00790.00870.00710.02060.0206

PyCaret Train Skorch Model

  • 이번에는 Skorch Model을 Pycaret 함수에 넣어서 확인해본다.
skorch_model = create_model(nn_pipe)
AccuracyAUCRecallPrec.F1KappaMCC
00.88310.96440.95000.87690.91200.73890.7441
10.85500.94370.95690.83850.89380.66850.6831
20.83690.92800.96380.81460.88290.62020.6446
30.85060.93470.86680.89570.88100.68050.6812
40.80810.94110.97650.77890.86660.54000.5859
Mean0.84680.94240.94280.84090.88730.64960.6678
SD0.02450.01230.03900.04210.01510.06660.0519

Comparing Models

  • 두 모델 중 어떤 모델이 더 좋은지 확인해본다.
best_model = compare_models(include=[skorch_model, model], sort = "AUC")
ModelAccuracyAUCRecallPrec.F1KappaMCCTT (Sec)
1Random Forest Classifier0.91740.97750.95510.91860.93650.81840.81972.114
0NeuralNetClassifier0.84260.94000.95470.82810.88610.63550.656511.878

Hyperparameter Grid

  • Hyperparameter 튜닝을 적용하도록 한다.
  • 모형 튜닝을 위한 parameter 값은 다음 명령어를 통해서 확인할 수 있다.
skorch_model.get_params().keys()
dict_keys(['memory', 'steps', 'verbose', 'transform', 'net', 'transform__float_dtype', 'transform__int_dtype', 'transform__treat_int_as_categorical', 'net__module', 'net__criterion', 'net__optimizer', 'net__lr', 'net__max_epochs', 'net__batch_size', 'net__iterator_train', 'net__iterator_valid', 'net__dataset', 'net__train_split', 'net__callbacks', 'net__predict_nonlinearity', 'net__warm_start', 'net__verbose', 'net__device', 'net___kwargs', 'net__classes', 'net__callbacks__epoch_timer', 'net__callbacks__train_loss', 'net__callbacks__train_loss__name', 'net__callbacks__train_loss__lower_is_better', 'net__callbacks__train_loss__on_train', 'net__callbacks__valid_loss', 'net__callbacks__valid_loss__name', 'net__callbacks__valid_loss__lower_is_better', 'net__callbacks__valid_loss__on_train', 'net__callbacks__valid_acc', 'net__callbacks__valid_acc__scoring', 'net__callbacks__valid_acc__lower_is_better', 'net__callbacks__valid_acc__on_train', 'net__callbacks__valid_acc__name', 'net__callbacks__valid_acc__target_extractor', 'net__callbacks__valid_acc__use_caching', 'net__callbacks__print_log', 'net__callbacks__print_log__keys_ignored', 'net__callbacks__print_log__sink', 'net__callbacks__print_log__tablefmt', 'net__callbacks__print_log__floatfmt', 'net__callbacks__print_log__stralign'])
net.get_params().keys()
dict_keys(['module', 'criterion', 'optimizer', 'lr', 'max_epochs', 'batch_size', 'iterator_train', 'iterator_valid', 'dataset', 'train_split', 'callbacks', 'predict_nonlinearity', 'warm_start', 'verbose', 'device', '_kwargs', 'classes', 'callbacks__epoch_timer', 'callbacks__train_loss', 'callbacks__train_loss__name', 'callbacks__train_loss__lower_is_better', 'callbacks__train_loss__on_train', 'callbacks__valid_loss', 'callbacks__valid_loss__name', 'callbacks__valid_loss__lower_is_better', 'callbacks__valid_loss__on_train', 'callbacks__valid_acc', 'callbacks__valid_acc__scoring', 'callbacks__valid_acc__lower_is_better', 'callbacks__valid_acc__on_train', 'callbacks__valid_acc__name', 'callbacks__valid_acc__target_extractor', 'callbacks__valid_acc__use_caching', 'callbacks__print_log', 'callbacks__print_log__keys_ignored', 'callbacks__print_log__sink', 'callbacks__print_log__tablefmt', 'callbacks__print_log__floatfmt', 'callbacks__print_log__stralign'])
import torch.optim as optim

custom_grid = {
	'net__max_epochs':[20, 30],
	'net__lr': [0.01, 0.05, 0.1],
	'net__module__num_units_d1': [50, 100, 150],
	'net__module__num_units_d2': [50, 100, 150],
	'net__optimizer': [optim.Adam, optim.SGD, optim.RMSprop]
	}
  • 이번에는 hyperparameter 모델을 적용하여 모델을 빠르게 만들어 본다.
tuned_skorch_model = tune_model(skorch_model, custom_grid = custom_grid)
AccuracyAUCRecallPrec.F1KappaMCC
00.87620.96670.96860.85620.90890.71820.7316
10.86750.94770.87840.91060.89420.71710.7179
20.83750.94520.78350.95350.86020.67060.6891
30.85750.95220.82080.94900.88030.70660.7180
40.79750.93150.97260.77040.85970.51270.5602
Mean0.84720.94870.88480.88790.88070.66500.6834
SD0.02800.01140.07630.06840.01920.07810.0631

References

  1. https://pycaret.org/
  2. https://www.analyticsvidhya.com/blog/2020/05/pycaret-machine-learning-model-seconds/
  3. https://github.com/skorch-dev/skorch
  4. https://towardsdatascience.com/skorch-pytorch-models-trained-with-a-scikit-learn-wrapper-62b9a154623e
  5. https://towardsdatascience.com/pycaret-skorch-build-pytorch-neural-networks-using-minimal-code-57079e197f33

Python with PostgreSQL - Create Database

PostgreSQL 및 Python 연동 예제

라이브러리 설치

  • 우선 설치를 진행한다.
$ pip install psycopg2-binary
Downloading psycopg2_binary-2.9.2-cp310-cp310-win_amd64.whl (1.2 MB)
     |████████████████████████████████| 1.2 MB 6.4 MB/s
Installing collected packages: psycopg2-binary
Successfully installed psycopg2-binary-2.9.2

현재 Database 확인

  • cmd 파일 창을 열고, 현재 DB 리스트를 확인한다.
    • \list or l: 전체 databases 리스트를 조회한다.
C:\Users\user>psql --username=postgres
postgres 사용자의 암호:
psql (13.5)
도움말을 보려면 "help"를 입력하십시오.
postgres=# \l
데이터베이스 목록
   이름    |  소유주  | 인코딩 |     Collate      |      Ctype       |      액세스 권한
-----------+----------+--------+------------------+------------------+-----------------------
 postgres  | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 template0 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
 template1 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
(3개 행)

Database 생성

# import the psycopg2 database adapter for PostgreSQL
from psycopg2 import connect, extensions

# connect
def createDB():
    conn = connect(
        database="postgres", user='postgres', password='your_password', host='127.0.0.1', port='5432'
    )

    # object type: psycopg2.extensions.connection
		# object type: conn 객체 유형을 확인한다. 
    print("\ntype(conn):", type(conn))

    # 명령 처리 함수 구현
    cursor = conn.cursor()

    # Create Database Creation
		# 먼저 DB_NAME을 생성한다. 
		
    DB_NAME = "testDB"
	
    # get the isolation leve for autocommit
		# autocommit을 설정한다. 
    autocommit = extensions.ISOLATION_LEVEL_AUTOCOMMIT
    print("ISOLATION_LEVEL_AUTOCOMMIT:", extensions.ISOLATION_LEVEL_AUTOCOMMIT)

    # set the isolation level for the connection's cursors
    # will raise ActiveSqlTransaction exception otherwise
    conn.set_isolation_level(autocommit)

    # Create Database
    # instantiate a cursor object from the connection
    cursor = conn.cursor()

    # use the execute METHOD to make a SQL Request
    cursor.execute("CREATE DATABASE " + str(DB_NAME))
    print("Database created successfully...!")

    # close the cursor to avoid memory leaks
    cursor.close

    # Connection Closed to avoid memory leaks
    conn.close()

if __name__ == "__main__":
    createDB()
  • DB 생성시 중요한 건, autocommit을 설정해줘야 한다는 것이다. 만약 해당 설정을 삭제하고 재 실행하면, psycopg2.errors.ActiveSqlTransaction: CREATE DATABASE cannot run inside a transaction block 과 같은 에러 메시지가 나타나게 될 것이다.

현재 Database 확인

  • cmd 파일 창을 열고, 현재 DB 리스트를 확인한다.
    • \list or l: 전체 databases 리스트를 조회한다.
    • testdb가 생성된 것을 확인할 수 있다.
postgres=# \l
                                      데이터베이스 목록
   이름    |  소유주  | 인코딩 |     Collate      |      Ctype       |      액세스 권한
-----------+----------+--------+------------------+------------------+-----------------------
 postgres  | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 template0 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
 template1 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
 testdb    | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
(4개 행)

Database 삭제

  • 이번에는 Database를 삭제하는 코드를 작성하고, 실행하여 testdb를 삭제하도록 한다.
# import the psycopg2 database adapter for PostgreSQL
from psycopg2 import connect, extensions

# delete
def deleteDB():
    conn = connect(
        database="postgres", user='postgres', password='your_password', host='127.0.0.1', port='5432'
    )

    # object type: psycopg2.extensions.connection
    print("\ntype(conn):", type(conn))

    # SQL Query
    DB_NAME = "testDB"
    # get the isolation leve for autocommit
    autocommit = extensions.ISOLATION_LEVEL_AUTOCOMMIT
    print("ISOLATION_LEVEL_AUTOCOMMIT:", extensions.ISOLATION_LEVEL_AUTOCOMMIT)

    # set the isolation level for the connection's cursors
    # will raise ActiveSqlTransaction exception otherwise
    conn.set_isolation_level(autocommit)

    # Create Database
    # instantiate a cursor object from the connection
    # 명령 처리 함수 구현
    cursor = conn.cursor()

    # use the execute METHOD to make a SQL Request
    cursor.execute("DROP DATABASE " + str(DB_NAME))
    print("Database Drop successfully...!")

    # close the cursor to avoid memory leaks
    cursor.close()

    # Connection Closed to avoid memory leaks
    conn.close()

if __name__ == "__main__":
    # createDB()
    deleteDB()

현재 Database 확인

  • cmd 파일 창을 열고, 현재 DB 리스트를 확인한다.
    • \list or l: 전체 databases 리스트를 조회한다.
    • testdb 가 삭제된 것을 확인할 수 있다.
C:\Users\user>psql --username=postgres
postgres 사용자의 암호:
psql (13.5)
도움말을 보려면 "help"를 입력하십시오.
postgres=# \l
데이터베이스 목록
   이름    |  소유주  | 인코딩 |     Collate      |      Ctype       |      액세스 권한
-----------+----------+--------+------------------+------------------+-----------------------
 postgres  | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 |
 template0 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
 template1 | postgres | UTF8   | Korean_Korea.949 | Korean_Korea.949 | =c/postgres          +
           |          |        |                  |                  | postgres=CTc/postgres
(3개 행)

소결

  • 해당 함수에서 불필요하게 재반복해서 사용하는 코드들이 있다.
  • 이러한 재반복 코드는 Class로 정의해서 사용하면 훨씬 더 간결하게 작성할 수 있다.
  • 다음번에는 Class로 정의해서 코드를 작성하도록 한다.

Verifying Outlier Values

이상값의 정의

  • 다소 주관적이며(Somewhat Subjective), 특정 분포의 중심경향성, 퍼진 정도와 형태에 따라 밀접한 관련이 있다.
    • 평균에서 표준편차보다 몇 배 더 떨어져 있다거나, 즉, 정규분포를 이루고 있지 않을 때
    • 왜도 또는 첨도가 발생할 때
  • 균등분포(Uniform Distribution)는, 발생할 확률이 모두 같다.
    • 만약, 확진자수가 최소 1부터 최대 10,000,000까지 균등하게 분포한다면, 어떤 값도 이상값으로 고려하지 않는다.
  • 이상값을 파악하려면, 반드시, 각 변수의 분포를 먼저 이해해야 한다.

라이브러리 및 데이터 불러오기

  • 실습을 위한 데이터를 불러온다.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
import scipy.stats as scistat

covidtotals = pd.read_csv("data/covidtotals.csv")
covidtotals.set_index("iso_code", inplace = True)

case_vars = ["location", "total_cases", "total_deaths", "total_cases_pm", "total_deaths_pm"]
demo_vars = ["population", "pop_density", "median_age", "gdp_per_capita", "hosp_beds"]

print(covidtotals.head())
            lastdate     location  total_cases  total_deaths  total_cases_pm  \
iso_code                                                                       
AFG       2020-06-01  Afghanistan        15205           257         390.589   
ALB       2020-06-01      Albania         1137            33         395.093   
DZA       2020-06-01      Algeria         9394           653         214.225   
AND       2020-06-01      Andorra          764            51        9888.048   
AGO       2020-06-01       Angola           86             4           2.617   

          total_deaths_pm  population  pop_density  median_age  \
iso_code                                                         
AFG                 6.602  38928341.0       54.422        18.6   
ALB                11.467   2877800.0      104.871        38.0   
DZA                14.891  43851043.0       17.348        29.1   
AND               660.066     77265.0      163.755         NaN   
AGO                 0.122  32866268.0       23.890        16.8   

          gdp_per_capita  hosp_beds  
iso_code                             
AFG             1803.987       0.50  
ALB            11803.431       2.89  
DZA            13913.839       1.90  
AND                  NaN        NaN  
AGO             5819.495        NaN  
  • describe() 함수를 통해 수치 데이터의 분포를 확인하도록 한다.
covid_case_df = covidtotals.loc[:, case_vars]
print(covid_case_df.describe())
        total_cases   total_deaths  total_cases_pm  total_deaths_pm
count  2.100000e+02     210.000000      210.000000       210.000000
mean   2.921614e+04    1770.714286     1355.357943        55.659129
std    1.363978e+05    8705.565857     2625.277497       144.785816
min    0.000000e+00       0.000000        0.000000         0.000000
25%    1.757500e+02       4.000000       92.541500         0.884750
50%    1.242500e+03      25.500000      280.928500         6.154000
75%    1.011700e+04     241.250000     1801.394750        31.777250
max    1.790191e+06  104383.000000    19771.348000      1237.551000
  • 백분위수(quantile)로 데이터를 표시한다.
print(covid_case_df.quantile(np.arange(0.0, 1.1, 0.1)))
     total_cases  total_deaths  total_cases_pm  total_deaths_pm
0.0          0.0           0.0          0.0000           0.0000
0.1         22.9           0.0         17.9986           0.0000
0.2        105.2           2.0         56.2910           0.3752
0.3        302.0           6.7        115.4341           1.7183
0.4        762.0          12.0        213.9734           3.9566
0.5       1242.5          25.5        280.9285           6.1540
0.6       2514.6          54.6        543.9562          12.2452
0.7       6959.8         137.2       1071.2442          25.9459
0.8      16847.2         323.2       2206.2982          49.9658
0.9      46513.1        1616.9       3765.1363         138.9045
1.0    1790191.0      104383.0      19771.3480        1237.5510
  • 왜도는 분포가 얼마나 대칭적인지를 나타냄
  • 왜도와 첨도는 어떻게 대칭적인지를 설명하며, 분포의 꼬리가 각각 얼마나 두꺼운지 나타냄.
covid_case_df.skew(axis=0, numeric_only = True)
total_cases        10.804275
total_deaths        8.929816
total_cases_pm      4.396091
total_deaths_pm     4.674417
dtype: float64
covid_case_df.kurtosis(axis=0, numeric_only = True)
total_cases        134.979577
total_deaths        95.737841
total_cases_pm      25.242790
total_deaths_pm     27.238232
dtype: float64
  • 정규성 검정을 테스트 한다.
  • p값 0.05미만에서 95% 수준에서 정규분포의 귀무가설을 기각하고, 대립가설을 채택한다.
    • 귀무가설: 표본의 모집단이 정규분포를 이루고 있다.
    • 대립가설: 표본의 모집단이 정규분포를 이루고 있지 않다.
scistat.shapiro(covid_case_df['total_cases'])
ShapiroResult(statistic=0.19379639625549316, pvalue=3.753789128593843e-29)
scistat.shapiro(covid_case_df['total_deaths'])
ShapiroResult(statistic=0.19832086563110352, pvalue=4.3427896631016077e-29)
scistat.shapiro(covid_case_df['total_cases_pm'])
ShapiroResult(statistic=0.5220695734024048, pvalue=1.3972683006509067e-23)
scistat.shapiro(covid_case_df['total_deaths_pm'])
ShapiroResult(statistic=0.41877639293670654, pvalue=1.361060423265974e-25)
  • 위 4개의 feature 모두 정규분포를 이루고 있지 않음을 확인할 수 있다.
  • 이번에는 qqplot을 그린다.
sm.qqplot(covid_case_df[["total_cases"]].sort_values(["total_cases"]), line = "s")
plt.title("QQ Plot of Total Cases")
Text(0.5, 1.0, 'QQ Plot of Total Cases')

png