1. 학습 데이터와 검증 데이터 분리
trains_test_split()
- return 값: tuple 형태로 4개의 데이터 세트가 반환(X_train, X_test, y_train, y_test)
- option
test_size: (default:0.25)
train_size: (normally not used)
shuffle: (default:True)
random_state: default로 계속 바뀜, 동일한 출력결과를 얻고 싶으면 state를 적어주는게 좋음
교차 검증
학습 데이터와 검증 데이터 세트를 여러 세트로 구성
K 폴드 교차 검증
K개의 데이터 폴드 세트를 만들고 K번 만큼(학습 K-1개의 세트, 검증 1개의 세트를 바꿔가면서) 반복적으로 수행
특정 검증 데이터에 overfit되는 경우를 방지하기 위한 목적
from sklearn.model_selection import KFold
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=156)
kfold = KFold(n_splits=5)
cv_accuracy=[]
for train_index, test_index in kfold.split(features):
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_text)
accuracy = np.round(accuracy_score(y_test,pred),4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
cv_accuracy.append(accuracy)
print(np.mean(cv_accuracy))
Stratified K 폴드
불균형한 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방식
분류에서 사용하고 회귀에서는 지원 X(회귀는 레이블이 아니라 숫자값이기 때문에 분포가 의미 X)
from sklearn.model_selection import StratifiedKFold
dt_clf = DecisionTreeClassifier(random_state=156)
skfold = StratifiedKFold(n_splits=3)
cv_accuracy=[]
for train_index,test_index in skfold.split(features,label):
label_train = iris_df['label'].iloc[train_index]
label_test = iris_df['label'].iloc[test_index]
print(label_train.value_counts())
print(label_test.value_counts())
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)
accuracy = np.round(accuracy_score(y_test,pred),4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print(accuracy,train_size,test_size)
cv_accuracy.append(accuracy)
print(np.round(cv_accuracy,4))
print(np.mean(cv_accuracy))
cross_val_score()
분류인 경우 stratified K 폴드, 회귀인 경우 K 폴드 방식 적용
cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch'2*n_jobs')
- return 값: 성능 지표 측정값을 배열 형태로 반환
- option
estimator: Classifier(분류) 또는 Regressor(회귀)
X: feature dataset
y: label dataset
scoring: 성능 평가 지표
cv: 교차 검증 폴드 수
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
scores = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=3)
print(np.round(scores,4))
print(np.round(np.mean(scores),4))
2. GridSearchCV
교차 검증과 최적 하이퍼 파라미터 튜닝을 한번에 해주는 function
refit: (default:True) True이면 가장 좋은 파라미터 설정으로 재 학습시킴
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
import pandas as pd
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=121)
dtree = DecisionTreeClassifier()
parameters = {'max_depth':[1,2,3], 'min_samples_split':[2,3]}
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)
grid_dtree.fit(X_train, y_train)
scores_df = pd.DataFrame(grid_dtree.cv_results_)
scores_df[['params','mean_test_score','rank_tree_score','split0_test_score','split1_test_score','split2_test_score']]
print(grid_dtree.best_params_)
print('{0:.4f}'.format(grid_dtree,best_score_))
estimator = grid_dtree.best_estimator_
pred = estimator.predict(X_test)
print('{0:.4f}'.format(accuracy_score(y_test,pred)))
3. 데이터 전처리
결손값(NaN,Null)값은 허용되지 않기 때문에 다른 값으로 변환해야함
=> 평균값으로 처리하거나 결손값이 대부분이면 드롭하는 방법이 더 좋으나 기준을 정하기 어려운 문제가 있음
문자열 값을 입력값으로 허용하지 않기 때문에 숫자형으로 변형해야 한다.
=> 카테고리형 피처는 코드값으로 표현하고 텍스트형 피처는 피처 벡터화 등의 기법으로 벡터화 하거나 불필요하면 삭제
데이터 인코딩
레이블 인코딩
숫자로 변환되기 때문에 순서나 중요도로 인식되는 알고리즘에 적용되어서는 안됨
선형 회귀 같은 알고리즘에 적용되면 안되고 트리 계열의 ML 알고리즘에는 괜찮음
from sklearn.preprocessing import LabelEncoder
items = ['TV','냉장고','전자레인지','컴퓨터','선풍기','선풍기','믹서','믹서']
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
print(labels) #[0 1 4 5 3 3 2 2]
print(encoder.classes_) #['TV' '냉장고' '믹서' '선풍기' '전자레인지' '컴퓨터']
print(encoder.inverse_transform([4,5,2,0,1,1,3,3])) #['전자레인지' '컴퓨터' '믹서' ....]
원핫 인코딩
from sklearn.preprocessing import OneHotEncoder
import numpy as np
items = ['TV', '냉장고', '전자레인지', '컴퓨터', '선풍기', '선풍기', '믹서', '믹서']
encoder=LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
labels = labels.reshape(-1,1)
oh_encoder = OneHotEncoder()
oh_encoder.fit(labels)
oh_labels = oh_encoder.transform(labels)
print(oh_labels.toarray())
print(oh_labels.shape)
# pandas를 활용한 방법
import pandas as pd
df = pd.DataFrame({'item':['TV','냉장고', '전자레인지','컴퓨터','선풍기','선풍기','믹서','믹서']})
pd.get_dummies(df)
피처 스케일링과 정규화
서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업을 피처 스케일링이라고 하며 대표적인 방법으로 표준화와 정규화가 있음
StandardScaler
표준화는 데이터의 피처 각각이 평균이 0이고 분산이 1인 가우시안 정규 분포를 가진 값으로 변환
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import pandas as pd
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data=iris_data, columns = iris.feature_names)
print(iris_df.mean())
print(iris_df.var())
scaler = StandardScaler()
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df) # ndarray를 return
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print(iris_df_scaled.mean())
print(iris_df_scaled.var())
MinMaxScaler
정규화는 모두 최소 0 ~ 최대 1의 값으로 변환
사이킷 런에서는 선형대수에서의 정규화 개념이 적용되어 개별 벡터의 크기를 맞추는 변환임(개념은 위와 비슷)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(iris_df)
iris_scaled = scaler.transform(iris_df)
iris_df_scaled = pd.DataFrame(data=iris_scaled, columns=iris.feature_names)
print(iris_df_scaled.min())
print(iris_df_scaled.max())
학습 데이터와 테스트 데이터의 스케일링 변환 시 유의점
fit은 데이터 변환을 위한 기준 설정, transform은 이 정보를 이용해 실제로 데이터를 변환한다.
학습 데이터와 테스트 데이터는 같은 fit 정보로 transform 해야된다.
'Data Science' 카테고리의 다른 글
회귀 (0) | 2020.10.07 |
---|---|
분류 (0) | 2020.10.06 |
사이킷런(scikit-learn) (0) | 2020.08.14 |
Numpy, Pandas (0) | 2020.08.14 |
Day 1. Intro To Machine Learning (0) | 2020.07.28 |