[mysql] workbench에서 ERD툴 사용하기 (Database Modeling)

데이터베이스 모델링 (Database Modeling)

데이터베이스 모델링(또는 데이터 모델링)이란 현실 세계에서 사용되는 작업이나 사물들을 DBMS의 데이터베이스 개체로 옮기기 위한 과정이라고 할 수 있습니다.

데이터베이스 모델링은 모델링을 하는 사람이 어떤 사람이냐에 따라서 각기 다른 결과가 나올 수밖에 없고 ‘많은 실무 경험과 지식을 가진 사람이 더 좋은 모델링을 한다’ 라고 합니다.

3가지의 모델링 방식이 있다.
- 개념적 모델링
- 논리적 모델링
- 물리적 모델링

개념적 모델링은 주로 업무 분석 단계에서 진행되며 논리적 모델링은 업무 분석의 후반부와 시스템 설계를 하는 부분에 걸쳐서 진행된다고 할 수 있습니다. 마지막으로 물리적 모델링은 시스템 설계 단계의 후반부에서 주로 진행됩니다.

그러나 모두 절대적인 것은 아니며 사람에 따라 조금씩 차이를 보이기도 합니다.

워크벤치는 이 모델링 툴을 제공해주는데 그것이 바로 ERD툴입니다.

ERD란?

Entity Relationship Diagram의 약자로, 개체관계도라고 부릅니다

장점
  1. 만들고자 하는 바를 더 명확하게 알 수 있다.
  2. 이해하고 소통하기에 편리하다.
  3. RDBMS 데이터 설계가 쉬워진다.
데이터베이스

모델링에서는 데이터베이스를 Schema라고 부릅니다.

실습을 해보기 전에 ERD에 대해 소개를 하였습니다. 실습은 워크벤치를 사용하였고. MySQL workbench는 약 10년 정도 상업용으로 개발되어 판매되다가, MySQL에서 workbench를 인수하여 오픈소스로 풀었다고 합니다.

실습과정
  1. FILE > New Model 클릭스크린샷 2020-07-23 오후 7 34 11
  1. Model의 이름 설정(안해도 됨)스크린샷 2020-07-23 오후 7 35 06
  1. 테이블 생성 > 흰 바탕에 클릭 > 컬럼 생성
  2. PK와 FK 설정 (설정 시 place a relationship using existing columns 선택 > 자식테이블의 해당 컬럼 열을 먼저 클릭 후 부모테이블의 컬럼 열 클릭)
  3. 관계 생성스크린샷 2020-07-23 오후 7 36 52
  1. 저장 > database의 forward engineer 선택 > continue 스크린샷 2020-07-23 오후 7 37 55

최종적으로 모델링이 되어 있는 db와 table 생성(refresh all)

[MySQL] Storage Engine (InnoDB vs MyISAM)

생각없이 Engine을 InnoDB만 사용했지 왜 이것을 사용해야 하는지 고민해본 적이 없었다.

하지만 많은 양의 데이터를 적재하면 데이터의 수가 매우 많거나 column의 갯수가 많아지면 공간부족 현상이 나타나게 되고, 그로 인해 엔진에 대해 고민하기 시작하였다.

대략 500개에 달하는 칼럼이 필요한 상황이였다. 그래서 어떻게 테이블에 적재해야 효율적인지 고민이 필요했다.

또한 InnoDB 테이블에 많은 칼럼을 추가하니 Row size too large. 라는 오류가 발생해서 Engine을 변경하는 방법을 생각하게 되었다.

우선 각 Stroage Engine에 대해 알아보았다.

Mysql Storage Engine은 물리적 저장장치에서 데이터를 어떤 식으로 구성하고 읽어올지를 결정하는 역할을 한다.

기본적으로 8가지의 스토리지 엔진이 탑재되어 있으며 CREATE TABLE문을 사용하여 테이블을 생성할 때 엔진 이름을 추가함으로써 간단하게 설정할 수 있다.

그 중 가장 많이 쓰이는 엔진은 InnoDB, MyISAM, Archive 3가지이다.

InnoDB

테이블 생성 시, 따로 스토리지 엔진을 명시하지 않으면 default로 설정되는 스토리지 엔진이다.

