В этом примере показано, как использовать методы обучения на основе графиков и самостоятельного обучения для маркировки данных.
Полууправляемое обучение объединяет аспекты контролируемого обучения, где все данные обучения помечены, и неконтролируемое обучение, где истинные метки неизвестны. То есть некоторые обучающие наблюдения помечены, но подавляющее большинство не помечены. Полууправляемые методы обучения пытаются использовать базовую структуру данных для подгонки меток к немаркированным данным.
Toolbox™ статистики и машинного обучения предоставляет для классификации следующие полууправляемые функции обучения:
fitsemigraph строит график подобия с помеченными и немечеными наблюдениями в качестве узлов и распределяет информацию метки из помеченных наблюдений в немеченые наблюдения.
fitsemiself итеративно обучает классификатор данным. Сначала функция обучает классификатор только по маркированным данным, а затем использует этот классификатор для прогнозирования метки для немаркированных данных. fitsemiself предоставляет оценки для прогнозов, а затем рассматривает прогнозы как истинные метки для следующего цикла обучения классификатора, если оценки превышают определенный порог. Этот процесс повторяется до тех пор, пока прогнозы метки не сойдутся.
Генерировать данные из двух полулунных форм. Определите, к каким новым точкам Луны относятся, используя методы, основанные на графах и самоподготовке.
Создание пользовательской функции twomoons (показано в конце этого примера). Эта функция принимает входной аргумент n и создает n точки в каждой из двух чересстрочных полулун: верхняя луна, вогнутая вниз, и нижняя луна, вогнутая вверх.
Создайте набор из 40 помеченных точек данных с помощью twomoons функция. Каждая точка в X находится в одной из двух лун, с соответствующей лунной меткой, сохраненной в векторе label.
rng('default') % For reproducibility [X,label] = twomoons(20);
Визуализируйте точки с помощью графика рассеяния. Точки на одной луне имеют одинаковый цвет.
scatter(X(:,1),X(:,2),[],label,'filled') title('Labeled Data')

Создайте набор из 400 немаркированных точек данных с помощью twomoons функция. Каждая точка в newX принадлежит одной из двух лун, но соответствующая лунная метка неизвестна.
newX = twomoons(200);
Пометить немаркированные данные в newX с использованием полупроверенного метода на основе графа. По умолчанию fitsemigraph строит график подобия из данных в X и newXи использует метод распространения меток для подгонки меток к newX.
graphMdl = fitsemigraph(X,label,newX)
graphMdl =
SemiSupervisedGraphModel with properties:
FittedLabels: [400x1 double]
LabelScores: [400x2 double]
ClassNames: [1 2]
ResponseName: 'Y'
CategoricalPredictors: []
Method: 'labelpropagation'
Properties, Methods
Функция возвращает SemiSupervisedGraphModel объект, чей FittedLabels содержит соответствующие метки для немаркированных данных и LabelScores содержит связанные оценки меток.
Визуализируйте результаты подгонки меток с помощью графика рассеяния. Для задания цвета точек используйте подогнанные метки, а для задания прозрачности точек - максимальные значения меток. Точки с меньшей прозрачностью маркируются с большей уверенностью.
maxGraphScores = max(graphMdl.LabelScores,[],2); rescaledGraphScores = rescale(maxGraphScores,0.05,0.95); scatter(newX(:,1),newX(:,2),[],graphMdl.FittedLabels,'filled', ... 'MarkerFaceAlpha','flat','AlphaData',rescaledGraphScores); title(["Fitted Labels for Unlabeled Data","(Graph-Based)"])

Этот метод, похоже, маркирует newX точки точно. Две луны визуально различимы, и точки, которые помечены с наибольшей неопределенностью, лежат на границе между двумя формами.
Пометить немаркированные данные в newX с использованием полууправляемого метода самоподготовки. По умолчанию fitsemiself использует модель вспомогательной векторной машины (SVM) с гауссовым ядром для итеративной маркировки данных.
selfSVMMdl = fitsemiself(X,label,newX)
selfSVMMdl =
SemiSupervisedSelfTrainingModel with properties:
FittedLabels: [400x1 double]
LabelScores: [400x2 double]
ClassNames: [1 2]
ResponseName: 'Y'
CategoricalPredictors: []
Learner: [1x1 classreg.learning.classif.CompactClassificationSVM]
Properties, Methods
Функция возвращает SemiSupervisedSelfTrainingModel объект, чей FittedLabels содержит соответствующие метки для немаркированных данных и LabelScores содержит связанные оценки меток.
Визуализируйте результаты подгонки меток с помощью графика рассеяния. Как и ранее, используйте подогнанные метки для задания цвета точек, а максимальные оценки меток - для задания прозрачности точек.
maxSVMScores = max(selfSVMMdl.LabelScores,[],2); rescaledSVMScores = rescale(maxSVMScores,0.05,0.95); scatter(newX(:,1),newX(:,2),[],selfSVMMdl.FittedLabels,'filled', ... 'MarkerFaceAlpha','flat','AlphaData',rescaledSVMScores); title(["Fitted Labels for Unlabeled Data","(Self-Training: SVM)"])

Этот метод с учеником SVM также, похоже, маркирует newX точки точно. Две луны визуально различимы, и точки, которые помечены с наибольшей неопределенностью, лежат на границе между двумя формами.
Однако некоторые учащиеся могут не маркировать немеченые данные так эффективно. Например, используйте древовидную модель вместо модели SVM по умолчанию для маркировки данных в newX.
selfTreeMdl = fitsemiself(X,label,newX,'Learner','tree');
Визуализируйте результаты подгонки метки.
maxTreeScores = max(selfTreeMdl.LabelScores,[],2); rescaledTreeScores = rescale(maxTreeScores,0.05,0.95); scatter(newX(:,1),newX(:,2),[],selfTreeMdl.FittedLabels,'filled', ... 'MarkerFaceAlpha','flat','AlphaData',rescaledTreeScores); title(["Fitted Labels for Unlabeled Data","(Self-Training: Tree)"])

Этот метод, с изучающим дерево, неправильно помечает многие точки в верхней Луне. При использовании полуинспектируемого метода самостоятельного обучения убедитесь, что используется базовый ученик, соответствующий структуре данных.
Этот код создает функцию twomoons.
function [X,label] = twomoons(n) % Generate two moons, with n points in each moon. % Specify the radius and relevant angles for the two moons. noise = (1/6).*randn(n,1); radius = 1 + noise; angle1 = pi + pi/10; angle2 = pi/10; % Create the bottom moon with a center at (1,0). bottomTheta = linspace(-angle1,angle2,n)'; bottomX1 = radius.*cos(bottomTheta) + 1; bottomX2 = radius.*sin(bottomTheta); % Create the top moon with a center at (0,0). topTheta = linspace(angle1,-angle2,n)'; topX1 = radius.*cos(topTheta); topX2 = radius.*sin(topTheta); % Return the moon points and their labels. X = [bottomX1 bottomX2; topX1 topX2]; label = [ones(n,1); 2*ones(n,1)]; end