В этом примере показано, как использовать основанные на графе и самообучение полууправляемые методы обучения для маркировки данных.
Полууправляемое обучение сочетает в себе аспекты контролируемого обучения, где все обучающие данные маркированы, и неконтролируемого обучения, где истинные метки неизвестны. То есть некоторые обучающие наблюдения маркируются, но подавляющее большинство не маркировано. Полууправляемые методы обучения пытаются использовать базовую структуру данных, чтобы соответствовать меткам к немаркированным данным.
Statistics and Machine Learning 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