본문 바로가기
python 및 머신러닝/파이썬 라이브러리를 활용한 머신러닝

scikit-learn 책 정리

by java개발자 2017. 9. 18.

Data load 

--> 데이터 특성 변환 (fit_transform)

--> data를 train/test로 나누기 

--> train data로 특성 선택 및 test data에 적용 (fit -> transform)

--> train data로 scaling 및 test data에 적용 (fit -> transform)

--> 알고리즘 학습 (fit -> predict / score)

---------------------------------------------------------------------------------


1. Data


2. 데이터 변환 (4장)¶

2-1 범주형데이터변환(원 핫 인코딩)

2-2 구간분할

2-3 상호작용

2-4 다항식

2-5 수학함수(일변량 비선형 변환), log, exp, sin

2-6 t-SNE 매니폴드 (3장)


3. 군집 (3장)¶

3-1 KMeans

3-2 Agglomerative 병합군집

3-3 DBSCAN


4. 특성 선택 및 전처리

4-0 DATA 나누기 (2장)

4-1 특성 선택 (4장)

4-1-1 특성자동선택 - 일변량 통계

4-1-2 특성자동선택 - 모델기반 특성 선택

4-1-3 특성자동선택 - 반복적 특성 선택

4-1-4 주성분분석 PCA (3장)

4-1-5 비음수행렬분해 NMF (3장)

4-2 DATA scaling (3장)



5. 지도학습

5-3 지도학습 알고리즘 (2장)

5-3-1 분류

5-3-2 회귀

분류

KNeighborsClassifier

LogisticRegression

LinearSVC

DecisionTreeClassifier

RandomForestClassifier

GradientBoostingClassifier

SVC

MLPClassifier

DummyClassifier

회귀

KNeighborsRegressor

LinearRegression

Ridge

Lasso

DecisionTreeRegressor


6. 교차검증, 그리드서치


7. 파이프


---------------------------------------------------------------------------------

from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
import os
import graphviz
%matplotlib inline

from sklearn.model_selection import *
from sklearn.neighbors import *
from sklearn.linear_model import *
from sklearn.tree import *
from sklearn.ensemble import *
from sklearn.svm import *
from sklearn.tree import *
from sklearn.neural_network import *
from sklearn.metrics import *
from sklearn.preprocessing import *
from sklearn.pipeline import *
from sklearn.decomposition import *
from sklearn.datasets import *
from sklearn.dummy import *
from sklearn.feature_selection import *
from sklearn.manifold import *
from sklearn.cluster import *
from sklearn.pipeline import *

1. Data

iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
feature_names = iris_dataset.feature_names
target_names = iris_dataset.target_names

2. 데이터 변환 (4장)¶

2-1 범주형데이터변환(원 핫 인코딩)

2-2 구간분할

2-3 상호작용

2-4 다항식

2-5 수학함수(일변량 비선형 변환), log, exp, sin

2-6 t-SNE 매니폴드 (3장)

# train / test로 나눈 다음에 각각 처리해도 된다. tSNE만 빼고

try:
    # 2-1. 범주형 데이터 변환(원 핫 인코딩)
    # iris는 범주형데이터가 아니므로 예제를 위해 다른 데이터 가져오기
    dictData = {'숫자특성':[0,1,2,1], '범주형특성':['양말', '여우','양말','상자']}
    df = pd.DataFrame(dictData)
    # 방법1 - 두 컬럼 모두 변환됨
    df['숫자특성'] = df['숫자특성'].astype(str) # 숫자를 문자열로 변환하면, 가변수특성이 만들어진다.
    df_dummies = pd.get_dummies(df)
    # 방법2 - 두 컬럼 모두 변환됨
    df_dummies = pd.get_dummies(df, columns=['범주형특성','숫자특성']) # 특정 컬럼 지정 가능
except Exception as e:
    print(e)

try:
    # 2-2 구간분할 (특성 1개만 있는 회귀 데이터를 각 구간분할해서 10개의 특성으로 확대하기)
    X, y = mglearn.datasets.make_wave(n_samples=100)
    feature_names = ['feature1']
    target_names = ['class1']
    bins = np.linspace(-3, 3, 11)
    X_which = np.digitize(X, bins=bins)
    encoder = OneHotEncoder(sparse=False) # 숫자로된 범주형변수에 적용
    encoder.fit(X_which)
    X_binned = encoder.transform(X_which)
    print('X: {}'.format(X.shape)) # 100, 1
    print('X_which: {}'.format(X_which.shape)) # 100, 1    
    print('X_binned: {}'.format(X_binned.shape)) # 100, 10
