评估算法与算法评估矩阵

  要知道算法模型对未知数据表现如何,最好的评估办法是利用已经明确知道结果的数据运行生成的算法模型进行验证。此外,还可以采用重新采样评估的方法,使用新的数据来评估算法模型。

  1.评估算法的方法
  在评估机器学习算法的时候,为什么不将训练数据集直接作为评估数据集,最直接的原因是过度拟合,不能有效地发现算法模型中的不足。过度拟合是指为了得到一致假设变得过度严格。避免过度拟合是分类器设计中的一个核心任务,通常采用增大数据量和评估数据集的方法对分类器进行评估。
  评估就是估计算法在预测新数据的时候能达到什么程度,但这不是对算法准确度的保证。当评估完算法模型之后,可以用整个数据集重新训练算法,生成最终的算法模型。接下来用四种不同的分离数据集的方法,用来分离训练数据集和评估数据集,并用其评估算法模型:
  1.分离训练数据集和评估数据集
  2.K折交叉验证分离
  3.弃一交叉验证分离
  4.重复随机评估,训练数据集分离

  1.1分离训练数据集和评估数据集
  最简单的方法就是将评估数据集和训练数据集完全分开,采用评估数据集来评估算法模型。可以简单地将原始数据集分成两个部分,第一部分用来训练算法生成模型,第二部分通过模型来预测结果,并与已知的结果进行比较,来评估算法模型的准确度。如何分割数据集取决于数据集的规模,通常会将67%的数据作为训练集,将33%的数据作为评估数据集。
  这是一种非常简洁,快速的数据分离技术,通常在具有大量数据,数据分布比较平衡,或者对问题的展示比较平均的情况下非常有效。这个方法非常快速,对某些执行比较慢的算法非常有效。

from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
test_size = 0.33
seed = 4
X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size=test_size,random_state=seed)
model = LogisticRegression()
model.fit(X_train,Y_train)
result = model.score(X_test,Y_test)
print("算法评估结果:%.3f%%" % (result * 100))

  注意的是,为了让算法模型具有良好的可复用性,在指定了分离数据的大小同时,还指定了数据随机的粒度,将数据随机进行分离。通过指定随机的粒度,可以确保每次执行程序得到相同的结果,这有助于比较两个不同的算法生成的模型的结果。为了保证算法比较是在相同的条件下执行的,必须保证训练数据集和评估数据集是相同的。

  1.2K折交叉验证分离
  交叉验证是用来验证分类器的性能的一种统计分析方法,有时也称作循环估计,在统计学上是将数据样本切割成小子集的实用方法。基本思想是按照某种规则将原始数据进行分组,一部分作为训练数据集,另一部分作为评估数据集。首先用训练数据集对分类器进行训练,再利用评估数据集来测试训练得到的模型,以此作为评价分类器的性能指标。
  K折交叉验证是将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样就会得到K个模型,再用这K个模型最终的验证集的分类准确率的平均数,作为此K折交叉验证下分类器的性能指标。K一般大于等于2,实际操作时一般从3开始取值,只有在原始数据集和数据量小的时候才会尝试取2。K折交叉验证可以有效地避免过学习及欠学习状态的发生。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,random_state=seed)
model = LogisticRegression()
result = cross_val_score(model,X,Y,cv=kfold)
print("算法评估结果:%.3f%%(%.3f%%)"%(result.mean()*100,result.std()*100))

  1.3弃一交叉验证分离
  如果原始数据有N个样本,那么弃一交叉验证就是N-1个交叉验证,即每个样本单独作为验证集,其余的N-1个样本作为训练集,所以弃一交叉验证会得到N个模型,即这N个模型最终的验证集的分类准确率的平均数作为此次弃一交叉验证分类器的性能指标。相较于K折交叉验证,弃一交叉验证有两个显著的优点:
  1.每一回合几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得到的结果比较可靠。
  2.实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。
  但弃一交叉验证的缺点是计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,弃一交叉验证在实际运行上便有困难,需要花费大量的时间来完成算法的运算和评估,除非每次训练分类器得到模型的速度很快,或者可以用并行化计算减少计算所需的时间。

from pandas import read_csv
from sklearn.model_selection import LeaveOneOut
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
loocv = LeaveOneOut()
model = LogisticRegression()
result = cross_val_score(model,X,Y,cv=loocv)
print("算法评估结果:%.3f%%(%.3f%%)"%(result.mean()*100,result.std()*100))

  1.4重复随机分离评估数据集与训练数据集
  另外一种K折交叉验证的用途是随机分离数据作为训练数据集和评估数据集,但是重复这个过程多次,就如同交叉验证分离。如下将数据按照67%:33%的比例分离,然后重复这个过程10次。

