Cài đặt Tunning Hyper Parameter trên sklearn

Machine Learning

Tunning Parameter là gì ???

Với các model bạn đang sử dụng, điều không thể thiếu là các parameter, và tất nhiên là tuỳ thuộc mỗi bài toán cụ thể, số dữ liệu training bạn đang có, sẽ có các parameter thích hợp. Và việc thử nhiều parameter khác nhau là điều đương nhiên cần thiết.
Ví dụ như RandomForest có các parameter như: n_estimators, max_features, max_depth, min_samples_split... Và việc thay đổi giá trị các parameter trên sẽ ảnh hưởng đến độ chính xác của model, công việc của chúng ta là tìm cho bằng được parameter đẹp trai nhất. Chính là việc Tunning HyperParameter.

Grid Search và Random Search

Hôm nay mình sẽ giới thiệu 2 phương pháp chính, giang hồ gọi tên là : Grid Search và Random Search.
Ví dụ chúng ta đang cần tunning với 2 parameter, cùng xem 2 đại hiệp kia sẻ xử lý chúng ra sao nhỉ.
Với Grid Search, giả dụ giá trị của 2 parameter lần lượt từ 0-9. Grid Search sẽ lần lượt ghép từng giá trị của param 1 với param 2 để tính toán độ chính xác của model. Đảm bảo không bỏ sót cặp parameter nào.
Ưu điểm: Diệt nhầm còn hơn bỏ sót, nên thường được ưu tiên lựa chọn.
Nhược điểm: Tuy nhiên đối với các model cần thiết lập nhiều parameter và nhiều giá trị thì việc tunning sẽ mất rất nhiều thời gian, hàng giờ, vài giờ thậm chỉ có thể tính bằng ngày.
Còn với Random Search, đúng như tên gọi, từ những giá trị parameter bạn setting, Random Search sẽ chọn ngẫu nhiên các cặp parameter để tiến hành độ chính xác của model.
Ưu điểm: Random nên sẽ không chạy đủ các trường hợp như Grid Search nên sẽ nhanh hơn đáng kể.
Nhược điểm: được cái lọ thì mất cái chai. Rất dễ bị trường hợp bỏ qua hyper parameter nhất.

Ứng dụng

Cả 2 phương pháp trên đều được scikit-learn hỗ trợ.
Lần này mình sử dụng data Machine Learning Repository từ UCI, thử nghiệm với 2 cách trên. Code trên jupyter notebook với python2.7.

Bước 1: Dowload data

Bộ data này phục vụ trong việc chuẩn đoán ác tính, lành tính với căn bệnh ung thư vú ^^.
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases'
                  '/breast-cancer-wisconsin/wdbc.data', header=None)
df.shape

# (569, 32)

Bước 2: Chia data

Chúng ta cần chia data làm 2 phần feature data và target data.
X_feature = df.loc[:, 2:].values
y_label = df.loc[:, 1].values

X_feature

# array([[  1.79900000e+01,   1.03800000e+01,   1.22800000e+02, ...,
#           2.65400000e-01,   4.60100000e-01,   1.18900000e-01],
#        [  2.05700000e+01,   1.77700000e+01,   1.32900000e+02, ...,
#           1.86000000e-01,   2.75000000e-01,   8.90200000e-02],
#        [  1.96900000e+01,   2.12500000e+01,   1.30000000e+02, ...,
#           2.43000000e-01,   3.61300000e-01,   8.75800000e-02],
#        ..., 
#        [  1.66000000e+01,   2.80800000e+01,   1.08300000e+02, ...,
#           1.41800000e-01,   2.21800000e-01,   7.82000000e-02],
#        [  2.06000000e+01,   2.93300000e+01,   1.40100000e+02, ...,
#           2.65000000e-01,   4.08700000e-01,   1.24000000e-01],
#        [  7.76000000e+00,   2.45400000e+01,   4.79200000e+01, ...,
#           0.00000000e+00,   2.87100000e-01,   7.03900000e-02]])

y_label

# array(['M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M',
#        'M', 'M', 'M', 'M', 'M', 'M', 'B', 'B', 'B', 'M', 'M', 'M', 'M',
#        'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'B', 'M',
#        'M', 'M', 'M', 'M', 'M', 'M', 'M', 'B', 'M', 'B', 'B', 'B', 'B',
#        'B', 'M', 'M', 'B', 'M', 'M', 'B', 'B', 'B', 'B', 'M', 'B', 'M',
#        'M', 'B', 'B', 'B', 'B', 'M', 'B', 'M', 'M', 'B', 'M', 'B', 'M',
#        'M', 'B', 'B', 'B', 'M', 'M', 'B', 'M', 'M', 'M', 'B', 'B', 'B',
#        'M', 'B', 'B', 'M', 'M', 'B', 'B', 'B', 'M', 'M', 'B', 'B', 'B',
Tiếp theo đương nhiên cần chia thành 2 bộ data training và test.
from sklearn.model_selection import train_test_split

