本章将专注于实现监督学习——分类。
分类技术或模型尝试从观察到的值中得出某些结论。在分类问题中,我们有分类的输出,如“黑色”或“白色”、“教学”和“非教学”。构建分类模型时,我们需要一个包含数据点及其相应标签的训练数据集。例如,如果我们想检查一张图片是否是汽车的图片。为了检查这一点,我们将构建一个包含与“汽车”和“非汽车”两个类别的训练数据集。然后我们需要使用训练样本训练模型。分类模型主要用在人脸识别、垃圾邮件识别等方面。
在Python中构建分类器的步骤
为了在Python中构建一个分类器,我们将使用Python 3和Scikit-learn,这是一个Python中的机器学习工具包。遵循以下步骤来构建一个分类器:
第一步:导入Scikit-learn
这是构建分类器的第一步。在这个步骤中,我们将安装一个名为Scikit-learn的Python包,它是Python中最好的机器学习模块之一。下面的命令将帮助我们导入这个包:
import sklearn
第二步:导入Scikit-learn的数据集
在这个步骤中,我们可以开始处理用于机器学习模型的数据集。这里,我们将使用威斯康星诊断乳腺癌数据库。该数据集包括关于乳腺肿瘤的各种信息以及恶性或良性的分类标签。该数据集有569个实例,即569个肿瘤的信息,并包含了关于30个属性的信息,如肿瘤的半径、纹理、光滑度和面积。下面的命令可以导入Scikit-learn的乳腺癌数据集:
from sklearn.datasets import load_breast_cancer
现在,下面的命令将加载数据集:
data = load_breast_cancer()
以下是重要的字典键列表:
现在,通过下面的命令,我们可以创建新的变量来为每组重要的信息分配数据。换句话说,我们可以组织数据如下:
label_names = data['target_names']
labels = data['target']
feature_names = data['feature_names']
features = data['data']
现在,为了使它更清楚,我们可以打印出类别标签、第一个数据实例的标签、特征名称以及特征值。这可以通过以下命令完成:
print(label_names)
上述命令将打印出类别名称,它们是恶性肿瘤和良性肿瘤,如下面的输出所示:
['malignant' 'benign']
现在,下面的命令将显示它们映射到的二进制值0和1。这里0代表恶性肿瘤,1代表良性肿瘤。你会得到如下输出:
print(labels[0])
0
下面两个命令将产生特征名称和特征值:
print(feature_names[0])
mean radius
print(features[0])
[ 1.79900000e+01 1.03800000e+01 1.22800000e+02 1.00100000e+03
1.18400000e-01 2.77600000e-01 3.00100000e-01 1.47100000e-01
2.41900000e-01 7.87100000e-02 1.09500000e+00 9.05300000e-01
8.58900000e+00 1.53400000e+02 6.39900000e-03 4.90400000e-02
5.37300000e-02 1.58700000e-02 3.00300000e-02 6.19300000e-03
2.53800000e+01 1.73300000e+01 1.84600000e+02 2.01900000e+03
1.62200000e-01 6.65600000e-01 7.11900000e-01 2.65400000e-01
4.60100000e-01 1.18900000e-01]
从上面的输出中,我们可以看到第一个数据实例是一个半径为1.7990000e+01的恶性肿瘤。
第三步:组织数据成集合
在这个步骤中,我们将数据分为两部分,即训练集和测试集。将数据分割为这些集合是非常重要的,因为我们需要在未见过的数据上测试我们的模型。为了分割数据成这些集合,sklearn有一个名为train_test_split()
的函数。下面的命令可以分割数据成这些集合:
from sklearn.model_selection import train_test_split
上述命令将导入train_test_split
函数。下面的命令将按照40%的数据用于测试而剩余数据用于训练模型的方式分割数据:
train, test, train_labels, test_labels = train_test_split(features, labels, test_size=0.40, random_state=42)
第四步:构建模型
在这个步骤中,我们将构建模型。我们将使用朴素贝叶斯算法来构建模型。下面的命令可以用来构建模型:
from sklearn.naive_bayes import GaussianNB
上述命令将导入GaussianNB模块。现在,下面的命令将初始化模型:
gnb = GaussianNB()
我们将通过拟合数据来训练模型:
model = gnb.fit(train, train_labels)
第五步:评估模型及其准确性
在这个步骤中,我们将通过在测试数据上进行预测来评估模型。然后我们将找出它的准确性。为了进行预测,我们将使用predict()
函数。下面的命令将帮助你做到这一点:
preds = gnb.predict(test)
print(preds)
[1 0 0 1 1 0 0 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1
0 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0
0 1 1 0 0 1 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0
0 1 1 1 1 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 0 0
1 1 1 0 0 1 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 0
1 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0
1 1 0 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 1 1 1 0 1 1 0 1 1 1 0
1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 1]
上述一系列的0和1是肿瘤分类——恶性或良性的预测值。
现在,通过比较test_labels
和preds
这两个数组,我们可以找出模型的准确性。我们将使用accuracy_score()
函数来确定准确率。考虑下面的命令:
from sklearn.metrics import accuracy_score
print(accuracy_score(test_labels, preds))
0.951754385965
结果表明,朴素贝叶斯分类器的准确率为95.17%。
通过以上步骤,我们可以构建Python中的分类器。
在Python中构建分类器
在这一节中,我们将学习如何在Python中构建分类器。
朴素贝叶斯分类器
朴素贝叶斯是一种使用贝叶斯定理来构建分类器的技术。其假设是预测因子是独立的。简单地说,它假定某一类中的某一特征的存在与另一特征的存在无关。为了构建朴素贝叶斯分类器,我们需要使用名为scikit-learn的Python库。在scikit-learn包中有三种类型的朴素贝叶斯模型,分别是高斯型、多项式型和伯努利型。
为了构建朴素贝叶斯机器学习分类器模型,我们需要以下组件:
数据集
我们将使用名为威斯康星诊断乳腺癌数据库的数据集。该数据集包括关于乳腺肿瘤的各种信息以及恶性或良性的分类标签。该数据集有569个实例,即569个肿瘤的信息,并包含了关于30个属性的信息,如肿瘤的半径、纹理、光滑度和面积。我们可以从sklearn包中导入此数据集。
朴素贝叶斯模型
为了构建朴素贝叶斯分类器,我们需要一个朴素贝叶斯模型。正如前面提到的,在scikit-learn包中有三种类型的朴素贝叶斯模型,分别是高斯型、多项式型和伯努利型。在这里,下面的例子中我们将使用高斯朴素贝叶斯模型。
使用以上组件,我们将构建一个利用肿瘤信息来预测肿瘤是否为恶性或良性的机器学习模型。
首先,我们需要安装sklearn模块。这可以通过下面的命令完成:
import sklearn
现在,我们需要导入名为威斯康星诊断乳腺癌数据库的数据集:
from sklearn.datasets import load_breast_cancer
现在,下面的命令将加载数据集:
data = load_breast_cancer()
数据可以这样组织:
label_names = data['target_names']
labels = data['target']
feature_names = data['feature_names']
features = data['data']
现在,为了使它更清楚,我们可以打印出类别标签、第一个数据实例的标签、特征名称以及特征值。这可以通过以下命令完成:
print(label_names)
上述命令将打印出类别名称,它们是恶性肿瘤和良性肿瘤,如下面的输出所示:
['malignant' 'benign']
现在,下面的命令将显示它们映射到的二进制值0和1。这里0代表恶性肿瘤,1代表良性肿瘤。它以如下输出形式展示:
print(labels[0])
0
构建分类器在Python中的实现
本章将专注于实现监督学习——分类。
分类技术或模型尝试从观察到的值中得出某些结论。在分类问题中,我们有分类的输出,如“黑色”或“白色”、“教学”和“非教学”。构建分类模型时,我们需要一个包含数据点及其相应标签的训练数据集。例如,如果我们想检查一张图片是否是汽车的图片。为了检查这一点,我们将构建一个包含与“汽车”和“非汽车”两个类别的训练数据集。然后我们需要使用训练样本训练模型。分类模型主要用在人脸识别、垃圾邮件识别等方面。
在Python中构建分类器的步骤
为了在Python中构建一个分类器,我们将使用Python 3和Scikit-learn,这是一个Python中的机器学习工具包。遵循以下步骤来构建一个分类器:
第一步:导入Scikit-learn
这是构建分类器的第一步。在这个步骤中,我们将安装一个名为Scikit-learn的Python包,它是Python中最好的机器学习模块之一。下面的命令将帮助我们导入这个包:
import sklearn
第二步:导入Scikit-learn的数据集
在这个步骤中,我们可以开始处理用于机器学习模型的数据集。这里,我们将使用威斯康星诊断乳腺癌数据库。该数据集包括关于乳腺肿瘤的各种信息以及恶性或良性的分类标签。该数据集有569个实例,即569个肿瘤的信息,并包含了关于30个属性的信息,如肿瘤的半径、纹理、光滑度和面积。下面的命令可以导入Scikit-learn的乳腺癌数据集:
from sklearn.datasets import load_breast_cancer
现在,下面的命令将加载数据集:
data = load_breast_cancer()
以下是重要的字典键列表:
现在,通过下面的命令,我们可以创建新的变量来为每组重要的信息分配数据。换句话说,我们可以组织数据如下:
label_names = data['target_names']
labels = data['target']
feature_names = data['feature_names']
features = data['data']
现在,为了使它更清楚,我们可以打印出类别标签、第一个数据实例的标签、特征名称以及特征值。这可以通过以下命令完成:
print(label_names)
上述命令将打印出类别名称,它们是恶性肿瘤和良性肿瘤,如下面的输出所示:
['malignant' 'benign']
现在,下面的命令将显示它们映射到的二进制值0和1。这里0代表恶性肿瘤,1代表良性肿瘤。你会得到如下输出:
print(labels[0])
0
下面两个命令将产生特征名称和特征值:
print(feature_names[0])
mean radius
print(features[0])
[ 1.79900000e+01 1.03800000e+01 1.22800000e+02 1.00100000e+03
1.18400000e-01 2.77600000e-01 3.00100000e-01 1.47100000e-01
2.41900000e-01 7.87100000e-02 1.09500000e+00 9.05300000e-01
8.58900000e+00 1.53400000e+02 6.39900000e-03 4.90400000e-02
5.37300000e-02 1.58700000e-02 3.00300000e-02 6.19300000e-03
2.53800000e+01 1.73300000e+01 1.84600000e+02 2.01900000e+03
1.62200000e-01 6.65600000e-01 7.11900000e-01 2.65400000e-01
4.60100000e-01 1.18900000e-01]
从上面的输出中,我们可以看到第一个数据实例是一个半径为1.7990000e+01的恶性肿瘤。
为了在未见过的数据上测试我们的模型,我们需要将数据分为训练数据和测试数据。这可以通过以下代码完成:
from sklearn.model_selection import train_test_split
上述命令将导入train_test_split
函数。下面的命令将按照40%的数据用于测试而剩余数据用于训练模型的方式分割数据:
train, test, train_labels, test_labels = train_test_split(features, labels, test_size=0.40, random_state=42)
现在,我们通过以下命令来构建模型:
from sklearn.naive_bayes import GaussianNB
上述命令将导入GaussianNB
模块。现在,通过下面的命令,我们需要初始化模型:
gnb = GaussianNB()
我们将通过拟合数据来训练模型:
model = gnb.fit(train, train_labels)
现在,通过在测试数据上进行预测来评估模型,这可以通过以下方式完成:
preds = gnb.predict(test)
print(preds)
[1 0 0 1 1 0 0 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1
0 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0
0 1 1 0 0 1 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 0 0 0
0 1 1 1 1 1 1 1 1 0 0 1 0 0 1 0 0 1 1 1 0 1 1 0 1 1 0 0 0
1 1 1 0 0 1 1 0 1 0 0 1 1 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 0
1 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0
1 1 0 1 1 1 1 1 1 0 0 0 1 1 0 1 0 1 1 1 1 0 1 1 0 1 1 1 0
1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 1]
上述一系列的0和1是肿瘤分类——恶性或良性的预测值。
现在,通过比较test_labels
和preds
这两个数组,我们可以找出模型的准确性。我们将使用accuracy_score()
函数来确定准确率。考虑下面的命令:
from sklearn.metrics import accuracy_score
print(accuracy_score(test_labels, preds))
0.951754385965
结果表明,朴素贝叶斯分类器的准确率为95.17%。
那是一个基于朴素贝叶斯高斯模型的机器学习分类器。
支持向量机(SVM)
基本上,支持向量机(SVM)是一种监督机器学习算法,它可以用于回归和分类。SVM的主要概念是将每个数据项作为n维空间中的一个点绘制出来,其中每个特征的值对应一个特定坐标。这里的n是我们拥有的特征数。下面是一个简单的图形表示,有助于理解SVM的概念:
在上面的图中,我们有两个特征。因此,我们首先需要在二维空间中绘制这两个变量,每个点有两个坐标,称为支持向量。这条线将数据分成两个不同的分类组。这条线就是分类器。
这里,我们打算通过使用scikit-learn和鸢尾花数据集来构建一个SVM分类器。Scikit-learn库有sklearn.svm
模块,并提供sklearn.svm.SVC
用于分类。下面展示了基于4个特征来预测鸢尾花植物类别的SVM分类器:
from sklearn import datasets
from sklearn import svm
iris = datasets.load_iris()
X = iris.data
y = iris.target
clf = svm.SVC()
clf.fit(X, y)
构建SVM分类器
本节将介绍如何使用支持向量机(SVM)对鸢尾花数据集进行分类。鸢尾花数据集包含三个类别的各50个实例,每个类别代表一种鸢尾花植物。每个实例具有四个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度。下面展示了基于这四个特征来预测鸢尾花植物类别的SVM分类器。
核函数
核函数是SVM所使用的一种技术。本质上,这些函数接受低维输入空间,并将其转换为更高维度的空间。这样做可以将原本不可分的问题转化为可分的问题。核函数可以是线性、多项式、RBF(径向基函数)或Sigmoid等类型。在此例中,我们将使用线性核。
现在让我们导入以下包:
import pandas as pd
import numpy as np
from sklearn import svm, datasets
import matplotlib.pyplot as plt
接下来,加载输入数据:
iris = datasets.load_iris()
我们取前两个特征:
X = iris.data[:, :2]
y = iris.target
我们将绘制支持向量机边界以及原始数据。为此,我们创建一个网格来进行绘制。
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max - x_min) / 100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
X_plot = np.c_[xx.ravel(), yy.ravel()]
我们需要给定正则化参数的值:
C = 1.0
我们需要创建SVM分类器对象:
svc_classifier = svm.SVC(kernel='linear', C=C, decision_function_shape='ovr').fit(X, y)
接着,我们对网格中的每一个点进行预测:
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
最后,我们绘制决策边界和数据点:
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('萼片长度')
plt.ylabel('萼片宽度')
plt.xlim(xx.min(), xx.max())
plt.title('带有线性核的支持向量机(SVC)')
带有线性核的支持向量机(SV C)。
逻辑回归
逻辑回归模型是监督分类算法家族的一员。逻辑回归通过估计概率来衡量依赖变量与独立变量之间的关系。
在这里,如果谈论依赖变量和独立变量,则依赖变量是我们要预测的目标类变量,而另一方面,独立变量是我们用来预测目标类的特征。
在逻辑回归中,估计概率意味着预测事件发生的可能性。例如,店主想要预测进入店铺的顾客是否会购买游戏机(例如PlayStation)。顾客会有很多特征——性别、年龄等——店主会根据这些特征来预测事件发生的可能性,即是否会购买游戏机。逻辑函数是用于建立函数的S形曲线,该曲线涉及各种参数。
前提条件
在使用逻辑回归构建分类器之前,我们需要在系统上安装Tkinter包。可以从以下网址安装:https://docs.python.org/2/library/tkinter.html。
现在,借助以下代码,我们可以使用逻辑回归创建分类器:
首先,我们将导入一些包:
import numpy as np
from sklearn import linear_model
import matplotlib.pyplot as plt
接下来,我们需要定义样本数据,可以按照以下方式进行:
X = np.array([[2, 4.8], [2.9, 4.7], [2.5, 5], [3.2, 5.5], [6, 5], [7.6, 4],
[3.2, 0.9], [2.9, 1.9], [2.4, 3.5], [0.5, 3.4], [1, 4], [0.9, 5.9]])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3])
接下来,我们需要创建逻辑回归分类器,可以按照以下方式进行:
classifier_lr = linear_model.LogisticRegression(solver='liblinear', C=75)
最后,我们需要训练这个分类器:
classifier_lr.fit(X, y)
现在,我们如何可视化输出?可以通过创建一个名为logistic_visualize
的函数来实现:
def logistic_visualize(classifier_lr, X, y):
min_x, max_x = X[:, 0].min() - 1.0, X[:, 0].max() + 1.0
min_y, max_y = X[:, 1].min() - 1.0, X[:, 1].max() + 1.0
在上述行中,我们定义了用于网格的X和Y的最小值和最大值。此外,我们将定义用于绘制网格的步长大小。
mesh_step_size = 0.02
让我们按照以下方式定义X和Y值的网格:
x_vals, y_vals = np.meshgrid(np.arange(min_x, max_x, mesh_step_size),
np.arange(min_y, max_y, mesh_step_size))
借助以下代码,我们可以在网格上运行分类器:
output = classifier_lr.predict(np.c_[x_vals.ravel(), y_vals.ravel()])
output = output.reshape(x_vals.shape)
plt.figure()
plt.pcolormesh(x_vals, y_vals, output, cmap=plt.cm.gray)
plt.scatter(X[:, 0], X[:, 1], c=y, s=75, edgecolors='black',
linewidth=1, cmap=plt.cm.Paired)
以下代码行将指定绘图的边界:
plt.xlim(x_vals.min(), x_vals.max())
plt.ylim(y_vals.min(), y_vals.max())
plt.xticks(np.arange(int(X[:, 0].min() - 1), int(X[:, 0].max() + 1), 1.0))
plt.yticks(np.arange(int(X[:, 1].min() - 1), int(X[:, 1].max() + 1), 1.0))
plt.show()
现在,在运行代码后,我们将获得以下输出,逻辑回归分类器:
注释: 原文中提到的“logistic_visualize”函数定义并未完整给出。在实际应用中,您需要确保所有必要的部分都已正确实现。此外,“plt.figure()”之后的绘图代码应该是在logistic_visualize
函数内部,而非全局执行。
决策树分类器
决策树基本上是一个二叉树流程图,其中每个节点根据某个特征变量分割一组观测值。
在这里,我们正在构建一个决策树分类器来预测男性或女性。我们将采用一个非常小的数据集,共有19个样本。这些样本将包含两个特征:“身高”和“头发长度”。
前提条件
为了构建以下分类器,我们需要安装pydotplus和graphviz。基本上,graphviz是一个用于使用dot文件绘制图形的工具,而pydotplus是一个Graphviz的Dot语言模块。它可以通过包管理器或pip进行安装。
现在,我们可以借助以下Python代码来构建决策树分类器:
首先,让我们导入一些重要的库:
import pydotplus
from sklearn import tree
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report
from sklearn import cross_validation
import collections
接下来,我们需要提供数据集:
X = [[165, 19], [175, 32], [136, 35], [174, 65], [141, 28], [176, 15], [131, 32],
[166, 6], [128, 32], [179, 10], [136, 34], [186, 2], [126, 25], [176, 28], [112, 38],
[169, 9], [171, 36], [116, 25], [196, 25]]
Y = ['Man', 'Woman', 'Woman', 'Man', 'Woman', 'Man', 'Woman', 'Man', 'Woman',
'Man', 'Woman', 'Man', 'Woman', 'Woman', 'Woman', 'Man', 'Woman', 'Woman', 'Man']
data_feature_names = ['height', 'length of hair']
X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(
X, Y, test_size=0.40, random_state=5)
提供了数据集后,我们需要拟合模型,可以按照以下方式完成:
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y)
可以通过以下Python代码进行预测:
prediction = clf.predict([[133, 37]])
print(prediction)
我们可以借助以下Python代码来可视化决策树:
dot_data = tree.export_graphviz(clf, feature_names=data_feature_names,
out_file=None, filled=True, rounded=True)
graph = pydotplus.graph_from_dot_data(dot_data)
colors = ('orange', 'yellow')
edges = collections.defaultdict(list)
for edge in graph.get_edge_list():
edges[edge.get_source()].append(int(edge.get_destination()))
for edge in edges:
edges[edge].sort()
for i in range(2):
dest = graph.get_node(str(edges[edge][i]))[0]
dest.set_fillcolor(colors[i])
graph.write_png('Decisiontree16.png')
对于上述代码,它将给出预测结果为['Woman'],并创建如下决策树:
决策树
我们可以更改预测中的特征值来测试它。
随机森林分类器
我们知道,集成方法是将机器学习模型组合成更强大的机器学习模型的方法。随机森林是一组决策树,是其中之一。它比单个决策树更好,因为它在保持预测能力的同时,通过平均结果减少过拟合。在这里,我们将在scikit-learn癌症数据集上实现随机森林模型。
首先,导入必要的包:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt
import numpy as np
现在,我们需要提供数据集,可以按照如下方式做:
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, random_state=0)
提供了数据集后,我们需要拟合模型,可以按照以下方式完成:
forest = RandomForestClassifier(n_estimators=50, random_state=0)
forest.fit(X_train, y_train)
现在,获取训练子集和测试子集上的准确率:如果我们增加估计器的数量,那么测试子集的准确率也会提高。
print('训练子集准确率:{:.3f}'.format(forest.score(X_train, y_train)))
print('测试子集准确率:{:.3f}'.format(forest.score(X_test, y_test)))
输出:
训练子集准确率:1.000
测试子集准确率:0.965
像决策树一样,随机森林也有feature_importance
模块,这将提供比决策树更好的特征权重视图。它可以按照如下方式绘制和可视化:
n_features = cancer.data.shape[1]
plt.barh(range(n_features), forest.feature_importances_, align='center')
plt.yticks(np.arange(n_features), cancer.feature_names)
plt.xlabel('特征重要性')
plt.ylabel('特征')
plt.show()
分类器性能
在实现机器学习算法之后,我们需要找出模型的有效性如何。衡量有效性的标准可能是基于数据集和度量指标的。为了评估不同的机器学习算法,我们可以使用不同的性能指标。例如,如果一个分类器用于区分不同物体的图像,我们可以使用诸如平均准确度、AUC等分类性能指标。在一个或另一个意义上,我们选择用来评估机器学习模型的度量是非常重要的,因为度量的选择影响着机器学习算法性能的测量和比较。以下是一些度量:
混淆矩阵
基本上,它是用于分类问题,其中输出可以属于两类或多类中的任一类。这是衡量分类器性能的最简单方法。混淆矩阵本质上是一个二维表,包含“实际”和“预测”的维度。在这两个维度中都有“真正例(TP)”、“真负例(TN)”、“假正例(FP)”、“假负例(FN)”。
在上面的混淆矩阵中,1代表正类,0代表负类。
以下是与混淆矩阵相关的术语:
-
真正例(TP) - 当数据点的实际类为1且预测也是1的情况。
-
真负例(TN) - 当数据点的实际类为0且预测也是0的情况。
-
假正例(FP) - 当数据点的实际类为0但预测为1的情况。
-
假负例(FN) - 当数据点的实际类为1但预测为0的情况
准确率
混淆矩阵本身并不是一个性能度量,但是几乎所有性能度量都是基于混淆矩阵的。其中之一就是准确率。在分类问题中,它可以定义为模型所做的所有预测中正确的预测数量。计算准确率的公式如下:
精确率
精确率主要用于文档检索领域。它可以定义为返回的文档中有多少是正确的。计算精确率的公式如下:
召回率或敏感性
它可以定义为模型返回了多少正例。计算召回率/敏感性的公式如下:
特异性
它可以定义为模型返回了多少负例。这与召回率正好相反。计算特异性的公式如下:
类别不平衡问题
类别不平衡是指一个类别的观察数显著低于其他类别的观察数。例如,在需要识别罕见疾病或银行中的欺诈交易的情况下,这个问题尤为突出。
不平衡类别示例
让我们通过一个欺诈检测数据集的例子来理解不平衡类别的概念:
解决方案
平衡类别可以作为解决不平衡类别问题的方法。平衡类别的主要目的是增加少数类的频率或减少多数类的频率。以下是解决类别不平衡问题的一些方法:
重采样
重采样是一系列用于重构样本数据集的方法——包括训练集和测试集。重采样的目的是提高模型的准确性。以下是一些重采样技术:
随机欠采样
这种技术旨在通过随机消除多数类实例来平衡类分布。直到多数类和少数类实例平衡为止。
在这种情况下,我们从非欺诈实例中无放回地抽取10%的样本,然后将它们与欺诈实例合并:
-
随机欠采样后的非欺诈观察数 = 4950的10% = 495
-
结合欺诈观察数后的总观察数 = 50+495 = 545
因此,欠采样后新数据集的事件发生率为9%。
这种方法的主要优点是可以减少运行时间和存储需求。但另一方面,减少训练数据样本数量可能会丢弃有用的信息。
随机过采样
这种技术旨在通过复制少数类实例来增加其数量以平衡类分布。
如果我们复制50个欺诈观察30次,则复制少数类观察后的欺诈观察数将是1500。然后,在过采样后的新数据集中总观察数将是4950+1500 = 6450。因此,新数据集的事件发生率为1500/6450 = 23%。
这种方法的主要优点是不会丢失有用的信息。但另一方面,由于复制了少数类事件,因此增加了过拟合的风险。
集成技术
这种方法基本上是用来修改现有的分类算法,使其适用于不平衡的数据集。在这个方法中,我们从原始数据构造多个两阶段分类器,然后汇总它们的预测。随机森林分类器就是一个基于集成技术的分类器的例子。