使用sklearn的cross_val_score进行交叉验证实例


Posted in Python onFebruary 28, 2020

在构建模型时,调参是极为重要的一个步骤,因为只有选择最佳的参数才能构建一个最优的模型。但是应该如何确定参数的值呢?所以这里记录一下选择参数的方法,以便后期复习以及分享。

(除了贝叶斯优化等方法)其它简单的验证有两种方法:

1、通过经常使用某个模型的经验和高超的数学知识。

2、通过交叉验证的方法,逐个来验证。

很显然我是属于后者所以我需要在这里记录一下

sklearn 的 cross_val_score:

我使用是cross_val_score方法,在sklearn中可以使用这个方法。交叉验证的原理不好表述下面随手画了一个图:

使用sklearn的cross_val_score进行交叉验证实例

(我都没见过这么丑的图)简单说下,比如上面,我们将数据集分为10折,做一次交叉验证,实际上它是计算了十次,将每一折都当做一次测试集,其余九折当做训练集,这样循环十次。通过传入的模型,训练十次,最后将十次结果求平均值。将每个数据集都算一次

交叉验证优点:

1:交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。

2:还可以从有限的数据中获取尽可能多的有效信息。

我们如何利用它来选择参数呢?

我们可以给它加上循环,通过循环不断的改变参数,再利用交叉验证来评估不同参数模型的能力。最终选择能力最优的模型。

下面通过一个简单的实例来说明:(iris鸢尾花)

from sklearn import datasets #自带数据集
from sklearn.model_selection import train_test_split,cross_val_score #划分数据 交叉验证
from sklearn.neighbors import KNeighborsClassifier #一个简单的模型,只有K一个参数,类似K-means
import matplotlib.pyplot as plt
iris = datasets.load_iris() #加载sklearn自带的数据集
X = iris.data #这是数据
y = iris.target #这是每个数据所对应的标签
train_X,test_X,train_y,test_y = train_test_split(X,y,test_size=1/3,random_state=3) #这里划分数据以1/3的来划分 训练集训练结果 测试集测试结果
k_range = range(1,31)
cv_scores = [] #用来放每个模型的结果值
for n in k_range:
 knn = KNeighborsClassifier(n) #knn模型,这里一个超参数可以做预测,当多个超参数时需要使用另一种方法GridSearchCV
 scores = cross_val_score(knn,train_X,train_y,cv=10,scoring='accuracy') #cv:选择每次测试折数 accuracy:评价指标是准确度,可以省略使用默认值,具体使用参考下面。
 cv_scores.append(scores.mean())
plt.plot(k_range,cv_scores)
plt.xlabel('K')
plt.ylabel('Accuracy') #通过图像选择最好的参数
plt.show()
best_knn = KNeighborsClassifier(n_neighbors=3) # 选择最优的K=3传入模型
best_knn.fit(train_X,train_y) #训练模型
print(best_knn.score(test_X,test_y)) #看看评分

最后得分0.94

使用sklearn的cross_val_score进行交叉验证实例

关于 cross_val_score 的 scoring 参数的选择,通过查看官方文档后可以发现相关指标的选择可以在这里找到:文档。

这应该是比较简单的一个例子了,上面的注释也比较清楚,如果我表达不清楚可以问我。

补充拓展:sklearn分类算法汇总

废话不多说,上代码吧!

import os
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn import preprocessing
from sklearn import neighbors
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn import svm
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from time import time
from sklearn.naive_bayes import MultinomialNB
from sklearn import tree
from sklearn.ensemble import GradientBoostingClassifier

#读取sklearn自带的数据集(鸢尾花)
def getData_1():
 iris = datasets.load_iris()
 X = iris.data #样本特征矩阵,150*4矩阵,每行一个样本,每个样本维度是4
 y = iris.target #样本类别矩阵,150维行向量,每个元素代表一个样本的类别