from pandas import read_csv
from sklearn.model_selection import ShuffleSplit
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
n_splits = 10
test_size = 0.33
seed = 7
kfold = ShuffleSplit(n_splits=n_splits,test_size=test_size,random_state=seed)
model = LogisticRegression()
result = cross_val_score(model,X,Y,cv=kfold)
print("算法评估结果:%.3f%%(%.3f%%)"%(result.mean()*100,result.std()*100))

  通常按照下面的原则来选择数据分离的方法:
  1.K折交叉验证时用来评估机器学习算法的黄金准则。通常会取K为3,5,10来分离数据
  2.分离训练数据集和评估数据集。因为执行效率比较高,通常会用于算法的执行效率比较低,或者具有大量数据的时候
  3.弃一交叉验证和重复随机分离评估数据集与训练数据集这两种方法,通常会用于平衡评估算法,模型训练的速度及数据集的大小
  4.当不知道如何选择分离数据集的方法时,选择K折交叉验证来分离数据集;当不知道如何设定K值时,将K值设为10

  2.算法评估矩阵
  如何来评估机器学习的算法模型时非常重要的。选择能够展示机器学习算法模型的准确度的评估矩阵,是计算和比较算法模型最好的方式。并且在评估算法时,计算并比较这些评估矩阵,可以快速地选择合适的算法。

  2.1分类算法矩阵
  分类问题或许是最常见的机器学习问题,并且有多种评估矩阵来评估分类算法。如以下几种:
  1.分类准确度
  2.对数损失函数
  3.AUC图
  4.混淆矩阵
  5.分类报告

  2.1.1分类准确度
  分类准确度就是算法自动分类正确的样本数除以所有的样本数得出的结果。通常,准确度越高,分类器越好。这是分类算法中最常见的,也最易被误用的评估参数。准确度确实是一个很好,很直观的评价指标,但是有时候准确度高并不代表算法一定好,比如因为数据分布不均衡,类别1的数据太少,完全错分类别1依然可以达到很高的准确度,却忽视了需要关注的事实和现象。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,random_state=seed)
model = LogisticRegression()
result = cross_val_score(model,X,Y,cv=kfold)
print("算法评估结果准确度:%.3f(%.3f)"%(result.mean(),result.std()))

  2.1.2对数损失函数
  在逻辑回归的推导中,它假设样本服从伯努利分布(0~1分布),然后求得满足该分布的似然函数,再取对数,求极值等。而逻辑回归并没有求似然函数的极值,而是把极大化当作一种思想,进而推导出它的经验风险函数为:最小化负的似然函数。从损失函数的视角来看,它就成了对数损失函数了。对数损失函数越小,模型就越好,而且使损失函数尽量是一个凸函数,便于收敛计算。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,random_state=seed)
model = LogisticRegression()
scoring = 'neg_log_loss'
result = cross_val_score(model,X,Y,cv=kfold,scoring=scoring)
print("Logloss:%.3f(%.3f)"%(result.mean(),result.std()))

  2.1.3.AUC图
  ROC和AUC是评价分类器的指标。ROC是受试者工作特征曲线的简写,又称为感受性曲线。得此名在于曲线上各点反映相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已。ROC纵轴是“真正例率”,横轴是“假正例率”。AUC是处于ROC下方的那部分面积大小。通常,AUC的值介于0.5和1之间,AUC的值越大,诊断准确性越高。在ROC曲线上,靠近坐标图左上方的点为敏感性和特异性均较高的临界值。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds,random_state=seed)
model = LogisticRegression()
scoring = 'roc_auc'
result = cross_val_score(model,X,Y,cv=kfold,scoring=scoring)
print('AUC %.3f (%.3f)'%(result.mean(),result.std()))

  2.14.混淆矩阵
  混淆矩阵主要用于比较分类结果和实际测得值,可以把分类结果的精度显示在一个混淆矩阵里面。混淆矩阵是可视化工具,特别适用于监督学习,在无监督学习时一般叫做匹配矩阵。混淆矩阵的每列代表预测类别,每列的总数表示预测为该类别的数据的数目;每行代表数据的真实归属类别,每行的数据总数表示该类别的数据的数目。每列中的数值表示真实数据被预测为该类的数目。

from pandas import read_csv
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
test_size = 0.33
seed = 4
X_train,X_test,Y_training,Y_test = train_test_split(X,Y,test_size=test_size,random_state=seed)
model = LogisticRegression()
model.fit(X_train,Y_training)
predicted = model.predict(X_test)
matrix = confusion_matrix(Y_test,predicted)
classes = ['0','1']
dataframe = pd.DataFrame(data=matrix,index=classes,columns=classes)
print(dataframe)#DataFrame是一个可以指定行和列标签的二维数组。数组可以通过指定列名来访问特定列的数据

  2.15.分类报告
  Classification_report()方法能够给出精确率,召回率,F1值和样本数目。

