Engee 文档
Notebook

分类

本例展示了如何使用天真贝叶斯分类器和决策树进行分类。假设您有一个数据集,其中包含不同变量(称为预测因子)的测量值及其已知类别标签。当您获得新观测值的预测值时,能否确定这些观测值可能属于哪个类别?这就是分类问题。

运行此演示需要互联网连接

费舍尔鸢尾花

费舍尔鸢尾花数据集包括 150 个鸢尾花标本的萼片长度和宽度以及花瓣长度和宽度的测量数据。三个物种各有 50 个标本。下载数据并查看不同物种的萼片大小有何不同。您可以使用包含其测量值的前两列。

下载用于统计分析的库

要处理统计数据,必须加载指定的库。

In [ ]:
Pkg.add(["RDatasets", "NaiveBayes", "StatsBase", "StatsPlots", "DecisionTree", "ScikitLearn"])
In [ ]:
Pkg.add("DecisionTree")#загрузка библиотеки решающих деревьев
Pkg.add("NaiveBayes")#загрузка библиотеки с Баесовскими классификаторами
Pkg.add("StatsBase")#для использования predict в баесовском классификаторе
Pkg.add("StatsPlots")#для построения точечных графиков

连接已加载库和辅助库,用于卸载数据集、绘图和训练分类器。

In [ ]:
using NaiveBayes
using RDatasets
using StatsBase
using Random
using StatsPlots
using Plots, RDatasets
using DecisionTree
using ScikitLearn: fit!, predict
using ScikitLearn.CrossValidation: cross_val_score

生成预测矩阵和一组类别标签。

In [ ]:
features, labels = load_data("iris")
features = float.(features);
labels   = string.(labels);

连接用于显示图表的 Plots 库方法,以及定义用于显示按萼片宽度和长度(SepalWidth、SepalLength)划分的观测值分布的数据集。

In [ ]:
plotlyjs();
iris = dataset("datasets", "iris");

带有预测因子和类别的数据集。

In [ ]:
first(iris[:,1:5],5)
Out[0]:

5 rows × 5 columns

SepalLengthSepalWidthPetalLengthPetalWidthSpecies
Float64Float64Float64Float64Cat…
15.13.51.40.2setosa
24.93.01.40.2setosa
34.73.21.30.2setosa
44.63.11.50.2setosa
55.03.61.40.2setosa

按萼片宽度和长度分列的观察结果分布图。

In [ ]:
@df iris scatter(:SepalLength, :SepalWidth, group = :Species)
Out[0]:

为所有假定观察结果准备预测矩阵,这在构建显示分类器将对象分类的性能的点阵图时需要用到。

In [ ]:
h = 10000;
x1 = rand(4:0.1:8, h)
x1t = x1'
x2 = rand(2:0.1:4.5, h)
x2t = x2'
x12 = vcat(x1t,x2t);

Naive Bayesian 分类器

Naive Bayesian 分类器是一种简单的概率分类器,基于贝叶斯定理的应用和严格(天真)的独立性假设。

天真贝叶斯分类器的优势在于训练、参数估计和分类所需的数据量较小。

用于训练贝叶斯分类器模型的数据预处理。

In [ ]:
Xx = Matrix(iris[:,1:2])';#features';#
Yy = [species for species in iris[:, 5]];#labels;
p, n = size(Xx)
train_frac = 0.8
k = floor(Int, train_frac * n)
idxs = randperm(n)
train_idxs = idxs[1:k];
test_idxs = idxs[k+1:end];

用高斯贝叶斯方法确定模型结构,并用拟合方法对其进行训练。 精度计算。

In [ ]:
modelNB = GaussianNB(unique(Yy), p)
fit(modelNB, Xx[:, train_idxs], Yy[train_idxs])
accuracyNB = count(!iszero, StatsBase.predict(modelNB, Xx[:,test_idxs]) .== Yy[test_idxs]) / count(!iszero, test_idxs)
println("Accuracy: $accuracyNB")
Accuracy: 0.7333333333333333

形成新观测数据的预测矩阵。

In [ ]:
predNB = fill("", 0);#Определение пустого массива
predNB = (NaiveBayes.predict(modelNB, x12[:,1:h]));#наполнение массива значениями предсказаний