#读取本地excel表格内的数据集(抽取每类60%样本组成训练集,剩余样本组成测试集)
#返回一个元祖,其内有4个元素(类型均为numpy.ndarray):
#(1)归一化后的训练集矩阵,每行为一个训练样本,矩阵行数=训练样本总数,矩阵列数=每个训练样本的特征数
#(2)每个训练样本的类标
#(3)归一化后的测试集矩阵,每行为一个测试样本,矩阵行数=测试样本总数,矩阵列数=每个测试样本的特征数
#(4)每个测试样本的类标
#【注】归一化采用“最大最小值”方法。
def getData_2():
 fPath = 'D:\分类算法\binary_classify_data.txt'
 if os.path.exists(fPath):
  data = pd.read_csv(fPath,header=None,skiprows=1,names=['class0','pixel0','pixel1','pixel2','pixel3'])
  X_train1, X_test1, y_train1, y_test1 = train_test_split(data, data['class0'], test_size = 0.4, random_state = 0)
  min_max_scaler = preprocessing.MinMaxScaler() #归一化
  X_train_minmax = min_max_scaler.fit_transform(np.array(X_train1))
  X_test_minmax = min_max_scaler.fit_transform(np.array(X_test1))
  return (X_train_minmax, np.array(y_train1), X_test_minmax, np.array(y_test1))
 else:
  print ('No such file or directory!')

#读取本地excel表格内的数据集(每类随机生成K个训练集和测试集的组合)
#【K的含义】假设一共有1000个样本,K取10,那么就将这1000个样本切分10份(一份100个),那么就产生了10个测试集
#对于每一份的测试集,剩余900个样本即作为训练集
#结果返回一个字典:键为集合编号(1train, 1trainclass, 1test, 1testclass, 2train, 2trainclass, 2test, 2testclass...),值为数据
#其中1train和1test为随机生成的第一组训练集和测试集(1trainclass和1testclass为训练样本类别和测试样本类别),其他以此类推
def getData_3():
 fPath = 'D:\\分类算法\\binary_classify_data.txt'
 if os.path.exists(fPath):
  #读取csv文件内的数据,
  dataMatrix = np.array(pd.read_csv(fPath,header=None,skiprows=1,names=['class0','pixel0','pixel1','pixel2','pixel3']))
  #获取每个样本的特征以及类标
  rowNum, colNum = dataMatrix.shape[0], dataMatrix.shape[1]
  sampleData = []
  sampleClass = []
  for i in range(0, rowNum):
   tempList = list(dataMatrix[i,:])
   sampleClass.append(tempList[0])
   sampleData.append(tempList[1:])
  sampleM = np.array(sampleData) #二维矩阵,一行是一个样本,行数=样本总数,列数=样本特征数
  classM = np.array(sampleClass) #一维列向量,每个元素对应每个样本所属类别
  #调用StratifiedKFold方法生成训练集和测试集
  skf = StratifiedKFold(n_splits = 10)
  setDict = {} #创建字典,用于存储生成的训练集和测试集
  count = 1
  for trainI, testI in skf.split(sampleM, classM):
   trainSTemp = [] #用于存储当前循环抽取出的训练样本数据
   trainCTemp = [] #用于存储当前循环抽取出的训练样本类标
   testSTemp = [] #用于存储当前循环抽取出的测试样本数据
   testCTemp = [] #用于存储当前循环抽取出的测试样本类标
   #生成训练集
   trainIndex = list(trainI)
   for t1 in range(0, len(trainIndex)):
    trainNum = trainIndex[t1]
    trainSTemp.append(list(sampleM[trainNum, :]))
    trainCTemp.append(list(classM)[trainNum])
   setDict[str(count) + 'train'] = np.array(trainSTemp)
   setDict[str(count) + 'trainclass'] = np.array(trainCTemp)
   #生成测试集
   testIndex = list(testI)
   for t2 in range(0, len(testIndex)):
    testNum = testIndex[t2]
    testSTemp.append(list(sampleM[testNum, :]))
    testCTemp.append(list(classM)[testNum])
   setDict[str(count) + 'test'] = np.array(testSTemp)
   setDict[str(count) + 'testclass'] = np.array(testCTemp)
   count += 1
  return setDict
 else:
  print ('No such file or directory!')
#K近邻(K Nearest Neighbor)
def KNN():
 clf = neighbors.KNeighborsClassifier()
 return clf

