본문 바로가기

Self-Taught/Machine Learning

파이썬 머신러닝 완벽가이드 _ CH.2_(1)

Chapter2.1 _ 사이킷런이란?

 

파이썬 머신러닝 라이브러리 중 가장 많이 사용되는 라이브러리

다양한 알고리즘과 프레임워크, API 제공

 

*텐서플로, 케라스 : 딥러닝 전문 라이브러리가 있다.

 

 

Chapter2.2 _ 첫 번째 머신러닝

붓꽃 데이터 세트의 Feature* 기반 붓꽃 품종 분류*(Classification)

*꽃잎의 길이 너비, 꽃받침의 길이와 너비

*분류는 대표적인 Supervised Learning_지도학습 방법

 

#Supervised Learning _ 지도학습

다양한 feature와 분류 결정값인 Label data*로 모델 학습 --> 별도의 테스트 data set**에서 미지의 레이블 예측

*학습 data set

** 테스트 data set

 

from sklearn.datasets import load_iris   ## data set 로딩
from sklearn.tree import DecisionTreeClassifier   ## 머신러닝 알고리즘 선택 
from sklearn.model_selection import train_test_split   ## 데이터 셋을 학습/테스트로 분리

* 내장 데이터 찾을 때는 sklearn.datasets 이용

* 트리 기반 ML 알고리즘은 sklearn.tree 에서 찾기

* sklearn.model_selection : 데이터를 종류별로 분리하거나, 최적의 하이퍼 파라미터로 평가하기 위한 모듈 모임 

 

import pandas as pd

iris = load_iris()

iris_data=iris.data

iris_label = iris.target

print('iris target 값 : ', iris_label)
print('iris target 명 : ', iris.target_names)

iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)
iris_df['label']=iris.target    ## 새로운 칼럼 추가       -> 이 label 이란 개념이 잘 이해가 가지 않는다. 범주형 변수라고 보면 되는 걸까..? 
print(iris_df.head(5))
iris_df.shape
iris_df['label'].value_counts()

iris.data   iris.feature_names    iris.target     iris.target_names   모두 성립한다.

label은 뭔가 범주형 변수의 느낌이다. 더 찾아보기

 

*데이터 분할 함수는 CH.2_4에서 자세히 서술

 

Chapter2.3 _ 프레임워크 익히기

프레임워크란 응용 프로그램을 개발하기 위한 여러 라이브러리나 모듈 등을 효율적으로 사용할 수 있도록 하나로 묶어 놓은 일종의 패키지이다.

 

 

#지도학습

분류 알고리즘 구현 클래스 - Classifier   + 회귀 알고리즘 구현 클래스 - Regressor   = Estimator 클래스

지도 학습의 두 축인 분류_Classifier와 회귀_Regression은 fit( )*과 predict( )**만을 이용해 학습과 예측 결과를 반환

* ML 모델 학습을 위한 메서드** 학습된 모델의 예측을 위한  메서드

 

 

evaluation 함수*   &  GridSearchCV** 는 모두 Estimator를 인자로 받는다.

* 평가 함수 : ex) cross_val_score( )

** 하이퍼 파라미터 튜닝을 지원하는 클래스 

 

#비지도학습

차원 축소, 클러스터링, 피처 추출를 구현한 클래스 역시 fit( )* 과 transform( )** OR fit_transform( )***을 적용

 

* ML과 달리, 입력 데이터의 형태에 맞춰 데이터를 변환하기 위한 사전 구조를 맞추는 메서드** 입력 데이터의 차원 변환, 클러스터링, 피처 추출 등의 실제 작업을 수행하는 메서드

*** 위의 두 내용을 하나로 결합한 메서드 / 사용에 주의가 필요. 개별 사용의 경우와 차이가 있음

 

#주요 모듈

 

** 머신러닝 모델을 구축하는 프로세스 (3단계의 무한 반복...)

 

피처의 가공 / 변경 / 추출 수행 by. feature processing

ML 알고리즘 학습 / 예측 수행