InnoDB는 트랜잭션(tranjection)을 지원하고, 커밋(commit)과 롤백(roll-back) 그리고 데이터 복구 기능을 제공하므로 데이터를 효과적으로 관리할 수 있다.

InnoDB는 기본적으로 row-level locking을 제공하며, 또한 데이터를 clustered index에 저장하여 PK기반의 query의 비용을 줄인다.

또한, PK 제약을 제공하여 데이터 무결성을 보장한다.

여기서 clustered index에 저장한다는 것은 데이터를 PK순서에 맞게 저장한다는 뜻이므로 order by 등 쿼리에 유리할 수 있다. 또한 row-level locking을 제공한다는 뜻은 테이블에 CRUD할 때, 로우별로 락을 잡기 때문에 multi-thread에 보다 효율적이라는 말이다.

물론 장점만 있는 것은 아니다. InnoDB는 더욱 많은 메모리와 디스크를 사용한다. 또한 데이터가 깨졌을 때 단순 파일 백업/복구만으로 처리가 가능한 MyISAM과 달리 InnoDB의 경우 복구 방법이 어렵다. MyISAM이나 Memory 방식이 지원하지 않는 FK의 경우도 테이블 간 데이터 체크로 인한 lock, 특히 dead lock이 발생할 가능성이 있다.

InnoDB의 최대 행 저장공간

Mysql 테이블의 행 크기는 스토리지 엔진에 제약이 없다면 기본적으로 최대 65535바이트이다. 하지만 스토리지 엔진에 따라 제약이 추가되어 행 크기는 줄어들 수 있다.

BLOB, TEXT 컬럼의 내용은 행의 남은 부분이 아닌 별도의 공간에 저장되기 때문에 각각 912바이트만 영향을 준다. (포인트 저장 공간이 912바이트) 여기서 중요한 것은 위의 내용은 스토리지 엔진에 상관없이 기본적으로 이렇다는 것이다.

MyISAM

트랜잭션(tranjection)을 지원하지 않고 table-level locking을 제공한다.

따라서 1개의 ROW을 READ하더라도 테이블 전체에 락을 잡기 때문에 multi-thread 환경에서 성능이 저하될 수 있다.

하지만 InnoDB에 비해 기능적으로 단순하므로 대부분의 작업은 InnoDB보다 속도면에서 우월하다.

단순한 조회의 경우 MyISAM이 InnoDB보다 빠르지만, Order By등 정렬들의 구문이 들어간다면 InnoDB보다 느리다.

왜냐하면 InnoDB는 클러스터링 인덱스에 저장하기 때문에 PK에 따라 데이터 파일이 정렬되어 있지만, MyISAM은 그렇지 않기 때문이다.

Full text searching을 지원한다.

MyISAM 엔진의 경우 최대 행 크기가 기본 MySQL 제약을 따르므로 최대 행 크기는 65535바이트가 될 것이다.

Archive

로그 수집에 적합한 엔진이다. 데이터가 메모리상에서 압축되고 압축된 상태로 디스크에 저장되기 때문에 row-level locking이 가능하다.

다만, 한번 INSERT된 데이터는 UPDATE, DELETE를 사용할 수 없으며 인덱스를 지원하지 않는다. 따라서 거의 가공하지 않을 데이터에 대해서 관리하는데에 효율적일 수 있고, 테이블 파티셔닝도 지원한다. 다만 트랜잭션은 지원하지 않는다.

[Python] SQLAlchemy 사용하기

DataFrame을 MySQL에 저장하기 위해 먼저 엔진 커넥터가 필요합니다. 파이썬3에서는 MySQLdb를 지원하지 않기 때문에, pymysql로 불러와야 합니다. 꼭 pymysql이 아니어도 상관없지만, 사용해보면 mysql-connector 보다 빠르다는걸 체감할 수 있습니다. 먼저, 필요한 패키지를 설치해줍니다.
1
2
3
# python3
pip install pymysql
pip install sqlalchemy
SQLAlchemy, Pymysql, MySQLdb
install_as_MySQLdb() 함수를 통해 MySQLdb와 호환 가능합니다. 이제 sqlalchemy를 통해 DB에 연결할 수 있습니다. 주소에서 root, password는 DB에 맞게 변경해야 합니다.
1
2
3
4
5
6
7
8
9
import pandas as pd
from sqlalchemy import create_engine