from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
#导入数据
filename = '/home/hadoop/DataSet/pima indians.csv'
names = ['preg','plas','pres','skin','test','mass','pedi','age','class']
data = read_csv(filename,names=names)
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:8]
Y = array[:,8]
test_size = 0.33
seed = 4
X_train,X_test,Y_training,Y_test = train_test_split(X,Y,test_size=test_size,random_state=seed)
model = LogisticRegression()
model.fit(X_train,Y_training)
predicted = model.predict(X_test)
report = classification_report(Y_test,predicted)
print(report)

  2.2回归算法矩阵
  三种评估机器学习的回归算法的评估矩阵:1.平方绝对误差(MAE) 2.均方误差(MSE) 3.决定系数 ( R 2 )

  2.2.1.平方绝对误差(MAE)
  平方绝对误差是所有单个观测值与算术平均值的偏差的绝对值的平均值。与平均误差相比,平均绝对误差由于离差被绝对值化,不会出现正负相抵消的情况,因而,平均绝对误差能更好地反映预测值误差的实际情况。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
#导入数据
filename = '/home/hadoop/DataSet/housing.csv'
names =['CRIM','ZN','INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PRTATIO','B','LSTAT','MEDV']
data = read_csv(filename,names=names)#delim_whitespace指定空格作为分隔符使用
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:13]
Y = array[:,13]
n_splits = 10
seed = 7
kfold = KFold(n_splits=n_splits,random_state=seed)
model = LinearRegression()
scoring = 'neg_mean_absolute_error'
result = cross_val_score(model,X,Y,cv=kfold,scoring=scoring)
print('MAE:%.3f(%.3f)'%(result.mean(),result.std()))

  2.2.2.均方误差
  均方误差是衡量平均误差的方法,可以评价数据的变化程度。均方根误差是均方误差的算数平方根。均方误差的值越小,说明用该预测模型描述实验数据的准确度越高。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
#导入数据
filename = '/home/hadoop/DataSet/housing.csv'
names = ['CRIM','ZN','INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PRTATIO','B','LSTAT','MEDV']
data = read_csv(filename,names=names)#delim_whitespace指定空格作为分隔符使用
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:13]
Y = array[:,13]
n_splits = 10
seed = 7
kfold = KFold(n_splits=n_splits,random_state=seed)
model = LinearRegression()
scoring = 'neg_mean_absolute_error'
result = cross_val_score(model,X,Y,cv=kfold,scoring=scoring)
print('MAE:%.3f(%.3f)'%(result.mean(),result.std()))

  2.2.3.决定系数
  决定系数,反映因变量的全部变异能通过回归关系被自变量解释的比例。拟合优度越大,自变量对因变量的解释程度越高,自变量引起的变动占总变动的百分比越高,观察点在回归直线附近越密集。如决定系数为0.8,则表示回归关系可以解释因变量80%的变异。换句话说,如果我们能控制自变量不变,则因变量的变异程度会减少80%。
  决定系数的特点:
  1.决定系数是非负的统计量
  2.决定系数的取值范围为0~1之间
  3.决定系数是样本观测值的函数,是因随机抽样而变动的随机变量。为此,对决定系数的统计的可靠性也应该进行检验。
  4.R2的数值范围从0至1,表示目标变量的预测值和实际值之间的相关程度平方的百分比。一个模型的R2 值为0说明它完全无法预测目标变量;而一个R2 值为1的模型则可以对目标变量进行完美的预测。从0至1之间的数值,则表示该模型中目标变量中有百分之多少能够用特征来解释。_模型也可能出现负值的R2,这种情况下模型所做预测还不如直接计算目标变量的平均值。

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
#导入数据
filename = '/home/hadoop/DataSet/housing.csv'
names = ['CRIM','ZN','INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PRTATIO','B','LSTAT','MEDV']
data = read_csv(filename,names=names)#delim_whitespace指定空格作为分隔符使用
#将数据分为输入数据和输出结果
array = data.values
X = array[:,0:13]
Y = array[:,13]
n_splits = 10
seed = 7
kfold = KFold(n_splits=n_splits,random_state=seed)
model = LinearRegression()
scoring = 'r2'
result = cross_val_score(model,X,Y,cv=kfold,scoring=scoring)
print('r2:%.3f(%.3f)'%(result.mean(),result.std()))

猜你喜欢

转载自blog.csdn.net/heloiselt/article/details/80870794