모델 평가

 

#내장된 예제 데이터 세트 (P.94)

_ 회귀, 분류 등 여러 용도로 활용 가능한 내제 데이터를 사용할 수 있다._fetch 계열의 명령은 인터넷에서 내려 받아 사용 가능한 데이터

 

#표본 데이터 생성기

- datasets.make_classifications( ) : 분류를 위한 데이터 세트 생성기- datasets.make_blobs( )   : 클러스터링을 위한 데이터 세트 생성기

 

#기본 용어

data : feature의 data set - ndarray 형target : 분류 시 레이블 값, 회귀 시 숫자 결괏값 data set  - ndarray 형target_names : 개별 레이블의 이름  - ndarray 형 OR list 형feature_names : feature의 이름 - ndarray 형 OR list 형 DESCR : describe - data set에 대한 설명 & 각 feature의 설명 

 

** label을 범주형 변수의 category 정도로 대략 이해해 두자.

 

from sklearn.datasets import load_iris   ## data set 로딩

iris_data = load_iris()
print(type(iris_data))          

keys = iris_data.keys()
print('붓꽃 데이터 세트의 키들 :', keys)
<class 'sklearn.utils._bunch.Bunch'>
붓꽃 데이터 세트의 키들 : dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])

* _bunch.Bunch는 .Bunch 라는 결과와 거의 같다고 할 수 있다. 그러나 약간의 차이가 있음 그건 나중에..! * Bunch - 파이썬의 dictionary 자료형과 유사한 클래스

 

print('\n feature_names의 type: ', type(iris_data.feature_names))
print('\n feature_names의 shape: ', len(iris_data.feature_names))       #feature의 길이를 묻는 내용
print(iris_data.feature_names)

print('\n target_names의 type: ', type(iris_data.target_names))
print('\n target_names의 shape: ', len(iris_data.target_names))       #feature의 길이를 묻는 내용
print(iris_data.target_names)


print('\n data의 type: ', type(iris_data.data))
print('\n data의 shape: ', (iris_data.data.shape))       #feature의 길이를 묻는 내용   - ndarray 여서 shpae
print(iris_data['data'])

print('\n target의 type: ', type(iris_data.target))
print('\n target의 shape: ', (iris_data.target.shape))       #feature의 길이를 묻는 내용   - ndarray 여서 shape
print(iris_data.target)
 feature_names의 type:  <class 'list'>

 feature_names의 shape:  4
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

 target_names의 type:  <class 'numpy.ndarray'>

 target_names의 shape:  3
['setosa' 'versicolor' 'virginica']

 data의 type:  <class 'numpy.ndarray'>

 data의 shape:  (150, 4)

 

Chapter2.4 _ Model Selection 모듈

_데이터 분리, 검증, 파라미터

 

#1 _ 학습 / 테스트 데이터 세트 분리 by. train_test_split( )

 

학습과 테스트 데이터를 구분하지 않을 경우 예측에서 정확하지 않은 결과가 나온다.

 

from sklearn.tree import DecisionTreeClassifier   ## 머신러닝 알고리즘 선택 
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris   ## data set 로딩
from sklearn.model_selection import train_test_split   ## 데이터 셋을 학습/테스트로 분리

dt_clf = DecisionTreeClassifier()
iris_data = load_iris()

X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.3, random_state=121)
##X : 피처 테이터 세트    / y : label 데이터 세트

dt_clf.fit(X_train, y_train)
pred=dt_clf.predict(X_test)
print("예측 정확도 : {0:.4f}".format(accuracy_score(y_test, pred)))
예측 정확도 : 0.9556

 

* 정확도가 높지만 전체 표본이 150개이고, 결과적으로 test data가 45개로 매우 적다.

그러므로 예측 성능을 판단하기에는 섣부르다고 할 수 있다.

 

 

## 데이터 분할 by. train_test_split()

X_train, X_test, y_train, y_test = train_test_split(feature data set = , label data set =, ...)

 

추가 옵션 :

