ML算法基礎——分類模型評估與調參

一、分類模型評估

1.準確率

estimator.score()
一般最常見使用的是準確率,即預測結果正確的百分比

2.精確率和召回率

2.1 混淆矩陣

在分類任務下,預測結果(Predicted Condition)與正確標記(True Condition)之間存在四種不同的組合,構成混淆矩陣(適用於多分類)
image

2.2 精確率(Precision)與召回率(Recall)

精確率:預測結果爲正例樣本中真實爲正例的比例(查得準)
image
召回率:真實爲正例的樣本中預測結果爲正例的比例(查的全,對正樣本的區分能力)
image
其他分類標準,F1-score,反映了模型的穩健型
image

2.3 分類模型評估API

sklearn.metrics.classification_report

  • sklearn.metrics.classification_report(y_true,y_pred,target_names=None)

    • y_true:真實目標值
    • y_pred:估計器預測目標值
    • target_names:目標類別名稱
    • return:每個類別精確率與召回率

2.4 貝葉斯模型評估實例

from sklearn.datasets import load_iris, fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import  classification_report

def naviebayes():
    #
    news = fetch_20newsgroups(subset='all')
    #數據分割
    x_train, x_test, y_train, y_test =train_test_split(news.data,news.target,test_size=0.25)
    # 對數據集進行特徵抽取
    tf=TfidfVectorizer()
    #以訓練集當中的詞的列表進行每篇文章重要性分析
    x_train=tf.fit_transform(x_train)
    print(tf.get_feature_names())
    x_test=tf.transform(x_test)
    #進行樸素貝葉斯算法
    mlt=MultinomialNB(alpha=1.0)
    print(x_train.toarray())
    mlt.fit(x_train,y_train)
    y_predict=mlt.predict(x_test)
    print("預測的文章類別爲:", y_predict)
    # 得出準確率
    print("準確率爲:",mlt.score(x_test,y_test))
    print("每個類別的精確率和召回率爲:", classification_report(y_test,y_predict,target_names=news.target_names))

    return None

naviebayes()

結果:

預測的文章類別爲: [16 18 17 ... 10 16  9]
準確率爲: 0.8495331069609507
每個類別的精確率和召回率爲:                           precision    recall  f1-score   support

             alt.atheism       0.84      0.72      0.78       200
           comp.graphics       0.87      0.81      0.84       233
 comp.os.ms-windows.misc       0.84      0.86      0.85       232
comp.sys.ibm.pc.hardware       0.70      0.85      0.77       243
   comp.sys.mac.hardware       0.94      0.74      0.83       262
          comp.windows.x       0.97      0.77      0.86       265
            misc.forsale       0.95      0.73      0.82       252
               rec.autos       0.87      0.92      0.89       246
         rec.motorcycles       0.95      0.97      0.96       236
      rec.sport.baseball       0.96      0.97      0.96       241
        rec.sport.hockey       0.93      0.98      0.95       256
               sci.crypt       0.74      0.97      0.84       240
         sci.electronics       0.85      0.85      0.85       234
                 sci.med       0.97      0.90      0.93       250
               sci.space       0.88      0.97      0.92       237
  soc.religion.christian       0.59      0.97      0.73       259
      talk.politics.guns       0.80      0.97      0.88       235
   talk.politics.mideast       0.88      0.97      0.93       231
      talk.politics.misc       0.97      0.63      0.76       193
      talk.religion.misc       1.00      0.15      0.26       167

               micro avg       0.85      0.85      0.85      4712
               macro avg       0.87      0.84      0.83      4712
            weighted avg       0.87      0.85      0.84      4712

二、模型的選擇與調優

1、交叉驗證

  • 交叉驗證優點:爲了讓被評估的模型更加準確可信
  • 交叉驗證過程
    將拿到的數據,分爲訓練和驗證集。
    以下圖爲例:將數據分成4份,其中一份作爲驗證集。然後經過4次(組)的測試,每次都更換不同的驗證集。即得到4組模型的結果,取平均值作爲最終結果。又稱4折交叉驗證。
    image

2、網格搜索

通常情況下,有很多參數是需要手動指定的(如k-近鄰算法中的K值),這種叫超參數。但是手動過程繁雜,所以需要對模型預設幾種超參數組合。每組超參數都採用交叉驗證來進行評估。最後選出最優參數組合建立模型。
⽹格搜索:調參數 K-近鄰:超參數K
image

若是有兩個參數:a [2,3,5,8,10] b [20,70,80] 兩兩組合 15

