데이터 필드에 결측치 값 np.NaN 존재하는 경우
결측치를 보완하는 인스턴스 객체를 활용
import numpy as np
data_origin = [[30, 100], [20, 50], [35, np.nan],
[25, 80], [30, 70], [40, 60]]
data_origin
[[30, 100], [20, 50], [35, nan], [25, 80], [30, 70], [40, 60]]
import numpy as np
data_origin = [[30, np.nan], [20, 50], [35, np.nan],
[25, 80], [30, np.nan], [40, 60]]
data_origin
[[30, nan], [20, 50], [35, nan], [25, 80], [30, nan], [40, 60]]
# 보간법 1 : 평균값으로 결측값을 대체
from sklearn.preprocessing import Imputer
imp_mean = Imputer(missing_values='NaN', strategy='mean')
imp_mean.fit(data_origin)
data_mean_imp = imp_mean.transform(data_origin)
print(data_mean_imp)
[[30. 63.33333333] [20. 50. ] [35. 63.33333333] [25. 80. ] [30. 63.33333333] [40. 60. ]]
# 보간법 2 : 중간값으로 결측값을 대체
imp_median = Imputer(missing_values='NaN', strategy='median')
imp_median.fit(data_origin)
data_median_imp = imp_median.transform(data_origin)
print(data_median_imp)
[[30. 60.] [20. 50.] [35. 60.] [25. 80.] [30. 60.] [40. 60.]]
# 보간법 3 : 새로운 데이터에 보간법 적용
new = [[20, np.nan],
[30, np.nan],
[np.nan, 70],
[np.nan, np.nan]]
new_mean_imp = imp_mean.transform(new)
print(new_mean_imp)
[[20. 63.33333333] [30. 63.33333333] [30. 70. ] [30. 63.33333333]]
# 불완전한 당뇨질환 데이터를 불러온다
from sklearn import datasets
dataset = datasets.load_diabetes()
X_full, y = dataset.data, dataset.target
# 25% 의 결측치를 OverWriting 한다
m, n = X_full.shape
m_missing = int(m * 0.25)
print("전체 데이터 Index : {:,}\n결측 데이터 Index : {:,}".format(m, m_missing))
전체 데이터 Index : 442 결측 데이터 Index : 110
# m_missing 갯수의 데이터를 무작위로 추출한다
np.random.seed(42)
missing_samples = np.array([True] * m_missing + [False] * (m - m_missing))
np.random.shuffle(missing_samples)
# 결측 데이터에 대해 1개의 feature를 무작위로 선택한다
missing_features = np.random.randint(low=0, high=n, size=m_missing)
# nan 로 결측값을 변경한다
X_missing = X_full.copy()
X_missing[np.where(missing_samples)[0], missing_features] = np.nan
# 결측값이 포함된 샘플은 제외한다
X_rm_missing = X_missing[~missing_samples, :]
y_rm_missing = y[~missing_samples]
# 결측값이 제거된 DataSet의 R^2 추정치를 계산한다
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
regressor = RandomForestRegressor(random_state = 42,
max_depth = 10,
n_estimators = 100)
score_rm_missing = cross_val_score(
regressor, X_rm_missing, y_rm_missing).mean()
print('결측값이 제거된 DataSet 의 R^2 : {0:.2f}'.format(score_rm_missing))
/home/markbaum/Python/python/lib/python3.6/site-packages/sklearn/ensemble/weight_boosting.py:29: DeprecationWarning: numpy.core.umath_tests is an internal NumPy module and should not be imported. It will be removed in a future NumPy release. from numpy.core.umath_tests import inner1d
결측값이 제거된 DataSet 의 R^2 : 0.39
# Imputation with mean value
imp_mean = Imputer(missing_values='NaN', strategy='mean')
X_mean_imp = imp_mean.fit_transform(X_missing)
# Estimate R^2 on the data set with missing samples removed
regressor = RandomForestRegressor(random_state=42, max_depth=10, n_estimators=100)
score_mean_imp = cross_val_score(regressor, X_mean_imp, y).mean()
print('Score with the data set with missing values replaced by mean: {0:.2f}'.format(score_mean_imp))
Score with the data set with missing values replaced by mean: 0.42
# Estimate R^2 on the full data set
regressor = RandomForestRegressor(random_state = 42,
max_depth = 10,
n_estimators = 500)
score_full = cross_val_score(regressor, X_full, y).mean()
print('Score with the full data set: {0:.2f}'.format(score_full))
Score with the full data set: 0.44
위의 단계에서 데이터Set 을 잘 준비했다면
데이터중 중요한 일부를 추출하는 과정 으로, 모든경우 정확도를 높이진 않는다
sklearn 데이터 불러오기
# 손으로 작성한 DataSet을 불러온다
from sklearn.datasets import load_digits
dataset = load_digits()
X, y = dataset.data, dataset.target
print(X.shape)
(1797, 64)
# 64차원 원본 데이터의 정확도를 측정한다
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
classifier = SVC(gamma=0.005)
score = cross_val_score(classifier, X, y).mean()
print('Score with the original data set: {0:.2f}'.format(score))
Score with the original data set: 0.88
Random Forest 로 작업 후, 중요도 스코어를 기준으로 정렬한다
# Feature selection with random forest
from sklearn.ensemble import RandomForestClassifier
random_forest = RandomForestClassifier(n_estimators=100, criterion='gini', n_jobs=-1)
random_forest.fit(X, y)
# Sort features based on their importancies
feature_sorted = np.argsort(random_forest.feature_importances_)
# Select different number of top features
K = [10, 15, 25, 35, 45]
for k in K:
top_K_features = feature_sorted[-k:]
X_k_selected = X[:, top_K_features]
# Estimate accuracy on the data set with k selected features
classifier = SVC(gamma=0.005)
score_k_features = cross_val_score(classifier, X_k_selected, y).mean()
print('Score with the data set of top {0} features: {1:.2f}'.format(k, score_k_features))
Score with the data set of top 10 features: 0.84 Score with the data set of top 15 features: 0.93 Score with the data set of top 25 features: 0.94 Score with the data set of top 35 features: 0.92 Score with the data set of top 45 features: 0.88
차원 축소는 Feature Selection과 유사한 장점이 존재한다
from sklearn.decomposition import PCA
N = [10, 15, 25, 35, 45]
for n in N:
pca = PCA(n_components=n)
X_n_kept = pca.fit_transform(X)
# Estimate accuracy on the data set with top n components
classifier = SVC(gamma=0.005)
score_n_components = cross_val_score(classifier, X_n_kept, y).mean()
print('Score with the data set of top {0} components: {1:.2f}'.format(n, score_n_components))
Score with the data set of top 10 components: 0.95 Score with the data set of top 15 components: 0.95 Score with the data set of top 25 components: 0.91 Score with the data set of top 35 components: 0.89 Score with the data set of top 45 components: 0.88
Feature Enginnering 방법중 일반화 내용들을 살펴보자
from sklearn.preprocessing import Binarizer
X = [[4], [1], [3], [0]]
binarizer = Binarizer(threshold=2.9)
X_new = binarizer.fit_transform(X)
print(X_new)
[[1] [0] [1] [0]]
from sklearn.preprocessing import PolynomialFeatures
X = [[2, 4], [1, 3], [3, 2], [0, 3]]
poly = PolynomialFeatures(degree=2)
X_new = poly.fit_transform(X)
print(X_new)
[[ 1. 2. 4. 4. 8. 16.] [ 1. 1. 3. 1. 3. 9.] [ 1. 3. 2. 9. 6. 4.] [ 1. 0. 3. 0. 0. 9.]]
알고리즘에 적합한 튜닝 작업에 소요되는 시간이 많으므로, 아래 중 1~3개를 택해서 시도한다
Bias가 낮고, 분산이 높은 알고리즘으로 L1, L2 둘을 합친 정규화 항으로 OverFitting을 해결한다
데이터를 선형분리하는 모델로, 로지스틱 회귀보다 성능이 좋다
별도의 인코딩 없이도 범주형 feature를 직접 적용가능하다
복잡한 튜닝에 시간을 많이 소요하므로, 처음부터 접근하기엔 용이하지 않은 부분이 많다
알고리즘 적용결과 Over Fitting을 피하기 위해서
데이터 전처리, 파이프라인, 학습 모델을 예측한 뒤 마지막 단계로써
from sklearn import datasets
dataset = datasets.load_diabetes()
X, y = dataset.data, dataset.target
num_new = 30 # the last 30 samples as new data set
X_train = X[:-num_new, :]
y_train = y[:-num_new]
X_new = X[-num_new:, :]
y_new = y[-num_new:]
# 정규화 작업후 객체를 저장
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
import pickle
file_name = "./data/scaler.p"
pickle.dump(scaler, open(file_name, "wb" ))
X_scaled_train = scaler.transform(X_train)
print('정규화 작업이 완료된 객체를 {}로 저장'.format(file_name))
정규화 작업이 완료된 객체를 ./data/scaler.p로 저장
# 작업이 완료된 객체로 모델을 학습
from sklearn.svm import SVR
regressor = SVR(C=20)
regressor.fit(X_scaled_train, y_train)
file_name = "./data/regressor.p"
pickle.dump(regressor, open(file_name, "wb"))
print("학습이 완료된 객체를 {}로 저장".format(file_name))
학습이 완료된 객체를 ./data/regressor.p로 저장
# 학습이 완료된 객체를 배포한다
my_scaler = pickle.load(open("./data/scaler.p", "rb" ))
my_regressor = pickle.load(open("./data/regressor.p", "rb"))
X_scaled_new = my_scaler.transform(X_new)
predictions = my_regressor.predict(X_scaled_new)
객체들이 제대로 돌아가는지를 확인한다
# Monitor
from sklearn.metrics import r2_score
print('Health check on the model, R^2: {0:.3f}'.format(r2_score(y_new, predictions)))
Health check on the model, R^2: 0.613
성능에 따라서 패턴이 달라진경우에는 모니터링 결과를 통해서 업데이트를 판단하여 재학습 한다