test_size = : test data set의 proportion

train_size = : 학습용 data set의 proportion *잘 사용되지 않음

shuffle = True/False : 데이터를 분산시키기 위해 섞는지 결정

random_state : 호출할 때마다 같은 data set을 생성하기 위해 주어지는 난수 발생 값!

 

return 값 : 튜플

 

 

#2 _ 검증

#교차 검증  = 1차 테스트

test data set만을 이용해 성능을 평가하는 것은 Overfitting_과적합*에 취약함.

*모델이 학습 데이터에만 과도하게 최적화돼, 실제 예측을 다른 데이터로 수행할 경우 예측 성능이 떨어지는 것

-> 이를 해결하기 위한 '교차 검증'

 

교차 검증은 본 test data set을 이용해 성능 평가를 거치기 전, 교차 검증을 통해 여러 번의 알고리즘 학습과 평가를 수행하는 것.

특정 data set에 편중되는 현상을 방지하기 위해, 개별의 data set을 만들어 학습과 평가 수행 -> 해당 결과에 따라 모델 최적화 진행

 

*성능 평가 = 교차 검증 → test data set 에서 검증

 

  1. K-fold 교차 검증 : K개의 data fold set을 생성해서, K번만큼 각 fold 세트에 학습과 검증을 반복적으로 수행
  2. Stratified K-fold : 불균형한 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방법
    • KFold로 분할된 label data set이 전체 label의 분포도를 반영할 수 있도록 해준다.Ex) 1:1:1로 label이 구성됐을 경우, test label의 분포도 비슷하게 이뤄진다.
  3. cross_val_score() : 교차 검증을 편리하게 수행하게 해주는 API → 내부적으로 StratifiedKFold 이용
    • cross_val_score(estimator*, X, y=None, scoring, cv=None, ....)*estimator : Classifier OR Regressor 클래스* X: feature data set     /     y = label data set* scoring = 예측 성능 평가 지표* cv = 교차 검증 폴드 수

* Stratified K-fold_ K-fold가 원본 데이터 집합의 레이블 분포를 학습 및 테스트 데이터에 제대로 분배하지 못하는 경우의 문제를 해결해줌.

* Classification의 교차 검증은 STratified KFold가 적절

*Regression의 경우 Stratified는 부적절함. 결정값이 label이 아닌 연속된 숫자값이기 때문 

K-fold 교차 검증

from sklearn.tree import DecisionTreeClassifier   ## 머신러닝 알고리즘 선택 
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import numpy as np

iris = load_iris()
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=156)     ## DecisionTreeClassifier 객체 생성 

kfold = KFold(n_splits=5)    ##KFOLD의 객체 생성 - split=5라는 조건 설정
cv_accuracy = []

## n_split = 5 : 데이터 세트를 5개로 나누고, 5번 반복하여 학습과 평가를 진행
## cv_accuracy = [] 여기에 kfold를 진행한 정확도를 저장하게 됨. 총 다섯 번 저장된다. 

print('붓꽃 데이터 세트 크기 : ', features.shape[0])

#---------------------------------------------------------------------------

n_iter = 0