except Exception as e:
    print(e)

try:
    # 2-3 상호작용(각 특성간 상호작용)
    X_combined = np.hstack([X, X_binned]) # 특성 합치기
    X_product = np.hstack([X_binned, X * X_binned])  # 특성간 곱해서 합치기
    print('X_combined: {}'.format(X_combined.shape)) # 100, 11
    print('X_product: {}'.format(X_product.shape)) # 100, 20
except Exception as e:
    print(e)
    
try:
    # 2-4 다항식 추가(degree=10 : x ** 10까지 고차항을 추가한다. include_bias=False: 값이1인 절편특성은 제외한다.)
    poly = PolynomialFeatures(degree=10, include_bias=False)
    poly.fit(X)
    print('poly feature names: {}'.format(poly.get_feature_names()))
    X_poly = poly.transform(X)
    print('X: {}'.format(X.shape)) # 100, 1
    print('X_poly: {}'.format(X_poly.shape)) # 100, 10
except Exception as e:
    print(e)    

try:
    # 2-5  수학함수(일변량 비선형 변환) - 로그스케일
    rnd = np.random.RandomState(0) # 임의 데이터
    X_org = rnd.normal(size=(1000, 3))
    w = rnd.normal(size=3)
    X = rnd.poisson(10 * np.exp(X_org)) # 특성은 모두 정수
    y = np.dot(X_org, w) # 응답은 모두 실수
    print('X: {}'.format(X.shape)) # 1000, 3
    print('y: {}'.format(y.shape)) # 1000
    # log 처리
    X = np.log(X)
except Exception as e:
    print(e)     
    
try:
    # 2-6 tSNE 매니폴드
    tsne = TSNE(random_state=42)
    X = tsne.fit_transform(X) # transform 함수가 없다.
except Exception as e:
    print(e)     

3. 군집 (3장)¶

3-1 KMeans

3-2 Agglomerative 병합군집

3-3 DBSCAN

iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
clust = KMeans(n_clusters=3)
clust.fit(X)
print('label: {}'.format(clust.labels_))
print('predict: {}'.format(clust.predict(X)))
print('score: {}'.format(clust.score(X)))

clust = AgglomerativeClustering(n_clusters=3)
print('predict: {}'.format(clust.fit_predict(X)))

clust = DBSCAN()
print('predict: {}'.format(clust.fit_predict(X)))

4. 특성 선택 및 전처리

4-0 DATA 나누기 (2장)

4-1 특성 선택 (4장)

4-1-1 특성자동선택 - 일변량 통계

4-1-2 특성자동선택 - 모델기반 특성 선택

4-1-3 특성자동선택 - 반복적 특성 선택

4-1-4 주성분분석 PCA (3장)

4-1-5 비음수행렬분해 NMF (3장)

4-2 DATA scaling (3장)

# 4-0. 지도학습 전처리 - DATA 나누기
if len(target_names) == 1:
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
else:
    # 분류문제 : stratify=y, 타켓종류가 2개 이상인 경우 target의 비율에 맞춰서 DATA를 나눈다.
    X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)

# 4-1 특성 선택
try:
    cancer = load_breast_cancer()
    X = cancer.data
    y = cancer.target
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    # 4-1-1 특성자동선택 - 일변량 통계
    select = SelectPercentile(percentile=50)
    select.fit(X_train, y_train)
    # 4-1-2 모델 기반 특성 선택(feature_importances_ 속성을 이용)
    select = SelectFromModel(RandomForestClassifier(n_estimators=100, random_state=42),threshold="median")
    select.fit(X_train, y_train)
    # 4-1-3 특성자동선택 - 반복적 특성 선택
    select = RFE(RandomForestClassifier(n_estimators=100, random_state=42),n_features_to_select=40)   
    select.fit(X_train, y_train)
    # 4-1-4 PCA
    select = PCA(n_components=2, whiten=True, random_state=0)
    select.fit(X_train)
    # 4-1-5 NMF
    select = NMF(n_components=15, random_state=0)
    select.fit(X_train)
    
    print('X_train: {}'.format(X_train.shape)) # 426, 30
    X_train = select.transform(X_train)
    print('X_train_select: {}'.format(X_train.shape)) # 426, 15
    X_test = select.transform(X_test)
except Exception as e:
    print(e)        