# test size: 20%
# random_state: đảm bảo mỗi lần split đều ra output giống nhau.
X_train, X_test, y_train, y_test = train_test_split(
    X_feature, y_label, test_size=0.20, random_state=1
)

Bước 3: Sử dụng default parameter thử tìm độ chính xác của model

Ở bài toán này, mình sử dụng model RandomForest, đương nhiên với các model khác cũng tương tự.
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier

from sklearn.metrics import classification_report

 def model_check(model):
     model.fit(X_train,y_train)
     y_train_pred = classification_report(y_train,model.predict(X_train))
     y_test_pred  = classification_report(y_test,model.predict(X_test))

     print("""【{model_name}】n Train Accuracy: n{train}
           n Test Accuracy:  n{test}""".format(model_name=model.__class__.__name__, train=y_train_pred, test=y_test_pred))

print(model_check(RandomForestClassifier()))

# [RandomForestClassifier]
#      Train Accuracy:
#                  precision    recall  f1-score   support
#
#               B       1.00      1.00      1.00        67
#               M       1.00      1.00      1.00        75
#
#     avg / total       1.00      1.00      1.00       142
#
#
#      Test Accuracy:
#                  precision    recall  f1-score   support
#
#               B       0.89      0.93      0.91        72
#               M       0.93      0.89      0.91        70
#
#     avg / total       0.91      0.91      0.91       142
Độ chính xác khi thử với tập train là 100%, còn với tập test data là 91%, bây giờ chúng ta thử tunning parameter xem có thể tìm ra được model nào tốt hơn không.

Bước 4: Thử với Grid Search

 #Grid search

 from sklearn.grid_search import GridSearchCV

 # use a full grid over all parameters
 param_grid = {"max_depth": [2,3, None],
              "n_estimators":[50,100,200,300,400,500],
              "max_features": [1, 3, 10],
              "min_samples_split": [2, 3, 10],
              "min_samples_leaf": [1, 3, 10],
              "bootstrap": [True, False],
              "criterion": ["gini", "entropy"]}

 forest_grid = GridSearchCV(estimator=RandomForestClassifier(random_state=0),
                 param_grid = param_grid,   
                 scoring="accuracy",  #metrics
                 cv = 3,              #cross-validation
                 n_jobs = 1)          #number of core

 forest_grid.fit(X_train,y_train) #fit

 forest_grid_best = forest_grid.best_estimator_ #best estimator
 print("Best Model Parameter: ",forest_grid.best_params_)

#    [RandomForestClassifier]
#      Train Accuracy: 
#                  precision    recall  f1-score   support
# 
#               B       0.99      0.99      0.99        67
#               M       0.99      0.99      0.99        75
# 
#     avg / total       0.99      0.99      0.99       142
# 
# 
#      Test Accuracy:  
#                  precision    recall  f1-score   support
# 
#               B       0.96      0.89      0.92        72
#               M       0.89      0.96      0.92        70
# 
#     avg / total       0.92      0.92      0.92       142
Kết quả độ chính xác, f1-score đã được cải thiện

Bước 5: Thử với Random Search

#Random search
from sklearn.grid_search import RandomizedSearchCV
from scipy.stats import randint as sp_randint

param_dist = {"max_depth": [3, None],                  #distribution
              "n_estimators":[50,100,200,300,400,500],
              "max_features": sp_randint(1, 11),
              "min_samples_split": sp_randint(2, 11),
              "min_samples_leaf": sp_randint(1, 11),
              "bootstrap": [True, False],
              "criterion": ["gini", "entropy"]}

forest_random = RandomizedSearchCV( estimator=RandomForestClassifier( random_state=0 ),
                                    param_distributions=param_dist,
                                    cv=3,              #CV
                                    n_iter=1944,          #interation num
                                    scoring="accuracy", #metrics
                                    n_jobs=1,           #num of core
                                    verbose=0,          
                                    random_state=1)

forest_random.fit(X,y)
forest_random_best = forest_random.best_estimator_ #best estimator
print("Best Model Parameter: ",forest_random.best_params_)

#    [RandomForestClassifier]
#      Train Accuracy: 
#                  precision    recall  f1-score   support
# 
#               B       1.00      1.00      1.00        67
#               M       1.00      1.00      1.00        75
# 
#     avg / total       1.00      1.00      1.00       142
# 
# 
#      Test Accuracy:  
#                  precision    recall  f1-score   support
# 
#               B       0.94      0.92      0.93        72
#               M       0.92      0.94      0.93        70
# 
#     avg / total       0.93      0.93      0.93       142
So với default độ chính xác đã cải thiện được 2%.

(Nguồn codetudau.com)

Hits: 8

Leave a Reply