for train_index, test_index in kfold.split(features):
    #kfold.split()으로 반환된 인덱스를 이용해 학습용, 검증용 테스트 데이터 추출
    ## kfold.split(features)가 features 데이터를 훈련 데이터와 테스트 데이터의 인덱스로 나눔.
    ## kfold는 KFold(n_splits=5)로 정의되어 있기 때문에, 데이터를 5개의 Fold로 분할
    ## train_index와 test_index는 각 Fold에서의 훈련 데이터 인덱스와 테스트 데이터 인덱스를 반환
    
    X_train, X_test = features[train_index], features[test_index]
    y_train, y_test = label[train_index], label[test_index]
    ## features[train_index]는 훈련용 데이터 X_train을 추출하고, features[test_index]는 테스트용 데이터 X_test를 추출
    ## label[train_index]는 훈련 데이터에 해당하는 라벨 y_train이고, label[test_index]는 검증(테스트) 데이터에 해당하는 라벨 y_test

    dt_clf.fit(X_train, y_train)      #feature와 label 학습
    pred = dt_clf.predict(X_test)     #feature의 label 예상 
    n_iter +=1

    # 반복 시마다 정확도 측정 
    accuracy = np.round(accuracy_score(y_test, pred), 4)   #예상과 실제를 비교
    ## np.round(..., 4): 소수점 넷째 자리까지 반올림하여 정확도를 저장
    
    train_size = X_train.shape[0]
    test_size = X_test.shape[0]
    ## train_size는 훈련 데이터의 크기를 나타내고, test_size는 테스트 데이터의 크기를 나타냄
    
    print("\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}".format(n_iter, accuracy, train_size, test_size))
    print("#{0} 검증 세트 인덱스:{1}".format(n_iter, test_index))
    cv_accuracy.append(accuracy)
    ## accuracy를 cv_accuracy 리스트에 추가하여 각 Fold별 정확도를 저장

print("\n## 평균 검증 정확도:", np.mean(cv_accuracy))
붓꽃 데이터 세트 크기 :  150
#1 교차 검증 정확도 :1.0, 학습 데이터 크기: 120, 검증 데이터 크기: 30
#1 검증 세트 인덱스:[ 0  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]

#2 교차 검증 정확도 :0.9667, 학습 데이터 크기: 120, 검증 데이터 크기: 30
#2 검증 세트 인덱스:[30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 54 55 56 57 58 59]

#3 교차 검증 정확도 :0.8667, 학습 데이터 크기: 120, 검증 데이터 크기: 30
#3 검증 세트 인덱스:[60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
 84 85 86 87 88 89]

#4 교차 검증 정확도 :0.9333, 학습 데이터 크기: 120, 검증 데이터 크기: 30
#4 검증 세트 인덱스:[ 90  91  92  93  94  95  96  97  98  99 100 101 102 103 104 105 106 107
 108 109 110 111 112 113 114 115 116 117 118 119]

#5 교차 검증 정확도 :0.7333, 학습 데이터 크기: 120, 검증 데이터 크기: 30
#5 검증 세트 인덱스:[120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
 138 139 140 141 142 143 144 145 146 147 148 149]

## 평균 검증 정확도: 0.9

 

from sklearn.model_selection import StratifiedKFold

skf = StratifiedKFold(n_splits=3)
n_iter=0

for train_index, test_index in skf.split(iris_df, iris_df['label']):
    n_iter +=1
    label_train = iris_df['label'].iloc[train_index]    ##학습 레이블
    label_test = iris_df['label'].iloc[test_index]      ## 검증 레이
    print("## 교차 검증: {0}".format(n_iter))
    print("학습 레이블 데이터 분포\n: {0}", label_train.value_counts())
    print("검증 레이블 데이터 분포\n: {0}", label_test.value_counts())
## 교차 검증: 1
학습 레이블 데이터 분포
: {0} label
2    34
0    33
1    33
Name: count, dtype: int64
검증 레이블 데이터 분포
: {0} label
0    17
1    17
2    16
Name: count, dtype: int64
## 교차 검증: 2
학습 레이블 데이터 분포
: {0} label
1    34
0    33
2    33
Name: count, dtype: int64
검증 레이블 데이터 분포
: {0} label
0    17
2    17
1    16
Name: count, dtype: int64
## 교차 검증: 3
학습 레이블 데이터 분포
: {0} label
0    34
1    33
2    33
Name: count, dtype: int64
검증 레이블 데이터 분포
: {0} label
1    17
2    17
0    16
Name: count, dtype: int64
from sklearn.tree import DecisionTreeClassifier   ## 머신러닝 알고리즘 선택 
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import numpy as np

iris = load_iris()
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=156)     ## DecisionTreeClassifier 객체 생성 

skfold = StratifiedKFold(n_splits=5)
cv_accuracy = []