2.1 超參數搜索-網格搜索API

sklearn.model_selection.GridSearchCV

  • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
    • 對估計器的指定參數值進行詳盡搜索
    • estimator:估計器對象
    • param_grid:估計器參數(dict){“n_neighbors”:[1,3,5]}
    • cv:指定幾折交叉驗證
    • fit:輸入訓練數據
    • score:準確率
  • 結果分析:
    • best_score_:在交叉驗證中測試的最好結果
    • best_estimator_:最好的參數模型
    • cv_results_:每次交叉驗證後的測試集準確率結果和訓練集準確率結果

2.2 knn實例測試網格搜索

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler
import pandas as pd
def knncls():
    #KNN預測用戶簽到位置
    #(1)讀取
    data=pd.read_csv("train.csv")
    #print(data.head(10))
    #(2)處理
    #1.縮小數據,查詢數據,篩選
    data= data.query("x>1.0 & x<1.25 & y>2.5 & x<2.75 ")
    #2.處理時間數據
    time_value=pd.to_datetime(data['time'],unit='s')
    #print(time_value)
    #3.把日期格式轉換成字典格式
    time_value=pd.DatetimeIndex(time_value)
    #5.構造一些特徵,
    data.loc[:,'day']=time_value.day
    data.loc[:,'hour'] = time_value.hour
    data.loc[:,'weekday'] = time_value.weekday

    #6.把時間戳特徵刪除
    data=data.drop(['time'],axis=1)
    #7.把簽到數量小於n個的刪除
    place_count= data.groupby('place_id').count()
    tf=place_count[place_count.row_id>5].reset_index()
    data=data[data['place_id'].isin(tf.place_id)]

    #8.取出數據中特徵值和目標值
    y=data['place_id']

    x=data.drop(['place_id','row_id'],axis=1)

    #9.數據分割,分割成訓練集和測試集
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
    #(3)特徵工程
    std=StandardScaler()

    #對測試集和訓練集的特徵值進行標準化處理
    x_train=std.fit_transform(x_train)

    x_test=std.transform(x_test)

    #(4)進行算法流程
    knn=KNeighborsClassifier()

    #構造一些參數的值進行搜索
    param={"n_neighbors":[3,5,10]}
    #進行網格搜索
    gc=GridSearchCV(knn,param_grid=param,cv=4)
    gc.fit(x_train,y_train)
    #預測準確率
    print("在測試集上的準確率",gc.score(x_test,y_test))
    print("在交叉驗證中最好的結果:",gc.best_score_)
    print("選擇最好的模型是:", gc.best_estimator_)
    print("每個超參數每次交叉驗證的結果:", gc.cv_results_)

    return None

knncls()

結果:

在測試集上的準確率 0.14548372112664162
在交叉驗證中最好的結果: 0.1311800773618157
選擇最好的模型是: KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=10, p=2,
           weights='uniform')
每個超參數每次交叉驗證的結果: {'mean_fit_time': array([4.45146149, 4.44196486, 4.11655921]), 'std_fit_time': array([1.03164362, 0.27887817, 0.82325426]), 'mean_score_time': array([7.91340411, 9.79840308, 9.37138796]), 'std_score_time': array([1.20371498, 1.11789183, 0.34117932]), 'param_n_neighbors': masked_array(data=[3, 5, 10],
             mask=[False, False, False],
       fill_value='?',
            dtype=object), 'params': [{'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 10}], 'split0_test_score': array([0.11439086, 0.12198176, 0.12945183]), 'split1_test_score': array([0.11406997, 0.12397793, 0.13036728]), 'split2_test_score': array([0.11594878, 0.12543602, 0.1317419 ]), 'split3_test_score': array([0.1179383 , 0.1270673 , 0.13326486]), 'mean_test_score': array([0.11556132, 0.12458124, 0.13118008]), 'std_test_score': array([0.00152546, 0.00187404, 0.00143886]), 'rank_test_score': array([3, 2, 1]), 'split0_train_score': array([0.440091  , 0.35226585, 0.27819626]), 'split1_train_score': array([0.43980955, 0.35193647, 0.27779743]), 'split2_train_score': array([0.43872216, 0.35040288, 0.2768066 ]), 'split3_train_score': array([0.43867638, 0.35147282, 0.27770352]), 'mean_train_score': array([0.43932477, 0.3515195 , 0.27762595]), 'std_train_score': array([0.00063357, 0.00070355, 0.00050794])}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章