#线性鉴别分析(Linear Discriminant Analysis)
def LDA():
 clf = LinearDiscriminantAnalysis()
 return clf

#支持向量机(Support Vector Machine)
def SVM():
 clf = svm.SVC()
 return clf

#逻辑回归(Logistic Regression)
def LR():
 clf = LogisticRegression()
 return clf

#随机森林决策树(Random Forest)
def RF():
 clf = RandomForestClassifier()
 return clf

#多项式朴素贝叶斯分类器
def native_bayes_classifier():
 clf = MultinomialNB(alpha = 0.01)
 return clf

#决策树
def decision_tree_classifier():
 clf = tree.DecisionTreeClassifier()
 return clf

#GBDT
def gradient_boosting_classifier():
 clf = GradientBoostingClassifier(n_estimators = 200)
 return clf

#计算识别率
def getRecognitionRate(testPre, testClass):
 testNum = len(testPre)
 rightNum = 0
 for i in range(0, testNum):
  if testClass[i] == testPre[i]:
   rightNum += 1
 return float(rightNum) / float(testNum)

#report函数,将调参的详细结果存储到本地F盘(路径可自行修改,其中n_top是指定输出前多少个最优参数组合以及该组合的模型得分)
def report(results, n_top=5488):
 f = open('F:/grid_search_rf.txt', 'w')
 for i in range(1, n_top + 1):
  candidates = np.flatnonzero(results['rank_test_score'] == i)
  for candidate in candidates:
   f.write("Model with rank: {0}".format(i) + '\n')
   f.write("Mean validation score: {0:.3f} (std: {1:.3f})".format(
     results['mean_test_score'][candidate],
     results['std_test_score'][candidate]) + '\n')
   f.write("Parameters: {0}".format(results['params'][candidate]) + '\n')
   f.write("\n")
 f.close()

#自动调参(以随机森林为例)
def selectRFParam():
 clf_RF = RF()
 param_grid = {"max_depth": [3,15],
     "min_samples_split": [3, 5, 10],
     "min_samples_leaf": [3, 5, 10],
     "bootstrap": [True, False],
     "criterion": ["gini", "entropy"],
     "n_estimators": range(10,50,10)}
     # "class_weight": [{0:1,1:13.24503311,2:1.315789474,3:12.42236025,4:8.163265306,5:31.25,6:4.77326969,7:19.41747573}],
     # "max_features": range(3,10),
     # "warm_start": [True, False],
     # "oob_score": [True, False],
     # "verbose": [True, False]}
 grid_search = GridSearchCV(clf_RF, param_grid=param_grid, n_jobs=4)
 start = time()
 T = getData_2() #获取数据集
 grid_search.fit(T[0], T[1]) #传入训练集矩阵和训练样本类标
 print("GridSearchCV took %.2f seconds for %d candidate parameter settings."
   % (time() - start, len(grid_search.cv_results_['params'])))
 report(grid_search.cv_results_)