## n_split = 5 : 데이터 세트를 5개로 나누고, 5번 반복하여 학습과 평가를 진행
## cv_accuracy = [] 여기에 kfold를 진행한 정확도를 저장하게 됨. 총 다섯 번 저장된다. 

n_iter = 0

for train_index, test_index in skfold.split(features, label):
    
    X_train, X_test = features[train_index], features[test_index]
    y_train, y_test = label[train_index], label[test_index]

    dt_clf.fit(X_train, y_train)
    pred = dt_clf.predict(X_test)
    n_iter +=1

    # 반복 시마다 정확도 측정 
    accuracy = np.round(accuracy_score(y_test, pred), 4)
    ## accuracy_score(y_test, pred): 테스트 데이터의 실제 라벨(y_test)과 예측값(pred)을 비교하여 **정확도(Accuracy)**를 계산합니다.
    ## np.round(..., 4): 소수점 넷째 자리까지 반올림하여 정확도를 저장합니다.
    
    train_size = X_train.shape[0]
    test_size = X_test.shape[0]
    
    print("\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}".format(n_iter, accuracy, train_size, test_size))
    print("#{0} 검증 세트 인덱스:{1}".format(n_iter, test_index))
    cv_accuracy.append(accuracy)
    ## accuracy를 cv_accuracy 리스트에 추가하여 각 Fold별 정확도를 저장합니다.

print("\n## 평균 검증 정확도:", np.round(cv_accuracy,4))
print("\n## 평균 검증 정확도:", np.round(np.mean(cv_accuracy),4))

 

from sklearn.tree import DecisionTreeClassifier   ## 머신러닝 알고리즘 선택 
from sklearn.model_selection import cross_val_score, cross_validate
from sklearn.datasets import load_iris

iris_data = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)

data = iris_data.data
label = iris_data.target

#성능 지표는 정확도, 교차 검증 세트는 3개
scores = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=3)
print("교차 검증별 정확도: ", np.round(scores, 4))
print("평균 검증 정확도: ", np.round(np.mean(scores), 4))

 

#GridSearchCV  _ 교차 검증과 최적 하이퍼 파라미터 튜닝을 한 번에

머신러닝 알고리즘을 구성하는 요소 & 이 값을 조정해 알고리즘의 예측 성능을 개선

 

GridSearchCV API 은 여러 개의 하이퍼 파라미터를 입력하면서 테스트를 통해 최적의 파라미터를 찾아 줌그래서 수행 시간이 오래 걸린다.

 

grid_parameters = {'max_depth':[1,2,3], 'min_sample_split':[2,3]}

>> max_depth와 min_sample_split 에서 하나씩 선택해서 test 진행 → 총 6번의 test>> cv*=3 이라면 6번의 테스트 조합마다 3개의 폴딩 세트 생성 후 test*cross_validation

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV

iris_data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2, random_state=121)

dtree = DecisionTreeClassifier()

parameters = {'max_depth':[1,2,3], 'min_samples_split':[2,3]}

import pandas as pd

#param_grim의 하이퍼 파라미터를 3개의 train, test set fold로 나누어 테스트 수행 설정
## refit=True가 default임. True이면 가장 좋은 파라미터 설정으로 재학습시킴.
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)

##붓꽃 학습 데이터로 param_grid 의 하이퍼 파라미터를 순차적으로 학습/평가
grid_dtree.fit(X_train, y_train)


#GridSearchCV를 dataFrame으로 변환 
scores_df = pd.DataFrame(grid_dtree.cv_results_)
scores_df[['params', 'mean_test_score', 'rank_test_score', 'split0_test_score', 'split1_test_score', 'split2_test_score']] 

 

 

 

Chapter2.5 _ 데이터 전처리 _ Data Preprocessing

결손값_NaN, Null은 불가능

>> 피처 값 중 Null의 비중을 보고 Null 값을 대체하거나, 해당 피처를 드랍해야 한다.

 

머신러닝 알고리즘은 문자열 값을 입력값으로 허용하지 않음

