Note
λ¨Έμ λ¬λμ λ°μ΄ν° κ°κ³΅/λ³ν, λͺ¨λΈ νμ΅/μμΈ‘, κ·Έλ¦¬κ³ νκ°(Evaluation)μ νλ‘μΈμ€λ‘ ꡬμ±
λ¨Έμ λ¬λ λͺ¨λΈμ μ¬λ¬ κ°μ§ λ°©λ²μΌλ‘ μμΈ‘ μ±λ₯μ νκ°ν μ μμ
μ±λ₯ νκ° μ§ν(Evaluation Metric)λ μΌλ°μ μΌλ‘ λͺ¨λΈμ΄ λΆλ₯λ νκ·λμ λ°λΌ μ¬λ¬ μ’ λ₯λ‘ λλ¨
νκ·μ κ²½μ° λλΆλΆ μ€μ κ°κ³Ό μμΈ‘κ°μ μ€μ°¨ νκ· κ°μ κΈ°λ°
- μλ₯Ό λ€μ΄ μ€μ°¨μ μ λκ°μ μμ΄ λ€ νκ· μ€μ°¨λ₯Ό ꡬνκ±°λ μ€μ°¨μ μ κ³± κ°μ 루νΈλ₯Ό μμ΄ λ€ νκ· μ€μ°¨λ₯Ό ꡬνλ λ°©λ² λ±
- κΈ°λ³Έμ μΌλ‘ μμΈ‘ μ€μ°¨λ₯Ό κ°μ§κ³ μ κ·ν μμ€μ μ¬κ°κ³΅ νλ λ°©λ²μ΄ νκ·μ μ±λ₯ νκ° μ§ν μ ν
λΆλ₯μ νκ° λ°©λ²λ μΌλ°μ μΌλ‘λ μ€μ κ²°κ³Ό λ°μ΄ν°μ μμΈ‘ κ²°κ³Ό λ°μ΄ν°κ° μΌλ§λ μ ννκ³ μ€λ₯κ° μ κ² λ°μνλ κ°μ κΈ°λ°νμ§λ§, λ¨μν μ΄λ¬ν μ νλλ§ κ°μ§κ³ νλ¨νλ€κ°λ μλͺ»λ νκ° κ²°κ³Όμ λΉ μ§ μ μμ
λ³Έ μ₯μμλ λΆλ₯μ μ¬μ©λλ μ±λ₯ νκ° μ§νμ λν΄μ μ§μ€μ μΌλ‘ μ€λͺ ν¨
- νΉν 0κ³Ό 1λ‘ κ²°μ κ°μ΄ νμ λλ μ΄μ§ λΆλ₯μ μ±λ₯ νκ° μ§νμ λν΄μ μ§μ€μ μΌλ‘ μ€λͺ !
λΆλ₯μ μ±λ₯ νκ° μ§ν
- μ νλ (Accuracy)
- μ€μ°¨νλ ¬ (Confusion Matrix)
- μ λ°λ (Precision)
- μ¬νμ¨ (Recall)
- F1 μ€μ½μ΄
- ROC곑μ κ³Ό AUC
- λΆλ₯λ κ²°μ ν΄λμ€ κ° μ’
λ₯μ μ νμ λ°λΌ κΈμ /λΆμ κ³Ό κ°μ 2κ°μ κ²°κ΄κ°λ§μ κ°μ§λ μ΄μ§ λΆλ₯μ μ¬λ¬ κ°μ κ²°μ ν΄λμ€ κ°μ κ°μ§λ λ©ν° λΆλ₯λ‘ λλ μ μμ
- κ²°μ ν΄λμ€λ βκ°λ₯ν μ λ΅μ μ§ν©βμ΄κ³ labelμ βκ° λ°μ΄ν°μ μ€μ μ λ΅β
- μμμ μΈκΈν λΆλ₯μ μ±λ₯ μ§νλ μ΄μ§/λ©ν° λΆλ₯ λͺ¨λμ μ μ©λλ μ§νμ΄μ§λ§, νΉν μ΄μ§ λΆλ₯μμ λμ± μ€μνκ² κ°μ‘°νλ μ§ν!
μ μ μ§νκ° λͺ¨λ μ΄μ§ λΆλ₯μμ μ€μν κΉ?
μ νλ (Accuracy)
μ€μ λ°μ΄ν°μμ μμΈ‘ λ°μ΄ν°κ° μΌλ§λ κ°μμ§λ₯Ό νλ¨νλ μ§ν μ¦, μμΈ‘ κ²°κ³Όκ° λμΌν λ°μ΄ν° 건μλ₯Ό μ 체 μμΈ‘ λ°μ΄ν° 건μλ‘ λλ κ°
- μ νλλ μ§κ΄μ μΌλ‘ λͺ¨λΈ μμΈ‘ μ±λ₯μ λνλ΄λ νκ° μ§ν
- νμ§λ§ μ΄μ§ λΆλ₯μ κ²½μ° λ°μ΄ν°μ ꡬμ±μ λ°λΌ ML λͺ¨λΈμ μ±λ₯μ μ곑ν μ μκΈ° λλ¬Έμ μ νλ μμΉ νλλ§ κ°μ§κ³ μ±λ₯μ νκ°νμ§ μμ
κ·Έλ λ€λ©΄ μ νλ μ§νκ° μ΄λ»κ² ML λͺ¨λΈμ μ±λ₯μ μ곑ν κΉ?
- μμ νμ΄νλ μμ μν κ²°κ³Όλ₯Ό 보면 ν κ°μ§ μꡬμ¬μ΄ μκΈΈ μ μμ
- ML μκ³ λ¦¬μ¦μ μ μ©ν ν μμΈ‘ μ νλμ κ²°κ³Όκ° λ³΄ν΅ 80%λμμ§λ§, νμΉκ°μ΄ λ¨μμΈ κ²½μ°λ³΄λ€ μ¬μμΈ κ²½μ°μ μμ‘΄ νλ₯ μ΄ λμκΈ° λλ¬Έμ λ³λ€λ₯Έ μκ³ λ¦¬μ¦μ μ μ© μμ΄ λ¬΄μ‘°κ±΄ μ±λ³μ΄ μ¬μμΈ κ²½μ° μμ‘΄μΌλ‘, λ¨μμΈ κ²½μ° μ¬λ§μΌλ‘ μμΈ‘ κ²°κ³Όλ₯Ό μμΈ‘ν΄λ μ΄μ λΉμ·ν μμΉκ° λμ¬ μ μμ
- λ¨μ§ μ±λ³ 쑰건 νλλ§μ κ°μ§κ³ κ²°μ νλ λ³κ±° μλ μκ³ λ¦¬μ¦λ λμ μ νλλ₯Ό λνλ΄λ μν© λ°μ!
λ€μ μμ μμλ μ¬μ΄ν·λ°μ
BaseEstimatorν΄λμ€λ₯Ό μμλ°μ μλ¬΄λ° νμ΅μ νμ§ μκ³ , μ±λ³μ λ°λΌ μμ‘΄μλ₯Ό μμΈ‘νλ λ¨μνClassifierμμ±
- μ¬μ΄ν·λ°μ
BaseEstimatorλ₯Ό μμλ°μΌλ©΄ Customized ννμ Estimatorλ₯Ό κ°λ°μκ° μμ± κ°λ₯- μ¬κΈ°μ
fit()λ©μλλ μ무κ²λ μν X,predict()λ©μλλ λ¨μνSexfeatureκ° 1μ΄λ©΄ 0, κ·Έλ μ§ μμΌλ©΄ 1λ‘ μμΈ‘
import numpy as np
from sklearn.base import BaseEstimator
class MyDummyClassifier(BaseEstimator):
Β Β # fit( ) λ©μλλ μ무κ²λ νμ΅νμ§ μμ.
Β Β def fit(self, X , y=None):
Β Β Β Β pass
Β Β # predict( ) λ©μλλ λ¨μν Sex featureκ° 1 μ΄λ©΄ 0 , κ·Έλ μ§ μμΌλ©΄ 1 λ‘ μμΈ‘ν¨.
Β Β def predict(self, X):
Β Β Β Β pred = np.zeros((X.shape[0], 1))
Β Β Β Β for i in range (X.shape[0]) :
Β Β Β Β Β Β if X['Sex'].iloc[i] == 1:
Β Β Β Β Β Β Β Β pred[i] = 0
Β Β Β Β Β Β else :
Β Β Β Β Β Β Β Β pred[i] = 1
Β Β Β Β return pred
MyDummyClassifierλ₯Ό μ΄μ©ν΄ μ μ₯μ νμ΄νλ μμ‘΄μ μμΈ‘ μν
- μμμ μ€μ ν λ°μ΄ν° μ μ²λ¦¬ ν¨μ
from sklearn.preprocessing import LabelEncoder
# Null μ²λ¦¬ ν¨μ
def fillna(df):
Β Β df['Age'] = df['Age'].fillna(df['Age'].mean(), inplace=True)
Β Β df['Cabin'] = df['Cabin'].fillna('N', inplace=True)
Β Β df['Embarked'] = df['Embarked'].fillna('N', inplace=True)
Β Β df['Fare'] = df['Fare'].fillna(0, inplace=True)
Β Β return df
# λ¨Έμ λ¬λ μκ³ λ¦¬μ¦μ λΆνμν νΌμ² μ κ±°
def drop_features(df):
Β Β df.drop(['PassengerId', 'Name', 'Ticket'], axis=1, inplace=True)
Β Β 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 dfimport pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# μλ³Έ λ°μ΄ν°λ₯Ό μ¬λ‘λ©, λ°μ΄ν° κ°κ³΅, νμ΅ λ°μ΄ν°/ν
μ€νΈ λ°μ΄ν° λΆν .
titanic_df = pd.read_csv('train.csv')
y_titanic_df = titanic_df['Survived']
X_titanic_df= titanic_df.drop('Survived', axis=1)
X_titanic_df = transform_features(X_titanic_df)
X_train, X_test, y_train, y_test=train_test_split(X_titanic_df, y_titanic_df,
Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β test_size=0.2, random_state=0)
# μμμ μμ±ν Dummy Classifierλ₯Ό μ΄μ©ν΄ νμ΅/μμΈ‘/νκ° μν.
myclf = MyDummyClassifier()
myclf.fit(X_train, y_train)
mypredictions = myclf.predict(X_test)
print('Dummy Classifierμ μ νλλ: {0:.4f}'.format(accuracy_score(y_test, mypredictions)))
>>> Dummy Classifierμ μ νλλ: 0.7877- μ΄λ κ² λ¨μν μκ³ λ¦¬μ¦μΌλ‘ μμΈ‘μ νλλΌλ λ°μ΄ν°μ ꡬμ±μ λ°λΌ μ νλ κ²°κ³Όλ μ½ 78.77%λ‘ κ½€ λμ μμΉκ° λμ¬ μ μκΈ°μ μ νλλ₯Ό νκ° μ§νλ‘ μ¬μ©ν λλ λ§€μ° μ μ€ν΄μΌ ν¨!
- νΉν μ νλλ λΆκ· νν(imbalanced) label κ° λΆν¬μμ ML λͺ¨λΈμ μ±λ₯μ νλ¨ν κ²½μ°, μ ν©ν νκ° μ§νκ° μλ
- μλ₯Ό λ€μ΄ 100κ°μ λ°μ΄ν°κ° μκ³ μ΄ μ€μ 90κ°μ λ°μ΄ν° labelμ΄ 0, λ¨ 10κ°μ λ°μ΄ν° labelμ΄ 1μ΄λΌκ³ νλ€λ©΄ 무쑰건 0μΌλ‘ μμΈ‘ κ²°κ³Όλ₯Ό λ°ννλ ML λͺ¨λΈμ κ²½μ°λΌλ μ νλκ° 90%λ λ¨
MNIST λ°μ΄ν° μΈνΈλ₯Ό λ³νν΄ λΆκ· νν λ°μ΄ν° μΈνΈλ‘ λ§λ λ€μ μ νλ μ§ν μ μ©μ λ¬Έμ μ νμΈ
- MNIST λ°μ΄ν° μΈνΈνΈ 0λΆν° 9κΉμ§μ μ«μ μ΄λ―Έμ§μ ν½μ μ 보λ₯Ό κ°μ§κ³ μμΌλ©°, μ΄λ₯Ό κΈ°λ°μΌλ‘ μ«μ Digitλ₯Ό μμΈ‘νλ λ° μ¬μ©
- μ¬μ΄ν·λ°μ
load_digits()APIλ₯Ό ν΅ν΄ MNIST λ°μ΄ν° μΈνΈ μ 곡 - μλ MNIST λ°μ΄ν° μΈνΈλ label κ°μ΄ 0λΆν° 9κΉμ§ μλ λ©ν° label λΆλ₯λ₯Ό μν κ²μ΄μ§λ§, μ΄κ²μ label=7μΈ κ²λ§ True, λλ¨Έμ§λ λͺ¨λ Falseλ‘ λ³νν΄ μ΄μ§ λΆλ₯ λ¬Έμ λ‘ λ³κ²½