#“主”函数1(KFold方法生成K个训练集和测试集,即数据集采用getData_3()函数获取,计算这K个组合的平均识别率)
def totalAlgorithm_1():
 #获取各个分类器
 clf_KNN = KNN()
 clf_LDA = LDA()
 clf_SVM = SVM()
 clf_LR = LR()
 clf_RF = RF()
 clf_NBC = native_bayes_classifier()
 clf_DTC = decision_tree_classifier()
 clf_GBDT = gradient_boosting_classifier()
 #获取训练集和测试集
 setDict = getData_3()
 setNums = len(setDict.keys()) / 4 #一共生成了setNums个训练集和setNums个测试集,它们之间是一一对应关系
 #定义变量,用于将每个分类器的所有识别率累加
 KNN_rate = 0.0
 LDA_rate = 0.0
 SVM_rate = 0.0
 LR_rate = 0.0
 RF_rate = 0.0
 NBC_rate = 0.0
 DTC_rate = 0.0
 GBDT_rate = 0.0
 for i in range(1, int(setNums + 1)):
  trainMatrix = setDict[str(i) + 'train']
  trainClass = setDict[str(i) + 'trainclass']
  testMatrix = setDict[str(i) + 'test']
  testClass = setDict[str(i) + 'testclass']
  #输入训练样本
  clf_KNN.fit(trainMatrix, trainClass)
  clf_LDA.fit(trainMatrix, trainClass)
  clf_SVM.fit(trainMatrix, trainClass)
  clf_LR.fit(trainMatrix, trainClass)
  clf_RF.fit(trainMatrix, trainClass)
  clf_NBC.fit(trainMatrix, trainClass)
  clf_DTC.fit(trainMatrix, trainClass)
  clf_GBDT.fit(trainMatrix, trainClass)
  #计算识别率
  KNN_rate += getRecognitionRate(clf_KNN.predict(testMatrix), testClass)
  LDA_rate += getRecognitionRate(clf_LDA.predict(testMatrix), testClass)
  SVM_rate += getRecognitionRate(clf_SVM.predict(testMatrix), testClass)
  LR_rate += getRecognitionRate(clf_LR.predict(testMatrix), testClass)
  RF_rate += getRecognitionRate(clf_RF.predict(testMatrix), testClass)
  NBC_rate += getRecognitionRate(clf_NBC.predict(testMatrix), testClass)
  DTC_rate += getRecognitionRate(clf_DTC.predict(testMatrix), testClass)
  GBDT_rate += getRecognitionRate(clf_GBDT.predict(testMatrix), testClass)
 #输出各个分类器的平均识别率(K个训练集测试集,计算平均)
 print
 print
 print
 print('K Nearest Neighbor mean recognition rate: ', KNN_rate / float(setNums))
 print('Linear Discriminant Analysis mean recognition rate: ', LDA_rate / float(setNums))
 print('Support Vector Machine mean recognition rate: ', SVM_rate / float(setNums))
 print('Logistic Regression mean recognition rate: ', LR_rate / float(setNums))
 print('Random Forest mean recognition rate: ', RF_rate / float(setNums))
 print('Native Bayes Classifier mean recognition rate: ', NBC_rate / float(setNums))
 print('Decision Tree Classifier mean recognition rate: ', DTC_rate / float(setNums))
 print('Gradient Boosting Decision Tree mean recognition rate: ', GBDT_rate / float(setNums))

#“主”函数2(每类前x%作为训练集,剩余作为测试集,即数据集用getData_2()方法获取,计算识别率)
def totalAlgorithm_2():
 #获取各个分类器
 clf_KNN = KNN()
 clf_LDA = LDA()
 clf_SVM = SVM()
 clf_LR = LR()
 clf_RF = RF()
 clf_NBC = native_bayes_classifier()
 clf_DTC = decision_tree_classifier()
 clf_GBDT = gradient_boosting_classifier()
 #获取训练集和测试集
 T = getData_2()
 trainMatrix, trainClass, testMatrix, testClass = T[0], T[1], T[2], T[3]
 #输入训练样本
 clf_KNN.fit(trainMatrix, trainClass)
 clf_LDA.fit(trainMatrix, trainClass)
 clf_SVM.fit(trainMatrix, trainClass)
 clf_LR.fit(trainMatrix, trainClass)
 clf_RF.fit(trainMatrix, trainClass)
 clf_NBC.fit(trainMatrix, trainClass)
 clf_DTC.fit(trainMatrix, trainClass)
 clf_GBDT.fit(trainMatrix, trainClass)
 #输出各个分类器的识别率
 print('K Nearest Neighbor recognition rate: ', getRecognitionRate(clf_KNN.predict(testMatrix), testClass))
 print('Linear Discriminant Analysis recognition rate: ', getRecognitionRate(clf_LDA.predict(testMatrix), testClass))
 print('Support Vector Machine recognition rate: ', getRecognitionRate(clf_SVM.predict(testMatrix), testClass))
 print('Logistic Regression recognition rate: ', getRecognitionRate(clf_LR.predict(testMatrix), testClass))
 print('Random Forest recognition rate: ', getRecognitionRate(clf_RF.predict(testMatrix), testClass))
 print('Native Bayes Classifier recognition rate: ', getRecognitionRate(clf_NBC.predict(testMatrix), testClass))
 print('Decision Tree Classifier recognition rate: ', getRecognitionRate(clf_DTC.predict(testMatrix), testClass))
 print('Gradient Boosting Decision Tree recognition rate: ', getRecognitionRate(clf_GBDT.predict(testMatrix), testClass))