# MySQL Connector using pymysql
pymysql.install_as_MySQLdb()
import MySQLdb

engine = create_engine("mysql://root:"+"password"+"@public IP/db_name", encoding='utf-8')
conn = engine.connect()
MySQL에 저장하기
이제 DataFrame을 MySQL에 테이블 형태로 저장할 차례입니다. 아래와 같이 pandas의 to_sql() 함수를 사용하여 저장하면 됩니다.
1
df.to_sql(name=table_name, con=engine, if_exists='append')
자주 사용할 수 있으니 함수로 따로 설정해주면 원할 때마다 쉽게 사용할 수 있겠죠? 그리고 if_exists의 경우 만약 동일 테이블의 이름이 존재한다면 어떻게 처리하겠느냐의 파라미터를 주는 것인데 append 외에도 replace, delete 등 다양한 것이 있습니다.

Pandas: 한 셀의 데이터를 여러 행으로 나누기

1
2
df = pd.DataFrame({'alphabet': ['hello,world,in,python', 'python,is,great', 'data,science']})
df

alphabet
0 hello,world,in,python
1 python,is,great
2 data,science
위와 같이 한 셀에 들어있는 문자열을 컴마로 구분해서 한 글자씩 여러 행으로 나누고 싶다.

해결책:

문자열을 split 해 각 행을 여러 컬럼으로 나눈 후 병합하는 방법으로 구현할 수 있다.

먼저, 각 alphabet 컬럼의 문자열을 배열로 나눈다.
1
2
result = df['alphabet'].str.split(',')
result
0    [hello, world, in, python]
1           [python, is, great]
2               [data, science]
Name: alphabet, dtype: object



배열이 Series를 리턴하게 apply를 적용하면 Series -> DataFrame으로 변환할 수 있다.
1
2
result = result.apply(lambda x: pd.Series(x))
result

0 1 2 3
0 hello world in python
1 python is great NaN
2 data science NaN NaN
stack()을 활용하여 컬럼을 행으로 변환한다.
1
result.stack()
0  0      hello
   1      world
   2         in
   3     python
1  0     python
   1         is
   2      great
2  0       data
   1    science
dtype: object



stack()을 실행하면, 위와 같이 멀티 인덱스를 가진 Series가 된다.

알파벳 낱자만 가져오기 위해 인덱스를 초기화하고, 기준이 된 인덱스도 제거해보자.
1
result.stack().reset_index(level=1, drop=True)
0      hello
0      world
0         in
0     python
1     python
1         is
1      great
2       data
2    science
dtype: object



데이터프레임으로 변환하자
1
2
result = result.stack().reset_index(level=1, drop=True).to_frame('alphabet_single')
result

alphabet_single
0 hello
0 world
0 in
0 python
1 python
1 is
1 great
2 data
2 science
원본 프레임과 위의 프레임을 merge 해보자
1
2
result = df.merge(result, left_index=True, right_index=True, how='left')
result

alphabet alphabet_single
0 hello,world,in,python hello
0 hello,world,in,python world
0 hello,world,in,python in
0 hello,world,in,python python
1 python,is,great python
1 python,is,great is
1 python,is,great great
2 data,science data
2 data,science science

Ubuntu UTF-8 설정하기

아래 명령어를 통해 현재 설정된 언어정보를 확인할 수 있습니다.

locale

한글팩을 설치해줍니다.

apt-get -y install language-pack-ko

한글 utf8 언어팩을 설치합니다.

locale-gen ko_KR.UTF-8

아래 명령어로 언어팩을 선택할 수 있습니다.

dpkg-reconfigure locales

“ko_KR.UTF-8 UTF-8” 에 해당하는 번호를 입력하고 엔터! (저는 290번이였네요. 혹시 다를수 있으니 확인하세요)
“ko_KR.UTF-8” 을 선택합니다. (저는 3번과 4번에 똑같이 나타났습니다. 그냥 3번 눌렀습니다.)

아래 명령어로 시스템 정보를 업데이트하면 적용됩니다.
update-locale LANG=ko_KR.UTF-8 LC_MESSAGES=POSIX