为新的观测数据生成预测-预报矩阵。

In [ ]:
x_pred_NB = hcat(x12',predNB);
pred_df_NB = DataFrame(x_pred_NB,:auto);

显示分类器将预测字段划分为与虹膜种类相对应的类别。

In [ ]:
gr()
@df pred_df_NB scatter(:x1, :x2, group = :x3, markersize = 7)
Out[0]:

决策树

决策树是一组简单的规则,例如 "如果萼片长度小于 5.45,则将标本归类为蔷薇"。决策树也是非参数型的,因为它不需要对每个类别中变量的分布做任何假设。

构建决策树的过程是通过在节点上应用决策规则,按顺序递归地将训练集划分为若干子集。

使用决策树分类器方法定义模型结构,并使用拟合方法进行训练! 使用交叉验证计算精度。

显示决策树

In [ ]:
modelDT = DecisionTreeClassifier(max_depth=10)#определение структуры модели
fit!(modelDT, features[:,1:2], labels)#обучение модели
print_tree(modelDT, 5)#отображение дерева решений
accuracy = cross_val_score(modelDT, features[:,1:2], labels, cv=8)#вычисление точности
Feature 1 < 5.55 ?
├─ Feature 2 < 2.8 ?
    ├─ Feature 1 < 4.95 ?
        ├─ Feature 2 < 2.35 ?
            ├─ Iris-setosa : 1/1
            └─ Feature 2 < 2.45 ?
                ├─ Iris-versicolor : 1/1
                └─ Iris-virginica : 1/1
        └─ Iris-versicolor : 9/9
    └─ Feature 1 < 5.35 ?
        ├─ Iris-setosa : 39/39
        └─ Feature 2 < 3.2 ?
            ├─ Iris-versicolor : 1/1
            └─ Iris-setosa : 7/7
└─ Feature 2 < 3.7 ?
    ├─ Feature 1 < 6.25 ?
        ├─ Feature 1 < 5.75 ?
            ├─ Feature 2 < 2.85 ?
                ├─ 
                └─ Iris-versicolor : 5/5
            └─ Feature 2 < 2.95 ?
                ├─ 
                └─ 
        └─ Feature 1 < 7.05 ?
            ├─ Feature 2 < 2.4 ?
                ├─ Iris-versicolor : 1/1
                └─ 
            └─ Iris-virginica : 10/10
    └─ Feature 1 < 6.75 ?
        ├─ Iris-setosa : 3/3
        └─ Iris-virginica : 2/2
Out[0]:
8-element Vector{Float64}:
 0.6190476190476191
 0.7619047619047619
 0.5
 0.7222222222222222
 0.7222222222222222
 0.7222222222222222
 0.7777777777777778
 0.7222222222222222

这棵看起来杂乱无章的树使用一系列 "特征 1 < 5.55 "形式的规则将每个样本归入 11 个最终节点之一。要确定观察到的虹膜的种类,可以从最上面的条件开始,然后应用规则。如果观察结果符合规则,则选择顶部分支;如果不符合,则选择底部分支。最终,您将到达一个最终节点,为观察到的实例分配三个物种中的一个值。

为新的观察结果形成预测矩阵。

In [ ]:
predDT = fill("", 0);#определение массива 
#формирование матрицы значение-прогноз для решающего дерева
for i in 1:h
    predDT = vcat(predDT, predict(modelDT, x12[:,i]))
end

为新的观测数据生成预测-预报矩阵。

In [ ]:
x_pred_DT = hcat(x12',predDT);
pred_df_DT = DataFrame(x_pred_DT,:auto);

显示分类器将预测字段划分为与虹膜种类相对应的类别。

In [ ]:
@df pred_df_DT scatter(:x1, :x2, group = :x3, markersize = 7)
Out[0]:

输出

该示例使用天真贝叶斯分类器和决策树解决了一个分类问题。演示了 DecisionTreeNaiveBayes 库的使用。 它们被用来训练分类器。

反过来,分类器在使用相当小的数据集时显示出良好的准确性,并将预测领域划分为不同的类别。