# 4-2. 지도학습 전처리 - DATA scaling(option)    
try:
    scaler = MinMaxScaler()
    scaler = StandardScaler()
    scaler = RobustScaler()
    scaler = Normalizer()
    
    scaler.fit(X_train)
    X_train = scaler.transform(X_train)
    X_test = scaler.transform(X_test)    
except Exception as e:
    print(e)        

5. 지도학습

5-3 지도학습 알고리즘 (2장)

5-3-1 분류

5-3-2 회귀

iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# 5-3 지도학습
# 5-3-1 분류
model = KNeighborsClassifier(n_neighbors=3)
model = LogisticRegression(C=100, penalty="l1")
model = LinearSVC()
model = DecisionTreeClassifier(max_depth=4, random_state=0)
model = RandomForestClassifier(n_estimators=5, random_state=2)
model = GradientBoostingClassifier(max_depth=1, random_state=0, learning_rate=1)
model = SVC(kernel='rbf', C=10, gamma=0.1)
model = MLPClassifier(solver='lbfgs', random_state=0, hidden_layer_sizes=[10, 10], activation='tanh', max_iter=1000, alpha=1)
model = DummyClassifier(strategy='most_frequent')
5-3-2 회귀
model = KNeighborsRegressor(n_neighbors=3)
model = LinearRegression()
model = Ridge(alpha=0.1)
model = Lasso(alpha=0.01, max_iter=100000)
model = DecisionTreeRegressor(max_depth=4, random_state=0)
model.fit(X_train, y_train)
print('predict: {}'.format(model.predict(X_test)))
print('train score: {}'.format(model.score(X_train, y_train)))
print('test score: {}'.format(model.score(X_test, y_test)))

6. 교차검증, 그리드서치

6-1 교차검증

6-2 그리드 서치

6-3 중첩 교차검증(교차검증 + 그리드 서치)

중첩 교차검증(교차검증 + 그리드서치)을 사용할 경우, score가 높은 최적의 파라메터를 찾을 수 없기 때문에, 교차검증부분은 따로 구현이 필요하다.

6-4 my 중첩 교차검증

# 6-1 교차검증
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
lr = LogisticRegression()
scores = cross_val_score(lr, X, y, cv=5)
print('scores:{}, scores.mean:{}'.format(scores, scores.mean()))

# 6-2 그리드 서치
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100], 'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
print('grid_search scores: {}'.format(grid_search.score(X_test, y_test)))
print('grid_search.best_params_: {}'.format(grid_search.best_params_))
print('grid_search.best_score_: {}'.format(grid_search.best_score_))
print('grid_search.best_estimator_: {}'.format(grid_search.best_estimator_))

# 6-3 중첩 교차검증(교차검증 + 그리드 서치)
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100], 'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
scores = cross_val_score(GridSearchCV(SVC(), param_grid, cv=5), X, y, cv=5, n_jobs=-1)
print('scores:{}, scores.mean:{}'.format(scores, scores.mean()))

# 6-4 my 중첩 교차검증
def my_cross_val_score(model, X, y):
    # cross_val_score 내부의 상태를 알 수 없어서 직접 구형
    scores = []
    for i in range(5):
        X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y)
        ret = model.fit(X_train, y_train)
        print(i)
        print(ret.best_score_)
        print(ret.best_params_) # train/test data를 어떻게 나누냐에 따라 선택되는 것이 다르다.
        scores.append(ret.score(X_test, y_test))
    return scores
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100], 'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
grid = GridSearchCV(SVC(), param_grid, cv=5)
scores = my_cross_val_score(grid, X, y)
print(scores)

# 6-4 my 중첩 교차검증
def my_cross_val_score(model, X, y):
    # cross_val_score 내부의 상태를 알 수 없어서 직접 구형
    scores = []
    for i in range(5):
        X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y)
        ret = model.fit(X_train, y_train)
        print(i)
        print(ret.best_score_)
        print(ret.best_params_) # train/test data를 어떻게 나누냐에 따라 선택되는 것이 다르다.
        scores.append(ret.score(X_test, y_test))
    return scores
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100], 'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
grid = GridSearchCV(SVC(), param_grid, cv=5)
scores = my_cross_val_score(grid, X, y)
print(scores)

# 6-5 파이프
iris_dataset = load_iris()
X = iris_dataset.data
y = iris_dataset.target
param_grid = {'ridge__alpha':[0.001, 0.01, 0.1, 1, 10, 100]}
pipe = make_pipeline(StandardScaler(), Ridge()) # 정규화 추가 가능
grid = GridSearchCV(pipe, param_grid, cv=5, n_jobs=1)
scores = my_cross_val_score(grid, X, y)
print(scores)