로그아웃 후 다시 로그인한 후(SSH 재접속) 다시 locale 명령어를 입력하면 적용됩니다!
저는 아래와 같이 나타났습니다.

LANG=ko_KR.UTF-8
LANGUAGE=
LC_CTYPE=”ko_KR.UTF-8”
LC_NUMERIC=”ko_KR.UTF-8”
LC_TIME=”ko_KR.UTF-8”
LC_COLLATE=”ko_KR.UTF-8”
LC_MONETARY=”ko_KR.UTF-8”
LC_MESSAGES=POSIX
LC_PAPER=”ko_KR.UTF-8”
LC_NAME=”ko_KR.UTF-8”
LC_ADDRESS=”ko_KR.UTF-8”
LC_TELEPHONE=”ko_KR.UTF-8”
LC_MEASUREMENT=”ko_KR.UTF-8”
LC_IDENTIFICATION=”ko_KR.UTF-8”
LC_ALL=

[PYTHON]칼럼 내 특정 값을 가진 row만 가져오기

1
# 데이터 프레임에서 특정 칼럼 내에서 특정 값이 포함된 row만 가져오기

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

1
2
3
4
# seaborn 데이터 가져오기

iris_df = sns.load_dataset('iris')
iris_df

sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 virginica
146 6.3 2.5 5.0 1.9 virginica
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica

150 rows × 5 columns

여러개를 할 경우 | 로 구분하면 됩니다 (ex: setosa | virginica)

1
2
iris_filtered = iris_df[iris_df['species'].str.contains('setosa|virginica')]
iris_filtered

sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 virginica
146 6.3 2.5 5.0 1.9 virginica
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica

100 rows × 5 columns

1
2


비지도학습 : PCA 주성분 분석

비지도 학습을 사용해 데이터를 변환하는 이유는 여러가지이다. 가장 일반적으로는 데이터를 시각화 압축, 추가 처리를 위해 정보가 더 잘 드러나도록 하기 위해서이다.

  1. 주성분 분석(PCA)

PCA의 본질은 탐색적 분석이다. 즉, 변인을 탐색해서 변환을 통해 주성분을 결정하는 방법이다. 주성분이란 데이터를 구성하는 특성 중 데이터를 가장 잘 설명하는 특성을 말한다. 데이터의 특성이 많을때 중요하다고 판단되는 일부 특성을 활용하여 데이터를 설명 또는 모델링하고자 할때 PCA를 사용한다. 그러다보니 주성분을 알아보는 것 외에 차원을 축소하는 기능을 한다고 볼 수 있는 것이다.

1
2
import mglearn
mglearn.plots.plot_pca_illustration()
output_2_0

왼쪽 위 그래프에서 분산이 가장 큰 방향을 찾는다. 바로 성분 1이다. 이 방향은 데이터에서 가장 많은 정보를 담고 있다. 즉, 특성들의 상관관계가 가장 큰 방향이다. 그 후 첫 번째 방향과 직간인 방향 중에서 가장 많은 정보를 담은 방향을 찾는다. 해당 그래프에서 주성분을 하나로 선정한다면 2번째 성분은 제거된다. 그리고 다시 원래 모양으로 회전시킨다. 따라서 이러한 변환은 데이터에서 노이즈를 제거하거나 주성분에서 유지되는 정보를 시각화는데 종종 사용된다.

예시)

판다스에서 가장 유명한 붓꽃 데이터를 불러온다. 그 후 각 특성의 데이터를 스케일링한 후 주성분 분석을 실시하였다

1
2
iris_df = sns.load_dataset('iris')
iris_df.tail(3)

sepal_length sepal_width petal_length petal_width species
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica
1
2
3
4
5
6
7
8
from sklearn.preprocessing import StandardScaler  # 표준화 패키지 라이브러리 
x = df.drop(['target'], axis=1).values # 독립변인들의 value값만 추출
y = df['target'].values # 종속변인 추출

x = StandardScaler().fit_transform(x) # x객체에 x를 표준화한 데이터를 저장

features = ['sepal length', 'sepal width', 'petal length', 'petal width']
pd.DataFrame(x, columns=features).head()

