실습
붓꽃 데이터 불러오기
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
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
iris_df.head(3)
X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size = 0.2, random_state = 11)
df_clf = DecisionTreeClassifier(random_state=11)
df_clf.fit(X_train, y_train)
pred = df_clf.predict(X_test)
from sklearn.metrics import accuracy_score
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test, pred)))
예측 정확도: 0.9333
데이터셋 생성
from skelarn.datasets import load_iris
iris_data = load_iris()
print(type(iris_data))
<class 'sklearn.utils._bunch.Bunch'>
keys = iris_data.keys()
print('붗꽃 데이터 세트의 키들:', keys)
붗꽃 데이터 세트의 키들: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
print('\\n feature_manes 의 type:', type(iris_data.feature_names))
print(' feature_names의 shape:', len(iris_data.feature_names))
print(iris_data.feature_names)
print('\\n traget_names의 type:', type(iris_data.target_names))
print(' feature_names 의 shpae:', len(iris_data.target_names))
print(iris_data.target_names)
print('\\n data 의 type:', type(iris_data.data))
print(' data의 shape:', iris_data.data.shape))
print(iris_data['data'])
print('\\n target 의 type:', type(iris_data.target))
print(' target 의 shape:', iris_data.target.shape)
print(iris_data.target)
학습 데이터와 테스트 데이터
학습 데이터 세트
- 머신러닝 알고리즘의 학습을 위해 사용
- 데이터의 속성들과 결정값(레이블)값 모두를 가지고 있음
- 학습 데이터를 기반으로 머신러닝 알고리즘이 데이터 속성과 결정값의 패턴을 인지하고 학습
테스트 데이터 세트
- 테스트 데이터 세트에서 학습된 머신러닝 알고리즘을 테스트
- 테스트 데이터는 속성 데이터만 머신러닝 알고리즘에 제공하며, 머신러닝 알고리즘은 제공된 데이터를 기반으로 결정값을 예측
- 테스트 데이터는 학습 데이터와 별도의 데이터 세트로 제공되어야 함.
코드
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from skelarn.datasets import load_iris
from sklearn.model_selection import train_test_split
dt_clf = DecisinoTreeClassifier()
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)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예츨 정확도: {0:.4f}'.format(accuracy_score(y_test, pred)))
교차 검증
- 학습 데이터를 다시 분할하여 학습 데이터와 학습된 모델의 성능을 일차 평가하는 검증 데이터로 나눔
- 모든 학습/검증 과정이 완료된 후 최종적으로 성능을 평가하기 위한 데이터 세트
- 일반적인 ML모델은 1차 평가 후 최종 테스트 데이터 세트에 적용 후 평가
K 폴드 교차 검증
- 일반 k 폴드
- Stratified K 폴드
- 불균형한 분포도를 가진 레이블(결정 클래스) 데이터 집합을 위한 K폴드 방식
- 학습 데이터와 검증 데이터 세트가 가지는 레이블 분포도가 유사하도록 검증 데이터 추출
예제
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)
kfold = KFold(n_splits = 5)
cv_accuracy = []
print('붓꽃 데이터 세트 크기: ', features.shape[0])
n_iter = 0
# KFold객체의 split( ) 호출하면 폴드 별 학습용, 검증용 테스트의 로우 인덱스를 array로 반환
for train_index, test_index in kfold.split(features):
# kfold.split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
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)
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)
# 개별 iteration별 정확도를 합하여 평균 정확도 계산
print('\\n## 평균 검증 정확도:', np.mean(cv_accuracy))
Stratified K 폴드
import pandas as pd
iris = load_iris()
iris_df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
iris_df['label']=iris.target
iris_df['label'].value_counts()
0 50
1 50
2 50
Name: label, dtype: int64
kfold = KFold(n_splits=3)
# kfold.split(X)는 폴드 세트를 3번 반복할 때마다 달라지는 학습/테스트 용 데이터 로우 인덱스 번호 반환.
n_iter =0
for train_index, test_index in kfold.split(iris_df):
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', label_train.value_counts())
print('검증 레이블 데이터 분포:\\n', label_test.value_counts())
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', label_train.value_counts())
print('검증 레이블 데이터 분포:\\n', label_test.value_counts())
dt_clf = DecisionTreeClassifier(random_state=156)
skfold = StratifiedKFold(n_splits=3)
n_iter=0
cv_accuracy=[]
# StratifiedKFold의 split( ) 호출시 반드시 레이블 데이터 셋도 추가 입력 필요
for train_index, test_index in skfold.split(features, label):
# split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
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)
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)
# 교차 검증별 정확도 및 평균 정확도 계산
print('\\n## 교차 검증별 정확도:', np.round(cv_accuracy, 4))
print('## 평균 검증 정확도:', np.mean(cv_accuracy))
cross_val_socre() → kfold보다 쉬운데 같은 성능
KFold 클래스를 이용한 교차 검증 방법
- 폴드 세트 설정
- For 루프에서 반복적으로 학습/검증 데이터 추출 및 학습과 예측 수행
- 폴드 세트별로 예측 성능을 평균하여 최종 성능 평가
⇒ cross_val_score() 함수로 폴드 세트 추출, 학습/예측, 평가를 한번에 수
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
# 성능 지표는 정확도(accuracy) , 교차 검증 세트는 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를 이용해 Classifier나 REgressor와 같은 알고리즘에 사용되는 하이퍼 파라미터를 순차적으로 입력하면서 편리하게 최적의 파라미터를 도출할 수 있는 방안을 제공합니다.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
# 데이터를 로딩하고 학습데이타와 테스트 데이터 분리
iris = 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()
### parameter 들을 dictionary 형태로 설정
parameters = {'max_depth':[1,2,3], 'min_samples_split':[2,3]}
import pandas as pd
# param_grid의 하이퍼 파라미터들을 3개의 train, test set fold 로 나누어서 테스트 수행 설정.
### refit=True 가 default 임. True이면 가장 좋은 파라미터 설정으로 재 학습 시킴.
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)
# 붓꽃 Train 데이터로 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']]
print('GridSearchCV 최적 파라미터:', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dtree.best_score_))
# GridSearchCV의 refit으로 이미 학습이 된 estimator 반환
estimator = grid_dtree.best_estimator_
# GridSearchCV의 best_estimator_는 이미 최적 하이퍼 파라미터로 학습이 됨
pred = estimator.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
테스트 데이터 세트 정확도: 0.9667
데이터 전처리
- 데이터 클린징
- 결측치 처리
- 데이터 인코딩(레이블, 원-핫 인코딩)
- 데이터 스케일링
- 이상치 제거
- Feature 선택, 추출 및 가공
- 데이터 전처리는 알고리즘 만큼 중요. (Garbage in, Garbage out)
- 데이터는 문자열을 입력 값으로 허용 하지 않는다.
- 문자열을 인코딩하여 숫자로 변화 feature vectorization 기법
데이터 인코딩
- 레이블 인코딩 (Label encoding) 과 원 핫 인코딩(One Hot encoding)
Lable encoding
from sklearn.preprocessing import LabelEncoder
items = ['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']
# LabelEncoder 를 객체로 생성한 후, fit()과 transforem()으로 label 인코딩 수행
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]))
디코딩 원본 값: ['전자렌지' '컴퓨터' '믹서' 'TV' '냉장고' '냉장고' '선풍기' '선풍기']
원-핫 인코딩
피처값에 새로운 피처를 추가 후 고유값에 해당되는 칼럼에 1표시 하고 나머지는 0 표시 하는 방식
from sklearn.preprocessing import OneHotEncoder
import numpy as np
items = ['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']
# 먼저 숫자값으로 변환을 위해 LabelEncoder로 변환합니다.
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
#2차원 데이터로 변환합니다.
labels = labels.reshape(-1,1)
# 원-핫 인코딩을 적용합니다.
oh_encoder = OneHotEncoder()
oh_encoder.fit(labels)
oh_labels = oh_encoder.transform(labels)
print('원-핫 인코딩 데이터')
print(oh_labels.toarray())
print('원-핫 인코딩 데이터 차원')
print(oh_labels.shape)
판다스에서 지원하는 원-핫 인코딩 API get_dummies()
import pandas as pd
df = pd.DataFrame({'item':['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']})
pd.get_dummies(df)
피쳐 스케일링과 정규화
서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업 : feature scaling -> 표준화 (Standardization)와 정규화 (Normalization)
표준화 : 평균이 0 이고 분산이 1인 Gaussian distribution으로 변환
- 정규화 : 서로 다른 피처의 크기를 통일하기 위해 크기를 변환하는 개념.
- 사이킷 런의 Normalizer모듈은 선형대수에서의 정규화 개념이 적용, 개별 벡 터의 크기를 맞추기 위해 변환
StandardScaler
- 평균이 0이고, 분산이 1인 정규 분포 형태로 변환
from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
iris_data = iris.data
iris_df = pd.DataFrame(data = iris_data, columns = iris.feature_names)
print('feature 들의 평균 값')
print(iris_df.mean())
print('\\nfeature 들의 분산 값')
print(iris_df.var())
표준화 후 평균값과 분산 reconfirm
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('featur 들의 평균 값')
print(iris_df_scaled.mean())
print('\\nfeature들의 분산 값')
print(iris_df_scaled.var())
MinMaxScaler
- 데이터 값을 0과 1사이의 범위 값으로 변환합니다.(음수 값이 있으면 -1에서 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('feature들의 최소 값')
print(iris_df_scaled.min())
print('\\nfeature들의 최대 값')
print(iris_df_scaled.max())
결론 ( 순서 )
머신 러닝 지도 학습 프로세스
데이터 전처리 (데이터 클린징, Null처리, 데이터 인코딩, 스케일링, 이상치 제거
→ 데이터 세트 분리 (학습/테스트 데이터 분리)
→ 모델 학습 및 검증 평가 (알고리즘 학습, 교차검증, corss_val_score, GridSearch CV)
→ 예측 수행 (테스트 데이터로 예측 수행)
→ 평가 (예측 평가)
'빅데이터 분석가 양성과정 > Python - 머신러닝' 카테고리의 다른 글
머신러닝 평가 ( 2 ) (2) | 2024.07.11 |
---|---|
머신러닝 평가 ( 1 ) (0) | 2024.07.11 |
실습 - 타이타닉 생존자 ML 예측 구현 (0) | 2024.07.11 |
사이킷 런(scikit-learn) 개요 (0) | 2024.07.11 |
Machine learning (ML) (0) | 2024.07.11 |