>> 단순히 데이터 로우를 식별하는 용도의 문자열 피처는 삭제하는 것이 좋다.

 

#데이터 인코딩

 

##레이블 인코딩   by. LalbelEncoder 클래스 

카테고리 피처를 코드형 숫자 값으로 변환하는 것

이럴 경우 특정 ML 알고리즘*에서 숫자가 클 수록 가중치가 부여된다. 

*선형 회귀 ML 알고리즘에 해당함. 트리 계열 알고리즘은 제외.

 

from sklearn.preprocessing import LabelEncoder

items=['TV', '냉장고', '전자레인지', '컴퓨터', '선풍기', '선풍기', '믹서', '믹서']

encoder = LabelEncoder()

#fit, transform() 로 레이블 인코딩 수행
encoder.fit(items)
labels = encoder.transform(items)
print('인코딩 변환값:', labels)            # 인코딩 결과값 보여준다.
print('인코딩 클래스:', encoder.classes_)  #인코딩의 원본 클래스 (범주) 확인
print('디코딩 원본값:', encoder.inverse_transform([4,5,2,0,1,1,3,3]))     ##인코딩 해제 = 디코딩
인코딩 변환값: [0 1 4 5 3 3 2 2]
인코딩 클래스: ['TV' '냉장고' '믹서' '선풍기' '전자레인지' '컴퓨터']
디코딩 원본값: ['전자레인지' '컴퓨터' '믹서' 'TV' '냉장고' '냉장고' '선풍기' '선풍기']
 
 
 

##원-핫 인코딩 (One-Hot Encoding)    by.OneHotEncoder 클래스   OR   by. get_dummies( ) 

레이블 인코딩의 가중치 문제를 해결하기 위한 인코딩

입력값으로 2차원 데이터 필요  &  OneHotEncoder를 이용한 변환 결과 값이 희소 행렬(Sparse Matrix)이어야 하고,

toarray( ) 메서드를 이용해 밀집 행렬(Dense Matrix)로 변환해야 한다.

*saprse data는 차원/전체 공간에 비해 데이터가 있는 공간이 매우 협소한 데이터

* dense data는 차원/전체 공간에 비해 데이터가 있는 공간이 빽빽하게 차 있는 데이터

 

원핫인코딩 이미지

 

# OneHotEncoder 클래스

from sklearn.preprocessing import OneHotEncoder
import numpy as np

items=['TV', '냉장고', '전자레인지', '컴퓨터', '선풍기', '선풍기', '믹서', '믹서']
## 1차원 데이터
print(items)

## 2차원 데이터
items = np.array(items).reshape(-1,1)

## 원-핫 인코딩을 적용
oh_encoder = OneHotEncoder()
oh_encoder.fit(items)
oh_labels = oh_encoder.transform(items)

## 희소행렬을 toarray() 를 이용해 밀집 행렬로 변환 
print('원-핫 인코딩 데이터')
print(oh_labels.toarray())
print('원-핫 인코딩 데이터 차원')
print(oh_labels.shape)

 

# 희소 행렬로 변환 _ 1의 위치를 좌표로 표현함

oh_labels = oh_encoder.transform(items) : 결과

(0, 0)	1.0
  (1, 1)	1.0
  (2, 4)	1.0
  (3, 5)	1.0
  (4, 3)	1.0
  (5, 3)	1.0
  (6, 2)	1.0
  (7, 2)	1.0

 

#밀집 행렬로 변환

원-핫 인코딩 데이터
[[1. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0. 0.]
 [0. 0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0.]]
원-핫 인코딩 데이터 차원
(8, 6)

 

# get_dummies() 이용

import pandas as pd

df=pd.DataFrame({'item':['TV', '냉장고', '전자레인지', '컴퓨터', '선풍기', '선풍기', '믹서', '믹서']})
pd.get_dummies(df)

 

#피처 스케일링과 정규화

서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업

 