sepal length sepal width petal length petal width
0 -0.900681 1.032057 -1.341272 -1.312977
1 -1.143017 -0.124958 -1.341272 -1.312977
2 -1.385353 0.337848 -1.398138 -1.312977
3 -1.506521 0.106445 -1.284407 -1.312977
4 -1.021849 1.263460 -1.341272 -1.312977
1
2
3
4
5
6
from sklearn.decomposition import PCA
pca = PCA(n_components=2) # 주성분을 몇개로 할지 결정
printcipalComponents = pca.fit_transform(x)
principalDf = pd.DataFrame(data=printcipalComponents, columns = ['principal component1', 'principal component2'])
# 주성분으로 이루어진 데이터 프레임 구성
principalDf

principal component1 principal component2
0 -2.264542 0.505704
1 -2.086426 -0.655405
2 -2.367950 -0.318477
3 -2.304197 -0.575368
4 -2.388777 0.674767
... ... ...
145 1.870522 0.382822
146 1.558492 -0.905314
147 1.520845 0.266795
148 1.376391 1.016362
149 0.959299 -0.022284

150 rows × 2 columns

1
pca.explained_variance_ratio_
array([0.72770452, 0.23030523])

주성분을 2개로 했을때는 첫번째 성분이 데이터를 72%를 설명한다.

1
pca.components_
array([[ 0.52237162, -0.26335492,  0.58125401,  0.56561105],
       [ 0.37231836,  0.92555649,  0.02109478,  0.06541577]])

위의 주성분 2개에서 각 변수 중요도

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
finalDf = pd.concat([principalDf, df[['target']]], axis = 1)
fig = plt.figure(figsize = (8, 8))
ax = fig.add_subplot(1, 1, 1)
ax.set_xlabel('Principal Component 1', fontsize = 15)
ax.set_ylabel('Principal Component 2', fontsize = 15)
ax.set_title('2 component PCA', fontsize=20)

targets = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']
colors = ['r', 'g', 'b']
for target, color in zip(targets,colors):
indicesToKeep = finalDf['target'] == target
ax.scatter(finalDf.loc[indicesToKeep, 'principal component1']
, finalDf.loc[indicesToKeep, 'principal component2']
, c = color
, s = 50)
ax.legend(targets)
ax.grid()
output_12_0
1
2


1
2


1
2


1
2


1
2


mglearn에 대해

간단하게 그림을 그리거나 필요한 데이터를 바로 불러들이기 위해 mglearn을 사용합니다. 깃허브에 있는 노트북을 실행할 때는 이 모듈에 관해 신경 쓸 필요가 없습니다. 만약 다른 곳에서 mglearn 함수를 호출하려면, pip install mglearn 명령으로 설치하는 것이 가장 쉬운 방법입니다.7

노트_ 이 책은 NumPy, matplotlib, pandas를 많이 사용합니다. 따라서 모든 코드는 다음의 네 라이브러리를 임포트한다고 가정합니다.

from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn

데이터 전처리(Data Scaling with sklearn)

데이터 스케일링이란 데이터 전처리 과정의 하나입니다.

데이터 스케일링을 해주는 이유는 데이터의 값이 너무 크거나 혹은 작은 경우에 모델 알고리즘 학습과정에서 0으로 수렴하거나 무한으로 발산해버릴 수 있기 때문입니다.

따라서, scaling은 데이터 전처리 과정에서 굉장히 중요한 과정입니다.

가볍게 살펴보도록 하겠습니다
1. scale이란?
1
!pip install mglearn
Collecting mglearn
  Downloading mglearn-0.1.9.tar.gz (540 kB)
     |████████████████████████████████| 540 kB 506 kB/s eta 0:00:01
