Scikit-learn
1. 머신러닝 단계에 포함되어야 할 사항
Hold out
: Training, Test Split- 데이터가 많다는 가정 하에 수행
- 데이터가 작다면 Cross Validation 사용, stratify 사용해서 y값 비율 맞춤
EDA
: Split 전 합친 데이터로오버피팅 방지
- 데이터 추가
- 차원축소 (차원의 저주 막기 위함)
- Feature selection
- Ensemble
2. Hold out
iris 데이터를 가져와보자.
from sklearn.datasets import load_iris
import pandas as pd
data = load_iris()
iris = pd.DataFrame(data.data, columns=data.feature_names)
iris['target'] = data.target
sklearn은 train_test_split
이라는 Hold out 방식을 제공하며, stratify를 사용해 y값의 비율을 맞춰줄 수 있다. 데이터 양이 많다면 큰 문제 없지만 데이터가 작다면 stratify를 사용해주는 것이 좋다.
from sklearn.model_selection import train_test_split
train, test = train_test_split(iris, stratify=iris.target)
실제로는 다음과 같은 방식으로 많이 사용할 것이다.
X_train, X_test, y_train, y_test = train_test_split(iris.iloc[:, :-1], iris.iloc[:,-1])
3. 모델 성능 비교
사이킷런의 교차검증
은 cross_val_score로 쉽게 반복할 수 있다.
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier
cross_val_score(KNeighborsClassifier(), X_train, y_train, cv=10, n_jobs=-1)
# (회귀분석모형, 독립변수 데이터, 종속변수 데이터, cv=교차검증 생성기 객체 or 숫자)
Classification
모델에서는 accuracy를 주로 사용하며, Regression
모델에서는 r2_score를 주로 사용한다.
# 분류의 다양한 스코어링 기법 체크
from sklearn.metrics import classification_report
classification_report(y_true, y_pred)
4. DummyClassifier
DummyClassifier를 사용한다면 기계학습을 쓰지 않을 수도 있다. 단, testset이 작아 편차가 크면 할 때마다 성능은 다르게 나올 수 있다.
from sklearn.dummy import DummyClassifier
du = DummyClassifier()
du.fit(X_train, y_train)
du.score(X_test, y_test)
5. Encoding
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(X_train, y_train) # ValueError
현재 인코딩이 되지 않은 상태이기 때문에 에러가 발생한다.
(1) 판다스에서 Encoding
label encoding
다음과 같이 map을 활용해 라벨인코딩할 수 있다.
iris.species.map({'virginica':0, 'setosa':1, 'versicolor':2})
카테고리 type으로 만들어 라벨인코딩하는 것도 가능하다.
iris.species = iris.species.astype('category')
iris.species.cat.codes
one-hot encoding
# 방법 1
iris.species.str.get_dummies()
# 방법 2
pd.get_dummies(iris.species)
(2) Scikit-learn에서 Encoding
label encoding
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit_transform(iris.species)
le.inverse_transform([2])
inverse_transform 기능은 사이킷에서만 지원하는 기능으로, 인코딩한 결과를 반대로 이야기해준다.
le.fit_transform(iris[['species']])
위의 코드처럼 Fancy Indexing을 할 경우 1차원으로 넣어달라고 Warning이 발생한다. 1차원으로 넣어주자.
one-hot encoding
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder()
ohe.fit_transform(iris[['species']]).toarray()
OneHotEncoder는 반대로 2차원으로 넣어줘야 에러가 발생하지 않으며 toarray()까지 해줘야 값이 제대로 나올 수 있다.
6. Learning Curve
from sklearn.model_selection import learning_curve
import sklearn_evaluation
train_size,train_score,test_score = learning_curve(KNeighborsClassifier(), iris.iloc[:, :-1], iris.species, cv=10)
sklearn_evaluation.plot.learning_curve(train_score, test_score, train_size)
train_score는 train 가지고만 한 것으로 언더피팅을 확인하기 위해 사용한다.
해당 그래프는 iris 데이터를 활용해서 learning curve가 괜찮게 나온 상태이다. 만약 cross-validataion score가 계속 올라가지 않고 떨어지거나 한다면 문제가 있다고 판단할 수 있다.
7. 하이퍼파라미터 찾기
- GridSearchCV
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
knn = KNeighborsClassifier()
grid = GridSearchCV(KNeighborsClassifier(), {'n_neighbors':range(2,20)}, cv=10)
# 파라미터들은 knn.get_params()으로 확인
grid.fit(iris.iloc[:,:-1], iris.iloc[:, -1])
pd.DataFrame(grid.cv_results_).T
grid.best_params_
grid.best_index_
grid.best_score_
Leave a comment