ML算法基础——分类模型评估与调参
程序员文章站
2022-07-11 23:47:28
...
文章目录
一、分类模型评估
1.准确率
estimator.score()
一般最常见使用的是准确率,即预测结果正确的百分比
2.精确率和召回率
2.1 混淆矩阵
在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)
2.2 精确率(Precision)与召回率(Recall)
精确率:预测结果为正例样本中真实为正例的比例(查得准)
召回率:真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力)
其他分类标准,F1-score,反映了模型的稳健型
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折交叉验证。
2、网格搜索
通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
⽹格搜索:调参数 K-近邻:超参数K
若是有两个参数: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])}
上一篇: Eclipse 常用问题汇总
下一篇: 深度模型调参
推荐阅读