표준화_Standardization* & 정규화_Normalization*

  • 표준화 : 데이터의 피처 각각을 조정 _ 평균이 0, 분산이 1인 가우시안 정규 분포를 가진 값으로 변환
  • 정규화 : 데이터 피처 간의 크기를 통일하기 위해 크기를 변환
  • 사이킷런의 정규화 : 선형대수의 정규화 개념 _ 개별 벡터의 크기를 맞추기 위해 변환하는 것

표준화

 

정규화

 

 

#StandardScaler _ 표준화 지원 클래스 

개별 피처는 평균=0, 분산=1인 값으로 변환 * RBF 커널을 이용하는 서포트 벡터 머신 & 선형 회귀 & 로지스틱 회귀에서 필수인 과정

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(iris_df)
iris_scaled=scaler.transform(iris_df)

iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print('feature들의 평균 값')
print(iris_df_scaled.mean())
print('\nfeature들의 분산 값')
print(iris_df_scaled.var())

 

#MinMaxScaler _ 

데이터 값을 0-1 사이의 범위 값으로 변환

from sklearn.preprocessing import MinMaxScaler

#MinMaxScaler 객체 생성
scaler = MinMaxScaler()

#MinMaxScaler로 데이터 세트 변환. fit()과 transform() 호출
scaler.fit(iris_df)
iris_scaled=scaler.transform(iris_df)

#transform() 시 스케일 변환된 데이터 세트가 NumPy ndarray로 반환돼 DF로 변환
iris_df_scaled= pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print('feature들의 최솟값')
print(iris_df_scaled.min())
print('\nfeature들의 최댓값')
print(iris_df_scaled.max())
feature들의 최솟값
sepal length (cm)    0.0
sepal width (cm)     0.0
petal length (cm)    0.0
petal width (cm)     0.0
dtype: float64

feature들의 최댓값
sepal length (cm)    1.0
sepal width (cm)     1.0
petal length (cm)    1.0
petal width (cm)     1.0
dtype: float64
 
 

#학습 데이터와 테스터 데이터의 스케일링 변환 시 유의점

Scaler 객체를 이용해 데이터 스케일링 변환 시 fit(), transform(), fit_transform()  메서드를 이용한다. fit( ) _ 기준 정보 설정 / transform() _ 데이터 변환 = fit_transform() _ 옆의 기능 한 번에 수행

 

학습 데이터 세트와 테스트 데이터 세트를 같은 기준 정보(fit()에 의한 기준 정보)로 판단해야 한다.

from sklearn.preprocessing import MinMaxScaler
import numpy as np

train_array=np.arange(0,11).reshape(-1,1)
test_array = np.arange(0,6).reshape(-1,1)

scaler = MinMaxScaler()
scaler.fit(train_array)
train_scaled = scaler.transform(train_array)

print('원본 train_array 데이터 : ', np.round(train_array.reshape(-1),2))
print('Scale된 train_array 데이터 : ', np.round(train_scaled.reshape(-1),2))

test_scaled = scaler.transform(test_array)
print('원본 test_array 데이터 : ', np.round(test_array.reshape(-1),2))
print('Scale된 test_array 데이터 : ', np.round(test_scaled.reshape(-1),2))

 

 

Chapter2.6 _ 실습

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

##NULL 값 확인
titanic_df = pd.read_csv("C:\\Users\\rud92\\Downloads\\train.csv")
titanic_df.head(3)

##레이블 인코딩 
from sklearn.preprocessing import LabelEncoder

def encode_features(dataDF):
    features = ['Cabin', 'Sex', 'Embarked']
    for feature in features:
        le = LabelEncoder()
        le = le.fit(dataDF[feature])
        dataDF[feature]=le.transform(dataDF[feature])

    return dataDF

titanic_df = encode_features(titanic_df)
titanic_df.head()

#----------------------------------------------------------------------------------

##NULL 값 처리 함수
def fillna(df):
    titanic_df['Age'].fillna(titanic_df['Age'].mean(), inplace=True)
    titanic_df['Cabin'].fillna('N', inplace=True)
    titanic_df['Embarked'].fillna('N', inplace=True)
    titanic_df['Fare'].fillna(0, inplace=True)
    return df

