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])}

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