[?25hRequirement already satisfied: numpy in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (1.18.1)
Requirement already satisfied: matplotlib in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (3.2.1)
Requirement already satisfied: scikit-learn in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (0.22.2.post1)
Requirement already satisfied: pandas in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (1.0.3)
Requirement already satisfied: pillow in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (7.0.0)
Requirement already satisfied: cycler in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (0.10.0)
Requirement already satisfied: imageio in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (2.8.0)
Requirement already satisfied: joblib in /opt/anaconda3/lib/python3.7/site-packages (from mglearn) (0.14.1)
Requirement already satisfied: python-dateutil>=2.1 in /opt/anaconda3/lib/python3.7/site-packages (from matplotlib->mglearn) (2.8.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /opt/anaconda3/lib/python3.7/site-packages (from matplotlib->mglearn) (1.2.0)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /opt/anaconda3/lib/python3.7/site-packages (from matplotlib->mglearn) (2.4.7)
Requirement already satisfied: scipy>=0.17.0 in /opt/anaconda3/lib/python3.7/site-packages (from scikit-learn->mglearn) (1.4.1)
Requirement already satisfied: pytz>=2017.2 in /opt/anaconda3/lib/python3.7/site-packages (from pandas->mglearn) (2019.3)
Requirement already satisfied: six in /opt/anaconda3/lib/python3.7/site-packages (from cycler->mglearn) (1.14.0)
Building wheels for collected packages: mglearn
  Building wheel for mglearn (setup.py) ... [?25ldone
[?25h  Created wheel for mglearn: filename=mglearn-0.1.9-py2.py3-none-any.whl size=582638 sha256=6bf4e55bc798dd18a2ce5a5d67e6f134dfc35d54bb51cd8020f85b838a7173b1
  Stored in directory: /Users/wglee/Library/Caches/pip/wheels/f1/17/e1/1720d6dcd70187b6b6c3750cb3508798f2b1d57c9d3214b08b
Successfully built mglearn
Installing collected packages: mglearn
Successfully installed mglearn-0.1.9
1
2
import mglearn
mglearn.plots.plot_scaling()
output_3_0
(1) StandardScaler
각 feature의 평균을 0, 분산을 1로 변경합니다. 모든 특성들이 같은 스케일을 갖게 됩니다.


(2) RobustScaler
모든 특성들이 같은 크기를 갖는다는 점에서 StandardScaler와 비슷하지만, 평균과 분산 대신 median과 quartile을 사용합니다. RobustScaler는 이상치에 영향을 받지 않습니다.


(3) MinMaxScaler
모든 feature가 0과 1사이에 위치하게 만듭니다. 데이터가 2차원 셋일 경우, 모든 데이터는 x축의 0과 1 사이에, y축의 0과 1사이에 위치하게 됩니다.


(4) Normalizer
StandardScaler, RobustScaler, MinMaxScaler가 각 columns의 통계치를 이용한다면 Normalizer는 row마다 각각 정규화됩니다. Normalizer는 유클리드 거리가 1이 되도록 데이터를 조정합니다. (유클리드 거리는 두 점 사이의 거리를 계산할 때 쓰는 방법)
2. Code
scikit-learn에 있는 아이리스 데이터셋으로 데이터 스케일링을 해보겠습니다.
1
2
3
4
5
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.4, random_state=0)
데이터를 학습용과 테스트용으로 분할했습니다.

scaler를 사용하기 이전에 주의해야될 점을 먼저 살펴보겠습니다.

scaler는 fit과 transform 메서드를 지니고 있습니다. fit 메서드로 데이터 변환을 학습하고, transform 메서드로 실제 데이터의 스케일을 조정합니다. 

이때, fit 메서드는 학습용 데이터에만 적용해야 합니다. 그 후, transform 메서드를 학습용 데이터와 테스트 데이터에 적용합니다. scaler는 fit_transform()이란 단축 메서드를 제공합니다. 학습용 데이터에는 fit_transform()메서드를 적용하고, 테스트 데이터에는 transform()메서드를 적용합니다.
(1) StandardScaler code
1
2
3
4
5
6
7
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scale = scaler.fit_transform(X_train)
print('스케일 조정 전 features Min value : {}'.format(X_train.min(axis=0)))
print('스케일 조정 전 features Max value : {}'.format(X_train.max(axis=0)))
print('스케일 조정 후 features Min value : {}'.format(X_train_scale.min(axis=0)))
print('스케일 조정 후 features Max value : {}'.format(X_train_scale.max(axis=0)))
스케일 조정 전  features Min value : [4.3 2.2 1.1 0.1]
스케일 조정 전  features Max value : [7.9 4.4 6.9 2.5]
스케일 조정 후  features Min value : [-1.73905934 -2.11220356 -1.37231262 -1.32054283]
스케일 조정 후  features Max value : [2.32920943 3.06374081 1.74766642 1.68511841]
(2) RobustScaler code
1
2
3
4
5
6
7
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
X_train_scale = scaler.fit_transform(X_train)
print('스케일 조정 전 features Min value : {}'.format(X_train.min(axis=0)))
print('스케일 조정 전 features Max value : {}'.format(X_train.max(axis=0)))
print('스케일 조정 후 features Min value : {}'.format(X_train_scale.min(axis=0)))
print('스케일 조정 후 features Max value : {}'.format(X_train_scale.max(axis=0)))
스케일 조정 전  features Min value : [4.3 2.2 1.1 0.1]
스케일 조정 전  features Max value : [7.9 4.4 6.9 2.5]
스케일 조정 후  features Min value : [-1.01818182 -1.47826087 -0.82993197 -0.70588235]
스케일 조정 후  features Max value : [1.6        2.34782609 0.74829932 0.70588235]
(3) MinMaxScaler code
1
2
3
4
5
6
7
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scale = scaler.fit_transform(X_train)
print('스케일 조정 전 features Min value : {}'.format(X_train.min(axis=0)))
print('스케일 조정 전 features Max value : {}'.format(X_train.max(axis=0)))
print('스케일 조정 후 features Min value : {}'.format(X_train_scale.min(axis=0)))
print('스케일 조정 후 features Max value : {}'.format(X_train_scale.max(axis=0)))
스케일 조정 전  features Min value : [4.3 2.2 1.1 0.1]
스케일 조정 전  features Max value : [7.9 4.4 6.9 2.5]
스케일 조정 후  features Min value : [0. 0. 0. 0.]
스케일 조정 후  features Max value : [1. 1. 1. 1.]
(4) Normalizer code
1
2
3
4
5
6
7
from sklearn.preprocessing import Normalizer 
scaler = Normalizer()
X_train_scale = scaler.fit_transform(X_train)
print('스케일 조정 전 features Min value : {}'.format(X_train.min(axis=0)))
print('스케일 조정 전 features Max value : {}'.format(X_train.max(axis=0)))
print('스케일 조정 후 features Min value : {}'.format(X_train_scale.min(axis=0)))
print('스케일 조정 후 features Max value : {}'.format(X_train_scale.max(axis=0)))
스케일 조정 전  features Min value : [4.3 2.2 1.1 0.1]
스케일 조정 전  features Max value : [7.9 4.4 6.9 2.5]
스케일 조정 후  features Min value : [0.67017484 0.2383917  0.16783627 0.0147266 ]
스케일 조정 후  features Max value : [0.86093857 0.60379053 0.63265489 0.2553047 ]
3. 적용해보기
의사결정나무(decisionTree)로 breat_cancer 데이터셋을 학습해보겠습니다.
먼저, 데이터 스케일링을 적용하지 않은 채 진행하겠습니다.
1
2
3
4
5
6
7
8
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)
tree = DecisionTreeClassifier(criterion='entropy', max_depth=1)
tree.fit(X_train, y_train)
print('test accuracy : %3f' %tree.score(X_test, y_test))
test accuracy : 0.881119


다음은 데이터를 MinMaxScaler로 스케일을 조정하고 의사결정나무 모델로 학습시켜보겠습니다.
1
2
3
4
5
6
7
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
X_train_scale = scaler.fit_transform(X_train)
X_test_scale = scaler.fit_transform(X_test)
tree.fit(X_train_scale, y_train)
print('test accuracy : %3f' %tree.score(X_test_scale, y_test))
test accuracy : 0.860140


비슷하게 나온 것을 알 수 있습니다.
1
2


1
2


[Mysql]Database 용량 확인

[전체 데이터베이스 용량 확인]
select table_schema ‘Linear_Regression’, sum(data_length + index_length) / 1024 / 1024 ‘size(MB)’ from information_schema.tables group by table_schema

[특정 DB명 status 확인]
show table status like ‘DB명’

[특정 DB 용량 늘리기]
alter table ‘DB명’ max_rows = 400000000 avg_row_length=1500