##필요없는 피처 탈락
def drop_features(df):
    df.drop(['PassengerID', 'Name', 'Ticket'])
    return df

def format_features(df):
    df['Cabin']=df['Cabin'].str[:1]
    features=['Cabin', 'Sex', 'Embarked']
    for feature in features:
        le=LabelEncoder()
        le.le.fit(df[feature])
        df[feature]=le.transform(df[feature])
    return df

def transform_features(df):
    df=fillna(df)
    df=drop_features(df)
    df=format_features(df)
    return df
   


y_titanic_df = titanic_df['Survived']
X_titanic_df = titanic_df.drop('Survived', axis=1)

X_titanic_df = transform_features(X_titanic_df)

from sklearn.model_selection import train_test_split   ## 데이터 셋을 학습/테스트로 분리
X_train, X_test, y_train, y_test = train_test_split(X_titanic_df, y_titanic_df, test_size=0.2, random_state=11)

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score


dt_clf = DecisionTreeClassifier(random_state=11)
rf_clf = RandomForestClassifier(random_state=11)
lr_clf = LogisticRegression(solver='liblinear')

df_clf.fit(X_train, y_train)
dt_pred = dt_clf.predict(X_test)
print('DecisionTreeClassifier 정확도: {0:.4f}'.format(accuracy_score(y_test, dt_pred)))

rf_clf.fit(X_train, y_train)
rf_pred = rf_clf.predict(X_test)
print('RandomForestClassifier 정확도: {0:.4f}'.format(accuracy_score(y_test, rf_pred)))

lr_clf.fit(X_train, y_train)
lr_pred = lr_clf.predict(X_test)
print('LogisticRegression 정확도: {0:.4f}'.format(accuracy_score(y_test, lr_pred)))



import sklearn.model_selection import KFold

def exec_kfold(clf, folds=5):
    kfold = KFold(n_splits=folds)
    scores=[]

    for iter_count, (train_index, test_index) in enumerate(kfold.split(X_titanic_df)):
        X_train, X_test = X_titanic_df.values[train_index], X_titanic_df.values[test_index]
        y_train, y_test = y_titanic_df.values[train_index], y_titanic_df.values[test_index]

        clf.fit(X_train, y_train)
        predictions=clf.predict(X_test)
        accuracy=accuracy_score(y_test, predictions)
        scores.append(accuracy)
        print("교차 검증 {0} 정확도 : {1:.4f}".format(iter_count, accuracy))

    mean_score = np.mean(scores)
    print("평균 정확도 : {0:.4f}".format(mean_score))

exec_kfold(dt_clf, folds=5)


from sklearn.model_selection import cross_val_score

scores=cross_val_score(df_clf, X_titanic_df, y_titanic_df, cv=5)

for iter_count, accuracy in enumerate(scores):
    print("교차검증 : {0} 정확도 : {1:.4f}".format(iter_count, accuracy))

print("평균 정확도 : {0:4f}".format(np.mean(scores)))



from sklearn.model_selection import GridSearchCV

parameters = {'max_depth':[2,3,5,10], 'min_samples_split':[2,3,5], 'min_samples_leaf':[1,5,8]}

grid_dclf = GridSearchCV(dt_clf, param_grid=parameters, scoring='accuracy', cv=5)
grid_dclf.fit(X_train, y_train)

print('GridSearchCV 최적 하이퍼 파라미터 : ', grid_dclf.best_params)
print('GridSearchCV 최고 정확도 : {0:.4f}'.format(grid_dclf.best_score_))
best_dclf = grid_dclf.best_estimator_

dpredictions = best_dclf.predict(X_test)
accuracy = accuracy_score(y_test, dpredictions)
print('테스트 세트에서의 DecisionTreeClassifier 정확도 : {0:.4f}'.format(accuracy))

 

 

 

[출처] 머신 러닝 그리고 희소 데이터(sparse data)와 밀집 데이터(dense data)|작성자 예비개발자