if __name__ == '__main__':
 print('K个训练集和测试集的平均识别率')
 totalAlgorithm_1()
 print('每类前x%训练,剩余测试,各个模型的识别率')
 totalAlgorithm_2()
 selectRFParam()
 print('随机森林参数调优完成!')

以上都是个人理解,如果有问题还望指出。希望大家多多支持三水点靠木!

Python 相关文章推荐
Python基于Tkinter实现的记事本实例
Jun 17 Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
Jan 20 Python
Python安装官方whl包和tar.gz包的方法(推荐)
Jun 04 Python
Django代码性能优化与Pycharm Profile使用详解
Aug 26 Python
python3 爬取图片的实例代码
Nov 06 Python
Python-Tkinter Text输入内容在界面显示的实例
Jul 12 Python
python 下 CMake 安装配置 OPENCV 4.1.1的方法
Sep 30 Python
python的pyecharts绘制各种图表详细(附代码)
Nov 11 Python
Python爬虫使用bs4方法实现数据解析
Aug 25 Python
Python CategoricalDtype自定义排序实现原理解析
Sep 11 Python
Python Pygame实战之塔防游戏的实现
Mar 17 Python
基于Python实现nc批量转tif格式
Aug 14 Python
彻底搞懂 python 中文乱码问题(深入分析)
Feb 28 #Python
python GUI库图形界面开发之PyQt5状态栏控件QStatusBar详细使用方法实例
Feb 28 #Python
python sklearn包——混淆矩阵、分类报告等自动生成方式
Feb 28 #Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
Feb 28 #Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
Feb 28 #Python
浅谈ROC曲线的最佳阈值如何选取
Feb 28 #Python
python GUI库图形界面开发之PyQt5多行文本框控件QTextEdit详细使用方法实例
Feb 28 #Python
You might like
实用函数8
2007/11/08 PHP
PHP日期处理函数 整型日期格式
2011/01/12 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
php stream_get_meta_data返回值
2013/09/29 PHP
ThinkPHP处理Ajax返回的方法
2014/11/22 PHP
PHP实现无限极分类图文教程
2014/11/25 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
AJAX的跨域与JSONP(为文章自动添加短址的功能)
2010/01/17 Javascript
jquery中ajax学习笔记4
2011/10/16 Javascript
JavaScript判断密码强度(自写代码)
2013/09/06 Javascript
jquery 倒计时效果实现秒杀思路
2013/09/11 Javascript
移动节点的jquery代码
2014/01/13 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
JS实现的数组全排列输出算法
2015/03/19 Javascript
JavaScript中的toLocaleLowerCase()方法使用详解
2015/06/06 Javascript
jQuery横向擦除焦点图特效代码分享
2015/09/06 Javascript
基于jQuery实现表格的查看修改删除
2016/08/01 Javascript
jQuery扇形定时器插件pietimer使用方法详解
2017/07/18 jQuery
vue中axios实现数据交互与跨域问题
2019/05/12 Javascript
详解在vue-cli3.0中自定css、js和图片的打包路径
2019/08/26 Javascript
jQuery实现开关灯效果
2020/08/02 jQuery
[56:57]LGD vs VP 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第一场 8.20.mp4
2019/08/22 DOTA
Python字符串中查找子串小技巧
2015/04/10 Python
八大排序算法的Python实现
2021/01/28 Python
小议Python中自定义函数的可变参数的使用及注意点
2016/06/21 Python
利用PyInstaller将python程序.py转为.exe的方法详解
2017/05/03 Python
python顺序执行多个py文件的方法
2019/06/29 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
2019/10/23 Python
杠杆的科学教学反思
2014/01/10 职场文书
环境科学专业求职信
2014/08/04 职场文书
公民授权委托书范本
2014/09/17 职场文书
大学生个人简历自我评价
2015/03/11 职场文书
初婚初育证明范本
2015/06/18 职场文书
在Django中使用MQTT的方法
2021/05/10 Python