Классификация¶
В этом примере показано, как выполнить классификацию с использованием наивных байесовских классификаторов и деревьев решений. Предположим, у вас есть набор данных, содержащий наблюдения с измерениями различных переменных (называемых предикторами) и их известные метки классов. При получении значений предикторов для новых наблюдений, можете ли вы определить, к каким классам, вероятно, принадлежат эти наблюдения? В этом состоит проблема классификации.
Для запуска этой демонстрации требуется подключение к интернету
Ирисы Фишера¶
Набор данных "Ирисы Фишера" состоит из измерений длины и ширины чашелистика, а также длины и ширины лепестка по 150 экземплярам ирисов. Здесь представлено по 50 образцов каждого из трёх видов. Загрузите данные и посмотрите, как отличаются размеры чашелистиков у разных видов. Вы можете использовать первые два столбца, содержащих их измерения.
Загрузка библиотек для статистического анализа¶
Для работы со статистическими данными необходимо загрузить указанные библиотеки.
Pkg.add("DecisionTree")#загрузка библиотеки решающих деревьев
Pkg.add("NaiveBayes")#загрузка библиотеки с Баесовскими классификаторами
Pkg.add("StatsBase")#для использования predict в баесовском классификаторе
Pkg.add("StatsPlots")#для построения точечных графиков
Подключение загруженнных и вспомогательных библиотек для выгрузки набора данных, для построения графиков и для обучения классификаторов.
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
Формирование матриц предикторов и набора меток классов.
features, labels = load_data("iris")
features = float.(features);
labels = string.(labels);
Подключение метода библиотеки Plots для отображения графиков, а также определение датасета для отображения распределения наблюдений по ширине и длине чашелистика (SepalWidth, SepalLength).
plotlyjs();
iris = dataset("datasets", "iris");
Набор данных с предикторами и классами.
first(iris[:,1:5],5)
График распределения наблюдений по ширине и длине чашелистика.
@df iris scatter(:SepalLength, :SepalWidth, group = :Species)
Подготовка матрицы предикторов для всех гипотетических наблюдений, которая понадобится при построении точечного графика, отображающего работу классификатора по разделению объектов на классы.
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);
Наивный Байесовский классификатор¶
Наивный Баесовский классификатор - простой вероятностный классификатор, основанный на применении теоремы Байеса со строгими (наивными) предположениями о независимости.
Достоинством наивного байесовского классификатора является малое количество данных, необходимых для обучения, оценки параметров и классификации.
Предобработка данных для использования в обучении модели Баесовского классификатора.
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];
Определение структуры модели методом GaussianNB и её обучение методом fit. Вычисление точности.
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")
Формирование матрицы прогнозов для новых наблюдений.
predNB = fill("", 0);#Определение пустого массива
predNB = (NaiveBayes.predict(modelNB, x12[:,1:h]));#наполнение массива значениями предсказаний
Формирование матрицы предиктор-прогноз для новых наблюдений.
x_pred_NB = hcat(x12',predNB);
pred_df_NB = DataFrame(x_pred_NB,:auto);
Отображение разделения классификатором поля предикторов на классы, соответствующие видам ирисов.
gr()
@df pred_df_NB scatter(:x1, :x2, group = :x3, markersize = 7)
Дерево решений¶
Дерево решений - это набор простых правил, таких как "если длина чашелистиков меньше 5,45, классифицируйте образец как setosa". Деревья решений также непараметричны, поскольку они не требуют каких-либо предположений о распределении переменных в каждом классе.
Процесс построения деревьев решений заключается в последовательном, рекурсивном разбиении обучающего множества на подмножества с применением решающих правил в узлах.
Определение структуры модели методом DecisionTreeClassifier и её обучение методом fit!. Вычисление точности с помощью кросс-валидации.
Отображение дерева решений.
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", чтобы классифицировать каждый образец по одному из 11 конечных узлов. Чтобы определить вид наблюдаемого ириса, начните с верхнего условия и применяйте правила. Если наблюдение удовлетворяет правилу, вы выбираете верхнюю ветвь, а если нет, то выбираете нижнюю. В итоге вы достигнете конечного узла, который присвоит наблюдаемому экземпляру значение одного из трех видов.
Формирование матрицы прогнозов для новых наблюдений.
predDT = fill("", 0);#определение массива
#формирование матрицы значение-прогноз для решающего дерева
for i in 1:h
predDT = vcat(predDT, predict(modelDT, x12[:,i]))
end
Формирование матрицы предиктор-прогноз для новых наблюдений.
x_pred_DT = hcat(x12',predDT);
pred_df_DT = DataFrame(x_pred_DT,:auto);
Отображение разделения классификатором поля предикторов на классы, соответствующие видам ирисов.
@df pred_df_DT scatter(:x1, :x2, group = :x3, markersize = 7)
Вывод¶
В данном примере была решена задача классификации с использованием наивного байесовского классификатора и дерева решений. Было продемонстрировано использование библиотек DecisionTree и NaiveBayes. С их помощью осуществлялось обучение классификаторов.
Классификаторы, в свою очередь, при достаточно малом наборе данных, показали хорошую точность и разделили поле предикторов на классы.