Attention
μ무κ²λ νμ§ μκ³ λ¬΄μ‘°κ±΄ νΉμ ν κ²°κ³Όλ‘ μμΈ‘ κ²°κ³Όλ₯Ό λ°νν΄λ λ°μ΄ν° λΆν¬λκ° κ· μΌνμ§ μμ κ²½μ° λμ μμΉκ° λνλ μ μλ κ²μ΄ μ νλ νκ° μ§νμ λ§Ήμ !
- λΆκ· νν λ°μ΄ν° μΈνΈμ
Dummy Classifierμμ±
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.base import BaseEstimator
from sklearn.metrics import accuracy_score
import numpy as np
import pandas as pd
class MyFakeClassifier(BaseEstimator):
Β Β def fit(self,X,y):
Β Β Β Β pass
Β Β # μ
λ ₯κ°μΌλ‘ λ€μ΄μ€λ X λ°μ΄ν° μ
μ ν¬κΈ°λ§νΌ λͺ¨λ 0κ°μΌλ‘ λ§λ€μ΄μ λ°ν
Β Β def predict(self,X):
Β Β Β Β return np.zeros( (len(X), 1) , dtype=bool)
# μ¬μ΄ν·λ°μ λ΄μ₯ λ°μ΄ν° μ
μΈ load_digits( )λ₯Ό μ΄μ©νμ¬ MNIST λ°μ΄ν° λ‘λ©
digits = load_digits()
print(digits.data)
print("### digits.data.shape:", digits.data.shape)
print(digits.target)
print("### digits.target.shape:", digits.target.shape)