Калибровка Счета i-вектора

Система i-вектора выводит необработанный счет, характерный для данных, и параметры раньше разрабатывали систему. Это делает интерпретацию счета и нахождение сопоставимого порога решения для задач верификации трудными.

Чтобы обратиться к этим трудностям, исследователи разработали нормализацию счета и калибровочные методы счета.

  • В нормализации счета необработанные баллы нормированы относительно 'когорты самозванца'. Выиграйте нормализация происходит прежде, чем оценить ошибочный компромисс обнаружения и может улучшить точность системы и ее способности адаптироваться к новым данным.

  • В калибровке счета необработанные баллы сопоставлены с вероятностями, которые в свою очередь используются, чтобы лучше изучить доверие системы к решениям.

В этом примере вы применяете калибровку счета к системе i-вектора. Чтобы узнать о нормализации счета, смотрите Нормализацию Счета i-вектора.

Например, цели, вы используете выигрыш подобия косинуса (CSS) в этом примере. interpretability выигрыша вероятностного линейного дискриминантного анализа (PLDA) также улучшен калибровкой.

Загрузите Систему i-вектора и Набор данных

Чтобы загрузить предварительно обученную систему i-вектора, подходящую для распознавания динамика, вызовите speakerRecognition. ivectorSystem возвращенный был обучен на наборе данных LibriSpeech, который состоит из англоязычных записей на 16 кГц.

ivs = speakerRecognition;

Предварительно обученная система i-вектора достигает равного коэффициента ошибок (EER) использование на приблизительно 6,73% выигрыша подобия косинуса (CSS) и 1,11% с помощью вероятностного линейного дискриминантного анализа (PLDA) на наборе тестов LibriSpeech.

detectionErrorTradeoff(ivs)

Загрузите набор данных PTDB-TUG [1]. Функция поддержки, loadDataset, загружает набор данных и затем передискретизирует его от 48 кГц до 16 кГц, который является частотой дискретизации, на которой была обучена система i-вектора. loadDataset функция возвращает их audioDatastore объекты:

  • adsEnroll - Содержит файлы, чтобы зарегистрировать докладчиков в систему i-вектора.

  • adsDev - Содержит большой набор файлов, чтобы анализировать ошибочный компромисс обнаружения системы i-вектора, и к эффективности выборочной проверки.

  • adsCalibrate - Содержит набор динамиков, используемых, чтобы калибровать систему i-вектора. Калибровочный набор не перекрывается с наборами dev и регистрировать.

targetSampleRate = ivs.SampleRate;
[adsEnroll,adsDev,adsCalibrate] = loadDataset(targetSampleRate);

Оцените Производительность системы i-вектора на Новых Данных

Чтобы зарегистрировать докладчиков от набора данных приема в систему i-вектора, вызовите enroll.

enroll(ivs,adsEnroll,adsEnroll.Labels)
Extracting i-vectors ...done.
Enrolling i-vectors .............done.
Enrollment complete.

Чтобы установить порог решения верификации по умолчанию к порогу, подходящему для набора данных PTDB-TUG, вызовите detectionErrorTradeoff с набором разработки.

detectionErrorTradeoff(ivs,adsDev,adsDev.Labels)
Extracting i-vectors ...done.
Scoring i-vector pairs ...done.
Detection error tradeoff evaluation complete.

Считайте аудиосэмпл из набора разработки и получите связанную метку. Вызовите verify проверять способность системы правильно проверить целевую метку. verify объектная функция возвращает решение верификации и необработанный счет, сопоставленный с решением. Система правильно принимает целевую метку.

reset(adsDev)
[audioIn,fileInfo] = read(adsDev);
targetLabel = fileInfo.Label;

[decision,rawScore] = verify(ivs,audioIn,targetLabel,'css')
decision = logical
   1

rawScore = 0.8991

Выберите метку, которая не соответствует аудиовходу и затем вызывает, проверяют снова, чтобы проверять способность системы правильно отклонить нецелевую метку. Система правильно отклоняет нецелевую метку.

enrolledLabels = categorical(ivs.EnrolledLabels.Properties.RowNames);
nontargetIdx = find(~ismember(enrolledLabels,targetLabel));
nontargetLabel = enrolledLabels(nontargetIdx(1));

[decision,rawScore] = verify(ivs,audioIn,nontargetLabel,'css')
decision = logical
   0

rawScore = 0.8521

Система правильно принимает динамик при проверке истинной идентичности и правильно отклоняет динамик при попытке проверить ложную идентичность. Однако необработанные баллы не сразу переводимы как оценки достоверности. В этом примере вы исследуете две популярных альтернативы для преобразования необработанного счета к "калиброванному" счету.

Выиграйте калибровку

В калибровке счета вы применяете деформирующуюся функцию к баллам так, чтобы они были более легко и последовательно поддающиеся толкованию как меры доверия. Обычно выиграйте, калибровка не оказывает влияния на эффективность системы верификации, потому что отображение является аффинным преобразованием. Двумя самыми популярными подходами к калибровке является Платт, масштабирующийся и изотоническая регрессия. Изотоническая регрессия обычно приводит к лучшей эффективности, но более подвержена сверхподбору кривой, если калибровочные данные слишком маленькие [2].

В этом примере вы выполняете калибровку с помощью и Платта, масштабирующегося и изотонической регрессии, и затем сравниваете калибровки с помощью схем надежности.

Извлеките i-векторы

Чтобы правильно калибровать систему, необходимо использовать данные, которые не перекрываются с данными об оценке. Извлеките i-векторы из калибровочного набора. Вы будете использовать эти i-векторы, чтобы создать калибровочную функцию деформирования.

calibrationIvecs = ivector(ivs,adsCalibrate);

Выиграйте Пары i-вектора

Вы выиграете каждый i-вектор друг против друга i-вектор, чтобы создать матрицу баллов, некоторые из которых соответствуют целевым баллам, где оба i-вектора принадлежат тому же динамику, и некоторые из которых соответствуют нецелевым баллам, где i-векторы принадлежат двум различным динамикам. Во-первых, создайте targets матрица, чтобы отслеживать, которых баллы являются целью и которые являются нецелью.

targets = true(size(calibrationIvecs,2),size(calibrationIvecs,2));
calibrationLabels = adsCalibrate.Labels;
for ii = 1:size(calibrationIvecs,2)
    targets(:,ii) = ismember(calibrationLabels,calibrationLabels(ii));
end

Отбросьте целевые баллы, который соответствует i-вектору, выигранному с собой путем устанавливания соответствующего значения в целевой матрице к NaN. Функция поддержки, scoreTargets, баллы каждая допустимая пара i-вектора и возвращают результаты в массивы ячеек целевых и нецелевых баллов.

targets = targets + diag(diag(targets)*nan);
[targetScores,nontargetScores] = scoreTargets(calibrationIvecs,calibrationIvecs,targets);

Используйте функцию поддержки, plotScoreDistrubtions, построить целевые и нецелевые распределения счета для группы. Баллы располагаются от приблизительно 0,64 до 1. В правильно калиброванной системе баллы должны лежать в диапазоне от 0 до 1. Задание калибровки бинарной системы классификации должно сопоставить необработанный счет со счетом между 0 и 1. Калиброванный счет должен быть поддающимся толкованию как вероятность, что счет соответствует целевой паре.

plotScoreDistributions(targetScores,nontargetScores,'Analyze','group')

Платт, масштабирующийся

Платт, масштабирующийся (также называемый калибровкой Платта или логистической регрессией), работает, подбирая модель логистической регрессии к баллам классификатора.

Функция поддержки logistic реализует общую логистическую функцию, определяемую как

p(x)=11+e(B+Ax)

где A и B изученные параметры скаляра.

Функция поддержки logRegCost задает функцию стоимости для логистической регрессии, как задано в [3]:

A,Bargmin{-iyilog(pi)+(1-yi)log(1-pi)}

Как описано в [3], целевые значения изменяются от 0 и 1, чтобы не сверхсоответствовать:

y+=N++1N++2;y-=1N-+2

где y+ положительное демонстрационное значение и N+ количество положительных выборок, и y- отрицательное демонстрационное значение и N- количество отрицательных выборок.

Создайте вектор из необработанных целевых и нецелевых баллов.

tS = cat(1,targetScores{:});
ntS = cat(1,nontargetScores{:});
x = [tS;ntS];

Создайте вектор из идеальных целевых вероятностей.

yplus = (numel(tS) + 1)./(numel(tS) + 2);
yminus = 1./(numel(ntS) + 2);
y = [yplus*ones(numel(tS),1);yminus*ones(numel(ntS),1)];

Используйте fminsearch найти значения A и B, которые минимизируют функцию стоимости.

init = [1,1];
AB = fminsearch(@(AB)logRegCost(y,x,AB),init);

Сортировка музыки в порядке возрастания к целям визуализации.

[x,idx] = sort(x,'ascend');
trueLabel = [ones(numel(tS),1);zeros(numel(ntS),1)];
trueLabel = trueLabel(idx);

Используйте функцию поддержки calibrateScores калибровать необработанные баллы. Постройте деформирующуюся функцию, которая сопоставляет необработанные баллы с калиброванными баллами. Также постройте целевые баллы, которые вы моделируете.

calibratedScores = calibrateScores(x,AB);

plot(x,trueLabel,'o')
hold on
plot(x,calibratedScores,'LineWidth',1.5)
grid on
xlabel('Raw Score')
ylabel('Calibrated Score')
hold off

Оцените Платта, масштабирующегося

Вызовите verify на правильно помеченном динамике, чтобы смотреть необработанный счет и калиброванный счет.

reset(adsDev)
[audioIn,fileInfo] = read(adsDev);
targetLabel = fileInfo.Label;

[decision,rawScore] = verify(ivs,audioIn,targetLabel,'css')
decision = logical
   1

rawScore = 0.8991
calibratedScore = calibrateScores(rawScore,AB)
calibratedScore = 0.9963

Вызовите verify на неправильно помеченном динамике, чтобы смотреть решение, необработанный счет и калиброванный счет.

nontargetIdx = find(~ismember(enrolledLabels,targetLabel));
nontargetLabel = enrolledLabels(nontargetIdx(randperm(numel(nontargetIdx),1)));

[decision,rawScore] = verify(ivs,audioIn,nontargetLabel,'css')
decision = logical
   0

rawScore = 0.8151
calibratedScore = calibrateScores(rawScore,AB)
calibratedScore = 0.0253

Изотоническая регрессия

Изотоническая регрессия соответствует линии свободной формы к наблюдениям с единственным условием, являющимся этим, это не уменьшается (или не увеличивается). Функция поддержки isotonicRegression использует алгоритм пула смежных нарушителей (PAV) [3] для изотонической регрессии.

Вызовите isotonicRegression с необработанным счетом и истинными метками. Функциональные выходные параметры struct, содержащий карту между необработанными баллами и калиброванными баллами.

scoringMap = isotonicRegression(x,trueLabel);

Постройте необработанный счет против калиброванного счета. Линия является изученной изотонической подгонкой. Круги являются данными, которым вы соответствуете.

plot(x,trueLabel,'o')
hold on
plot(scoringMap.Raw,scoringMap.Calibrated,'LineWidth',1.5)
grid on
xlabel('Raw Score')
ylabel('Calibrated Score')
hold off

Оцените изотоническую регрессию

Вызовите verify на правильно помеченном динамике, чтобы смотреть необработанный счет и калиброванный счет.

reset(adsDev)
[audioIn,fileInfo] = read(adsDev);
targetLabel = fileInfo.Label;

[decision,rawScore] = verify(ivs,audioIn,targetLabel,'css')
decision = logical
   1

rawScore = 0.8991
calibratedScore = calibrateScores(rawScore,scoringMap)
calibratedScore = 1

Вызовите verify на неправильно помеченном динамике, чтобы смотреть решение, необработанный счет и калиброванный счет.

nontargetIdx = find(~ismember(enrolledLabels,targetLabel));
nontargetLabel = enrolledLabels(nontargetIdx(1));

[decision,rawScore] = verify(ivs,audioIn,nontargetLabel,'css')
decision = logical
   0

rawScore = 0.8521
calibratedScore = calibrateScores(rawScore,scoringMap)
calibratedScore = 0.5748

Схема надежности

Схемы надежности показывают надежность путем графического вывода среднего значения ожидаемого значения против известной части положительных сторон. Система надежна, если среднее значение ожидаемого значения равно части положительных сторон [4].

Надежность должна быть оценена с помощью различного набора данных, чем тот раньше калибровал систему. Извлеките i-векторы из набора данных разработки, adsDev. Набор данных разработки не имеет никакого перекрытия динамика с калибровочным набором данных.

devIvecs = ivector(ivs,adsDev);

Создайте targets сопоставьте и выиграйте все пары i-вектора.

devLabels = adsDev.Labels;
targets = true(size(devIvecs,2),size(devIvecs,2));
for ii = 1:size(devIvecs,2)
    targets(:,ii) = ismember(devLabels,devLabels(ii));
end
targets = targets + diag(diag(targets)*nan);

[targetScores,nontargetScores] = scoreTargets(devIvecs,devIvecs,targets);

Объедините все баллы и метки для более быстрой обработки.

ts = cat(1,targetScores{:});
nts = cat(1,nontargetScores{:});
scores = [ts;nts];
trueLabels = [true(numel(ts),1);false(numel(nts),1)];

Калибруйте баллы с помощью Платта, масштабирующегося.

calibratedScoresPlattScaling = calibrateScores(scores,AB);

Калибруйте баллы с помощью изотонической регрессии.

calibratedScoresIsotonicRegression = calibrateScores(scores,scoringMap);

При интерпретации схемы надежности значения ниже диагонали указывают, что система дает более высокие баллы вероятности, чем это должно быть, и значения выше диагонали указывают, что система дает более низкие баллы вероятности, чем это должно. В обоих случаях увеличение суммы калибровочных данных и использование калибровочных данных как целевое приложение, должны улучшать производительность.

numBins = 10;

Постройте схему надежности для системы i-вектора, калиброванной с помощью Платта, масштабирующегося.

reliabilityDiagram(trueLabels,calibratedScoresPlattScaling,numBins)

Постройте схему надежности для системы i-вектора, калиброванной с помощью изотонической регрессии.

reliabilityDiagram(trueLabels,calibratedScoresIsotonicRegression,numBins)

Вспомогательные Функции

Загрузите набор данных

function [adsEnroll,adsDev,adsCalibrate] = loadDataset(targetSampleRate)
%LOADDATASET Load PTDB-TUG data set
% [adsEnroll,adsDev,adsCalibrate] = loadDataset(targetSampleteRate)
% downloads the PTDB-TUG data set, resamples it to the specified target
% sample rate and save the results in your current folder. The function
% then creates and returns three audioDatastore objects. The enrollment set
% includes two utterances per speaker. The calibrate set does not overlap
% with the other data sets.

% Copyright 2021 The MathWorks, Inc.

rng(0)
url = 'https://www2.spsc.tugraz.at/databases/PTDB-TUG/SPEECH_DATA_ZIPPED.zip';
downloadFolder = tempdir;
datasetFolder = fullfile(downloadFolder,'PTDB-TUG');

% Download and unzip the dataset if it doesn't already exist.
if ~isfolder(datasetFolder)
    disp('Downloading PTDB-TUG (3.9 G) ...')
    unzip(url,datasetFolder)
end

% Resample the dataset and save to current folder if it doesn't already
% exist.
if ~isfolder(fullfile(pwd,'MIC'))
    ads = audioDatastore([fullfile(datasetFolder,"SPEECH DATA","FEMALE","MIC"),fullfile(datasetFolder,"SPEECH DATA","MALE","MIC")], ...
        'IncludeSubfolders',true, ...
        'FileExtensions','.wav', ...
        'LabelSource','foldernames');
    reduceDataset = false;
    if reduceDataset
        ads = splitEachLabel(ads,10);
    end
    adsTransform = transform(ads,@(x,y)fileResampler(x,y,targetSampleRate),'IncludeInfo',true);
    writeall(adsTransform,pwd,'OutputFormat','flac','UseParallel',~isempty(ver('parallel')))
end

% Create a datastore that points to the resampled dataset. Use the folder
% names as the labels.
ads = audioDatastore(fullfile(pwd,'MIC'),'IncludeSubfolders',true,'LabelSource',"foldernames");

% Split the data set into enrollment, development, and calibration sets.
calibrationLabels = categorical(["M01","M03","M05","M7","M9","F01","F03","F05","F07","F09"]);

adsCalibrate = subset(ads,ismember(ads.Labels,calibrationLabels));

adsDev = subset(ads,~ismember(ads.Labels,calibrationLabels));

numToEnroll = 2;
[adsEnroll,adsDev] = splitEachLabel(adsDev,numToEnroll);

end

Файл Resampler

function [audioOut,adsInfo] = fileResampler(audioIn,adsInfo,targetSampleRate)
%FILERESAMPLER Resample audio files
% [audioOut,adsInfo] = fileResampler(audioIn,adsInfo,targetSampleRate)
% resamples the input audio to the target sample rate and updates the info
% passed through the datastore.

% Copyright 2021 The MathWorks, Inc.

arguments
    audioIn (:,1) {mustBeA(audioIn,{'single','double'})}
    adsInfo (1,1) {mustBeA(adsInfo,'struct')}
    targetSampleRate (1,1) {mustBeNumeric,mustBePositive}
end

% Isolate the original sample rate
originalSampleRate = adsInfo.SampleRate;

% Resample if necessary
if originalSampleRate ~= targetSampleRate
    audioOut = resample(audioIn,targetSampleRate,originalSampleRate);
    amax = max(abs(audioOut));
    if max(amax>1)
        audioOut = audioOut./amax;
    end
end

% Update the info passed through the datastore
adsInfo.SampleRate = targetSampleRate;

end

Выиграйте цели и нецели

function [targetScores,nontargetScores] = scoreTargets(e,t,targetMap,nvargs)
%SCORETARGETS Score i-vector pairs
% [targetScores,nontargetScores] = scoreTargets(e,t,targetMap) exhaustively
% scores i-vectors in e against i-vectors in t. Specify e as an M-by-N
% matrix, where M corresponds to the i-vector dimension, and N corresponds
% to the number of i-vectors in e. Specify t as an M-by-P matrix, where P
% corresponds to the number of i-vectors in t. Specify targetMap as a
% P-by-N numeric matrix that maps which i-vectors in e and t are target
% pairs (derived from the same speaker) and which i-vectors in e and t are
% non-target pairs (derived from different speakers). Values in targetMap
% set to NaN are discarded. The outputs, targetScores and nontargetScores,
% are N-element cell arrays. Each cell contains a vector of scores between
% the i-vector in e and either all the targets or nontargets in t.
%
% [targetScores,nontargetScores] =
% scoreTargets(e,t,targetMap,'NormFactorsSe',NFSe,'NormFactorsSt',NFSt)
% normalizes the scores by the specified normalization statistics contained
% in structs NFSe and NFSt. If unspecified, no normalization is applied.

% Copyright 2021 The MathWorks, Inc.

arguments
    e (:,:) {mustBeA(e,{'single','double'})}
    t (:,:) {mustBeA(t,{'single','double'})}
    targetMap (:,:)
    nvargs.NormFactorsSe = [];
    nvargs.NormFactorsSt = [];
end

% Score the i-vector pairs
scores = cosineSimilarityScore(e,t);

% Apply as-norm1 if normalization factors supplied.
if ~isempty(nvargs.NormFactorsSe) && ~isempty(nvargs.NormFactorsSt)
    scores = 0.5*( (scores - nvargs.NormFactorsSe.mu)./nvargs.NormFactorsSe.std + (scores - nvargs.NormFactorsSt.mu')./nvargs.NormFactorsSt.std' );
end

% Separate the scores into targets and non-targets
targetScores = cell(size(targetMap,2),1);
nontargetScores = cell(size(targetMap,2),1);
removeIndex = isnan(targetMap);
for ii = 1:size(targetMap,2)
    localScores = scores(:,ii);
    localMap = targetMap(:,ii);
    localScores(removeIndex(:,ii)) = [];
    localMap(removeIndex(:,ii)) = [];

    targetScores{ii} = localScores(logical(localMap));
    nontargetScores{ii} = localScores(~localMap);
end
end

Счет подобия косинуса (CSS)

function scores = cosineSimilarityScore(a,b)
%COSINESIMILARITYSCORE Cosine similarity score
% scores = cosineSimilarityScore(a,b) scores matrix of i-vectors, a,
% against matrix of i-vectors b. Specify a as an M-by-N matrix of
% i-vectors. Specify b as an M-by-P matrix of i-vectors. scores is returned
% as a P-by-N matrix, where columns corresponds the i-vectors in a
% and rows corresponds to the i-vectors in b and the elements of the array
% are the cosine similarity scores between them.

% Copyright 2021 The MathWorks, Inc.

arguments
    a (:,:) {mustBeA(a,{'single','double'})}
    b (:,:) {mustBeA(b,{'single','double'})}
end

scores = squeeze(sum(a.*reshape(b,size(b,1),1,[]),1)./(vecnorm(a).*reshape(vecnorm(b),1,1,[])));
scores = scores';
end

Постройте распределения счета

function plotScoreDistributions(targetScores,nontargetScores,nvargs)
%PLOTSCOREDISTRIBUTIONS Plot target and non-target score distributions
% plotScoreDistribution(targetScores,nontargetScores) plots empirical
% estimations of the distribution for target scores and nontarget scores.
% Specify targetScores and nontargetScores as cell arrays where each
% element contains a vector of speaker-specific scores.
%
% plotScoreDistrubtions(targetScores,nontargetScores,'Analyze',ANALYZE)
% specifies the scope for analysis as either 'label' or 'group'. If ANALYZE
% is set to 'label', then a score distribution plot is created for each
% label. If ANALYZE is set to 'group', then a score distribution plot is
% created for the entire group by combining scores across speakers. If
% unspecified, ANALYZE defaults to 'group'.

% Copyright 2021 The MathWorks, Inc.

arguments
    targetScores (1,:) cell
    nontargetScores (1,:) cell
    nvargs.Analyze (1,:) char {mustBeMember(nvargs.Analyze,{'label','group'})} = 'group'
end

% Combine all scores to determine good bins for analyzing both the target
% and non-target scores together.
allScores = cat(1,targetScores{:},nontargetScores{:});
[~,edges] = histcounts(allScores);

% Determine the center of each bin for plotting purposes.
centers = movmedian(edges(:),2,'Endpoints','discard');

if strcmpi(nvargs.Analyze,'group')
     % Plot the score distributions for the group.

    targetScoresBinCounts = histcounts(cat(1,targetScores{:}),edges);
    targetScoresBinProb = targetScoresBinCounts(:)./sum(targetScoresBinCounts);
    nontargetScoresBinCounts = histcounts(cat(1,nontargetScores{:}),edges);
    nontargetScoresBinProb = nontargetScoresBinCounts(:)./sum(nontargetScoresBinCounts);

    figure
    plot(centers,[targetScoresBinProb,nontargetScoresBinProb])
    title("Score Distributions")
    xlabel('Score')
    ylabel('Probability')
    legend(["target","non-target"],'Location','northwest')
    axis tight

else

    % Create a tiled layout and plot the score distributions for each speaker.

    N = numel(targetScores);
    tiledlayout(N,1)
    for ii = 1:N
        targetScoresBinCounts = histcounts(targetScores{ii},edges);
        targetScoresBinProb = targetScoresBinCounts(:)./sum(targetScoresBinCounts);
        nontargetScoresBinCounts = histcounts(nontargetScores{ii},edges);
        nontargetScoresBinProb = nontargetScoresBinCounts(:)./sum(nontargetScoresBinCounts);
        nexttile
        hold on
        plot(centers,[targetScoresBinProb,nontargetScoresBinProb])
        title("Score Distribution for Speaker " + string(ii))
        xlabel('Score')
        ylabel('Probability')
        legend(["target","non-target"],'Location','northwest')
        axis tight
    end
end
end

Калибруйте баллы

function y = calibrateScores(score,scoreMapping)
%CALIBRATESCORES Calibrate scores
% y = calibrateScores(score,scoreMapping) maps the raw scores to calibrated
% scores, y, using the score mappinging information in scoreMapping.
% Specify score as a vector or matrix of raw scores. Specify score mapping
% as either struct or a two-element vector. If scoreMapping is specified as
% a struct, then it should have two fields: Raw and Calibrated, that
% together form a score mapping. If scoreMapping is specified as a vector,
% then the elements are used as the coefficients in the logistic function.
% y is returned as vector or matrix the same size as the raw scores.

% Copyright 2021 The MathWorks, Inc.

arguments
    score (:,:) {mustBeA(score,{'single','double'})}
    scoreMapping
end

if isstruct(scoreMapping)
    % Calibration using isotonic regression

    rawScore = scoreMapping.Raw;
    interpretedScore = scoreMapping.Calibrated;

    n = numel(score);

    % Find the index of the raw score in the mapping closest to the score provided.
    idx = zeros(n,1);
    for ii = 1:n
        [~,idx(ii)] = min(abs(score(ii)-rawScore));
    end

    % Get the calibrated score.
    y = interpretedScore(idx);

else

    % Calibration using logistic regression
    y = logistic(score,scoreMapping);

end
end

Схема надежности

function reliabilityDiagram(targets,predictions,numBins)
%RELIABILITYDIAGRAM Plot reliability diagram
% reliabilityDiagram(targets,predictions) plots a reliability diagram for
% targets and predictions. Specify targets an M-by-1 logical vector.
% Specify predictions as an M-by-1 numeric vector.
%
% reliabilityDiagram(targets,predictions,numBins) specifies the number of
% bins for the reliability diagram. If unspecified, numBins defaults to 10.

% Copyright 2021 The MathWorks, Inc.

arguments
    targets (:,1) {mustBeA(targets,{'logical'})}
    predictions (:,1) {mustBeA(predictions,{'single','double'})}
    numBins (1,1) {mustBePositive,mustBeInteger} = 10;
end

% Bin the predictions into the requested number of bins. Count the number of
% predictions per bin.
[predictionsPerBin,~,predictionsInBin] = histcounts(predictions,numBins);

% Determine the mean of the predictions in the bin.
meanPredictions = accumarray(predictionsInBin,predictions)./predictionsPerBin(:);

% Determine the mean of the targets per bin. This is the fraction of
% positives--the number of targets in the bin over the total number of
% predictions in the bin.
meanTargets = accumarray(predictionsInBin,targets)./predictionsPerBin(:);

plot([0,1],[0,1])
hold on
plot(meanPredictions,meanTargets,'o')
legend('Ideal Calibration','Location','best')
xlabel('Mean Predicted Value')
ylabel('Fraction of Positives')
title('Reliability Diagram')
grid on
hold off

end

Функция стоимости логистической регрессии

function cost = logRegCost(y,f,iparams)
%LOGREGCOST Logistic regression cost
% cost = logRegCost(y,f,iparams) calculates the cost of the logistic
% function given truth y, prediction f, and logistic params iparams.
% Specify y and f as column vectors. Specify iparams as a two-element row
% vector in the form [A,B], where A and B are the model parameters:
%
%                1
% p(x) = ------------------
%         1 + e^(-A*f - B)
%

% Copyright 2021 The MathWorks, Inc.

arguments
    y (:,1) {mustBeA(y,{'single','double'})}
    f (:,1) {mustBeA(f,{'single','double'})}
    iparams (1,2) {mustBeA(iparams,{'single','double'})}
end
p = logistic(f,iparams);
cost = -sum(y.*log(p) + (1-y).*log(1-p));
end

Логистическая функция

function p = logistic(f,iparams)
%LOGISTIC Logistic function
% p = logistic(f,iparams) applies the general logistic function to input f
% with parameters iparams. Specify f as a numeric array. Specify iparams as
% a two-element vector. p is returned as the same size as f.

% Copyright 2021 The MathWorks, Inc.

arguments
    f
    iparams = [1 0];
end
p = 1./(1+exp(-iparams(1).*f - iparams(2)));
end

Изотоническая регрессия

function scoreMapping = isotonicRegression(x,y)
%ISOTONICREGRESSION Isotonic regression
% scoreMapping = isotonicRegression(x,y) fits a line yhat to data y under
% the monotonicity constraint that x(i)>x(j) -> yhat(i)>=yhat(j). That is,
% the values in yhat are monotontically non-decreasing with respect to x.
% The output, scoreMapping, is a struct containing the changepoints of yhat
% and the corresponding raw score in x.

% Copyright 2021, The MathWorks, Inc.

N = numel(x);

% Sort points in ascending order of x.
[x,idx] = sort(x(:),'ascend'); 
y = y(idx);

% Initialize fitted values to the given values.
m = y;

% Initialize blocks, one per point. These will merge and the number of
% blocks will reduce as the algorithm proceeds.
blockMap = 1:N;
w = ones(size(m));

while true

    diffs = diff(m);
    
    if all(diffs >= 0)

        % If all blocks are monotonic, end the loop.
        break;

    else

        % Find all positive changepoints. These are the beginnings of each
        % block.
        blockStartIndex = diffs>0;

        % Create group indices for each unique block.
        blockIndices = cumsum([1;blockStartIndex]);

        % Calculate the mean of each block and update the weights for the
        % blocks. We're merging all the points in the blocks here.
        m = accumarray(blockIndices,w.*m);
        w = accumarray(blockIndices,w);
        m = m ./ w;

        % Map which block corresponds to which index.
        blockMap = blockIndices(blockMap);

    end
end

% Broadcast merged blocks out to original points.
m = m(blockMap);

% Find the changepoints
changepoints = find(diff(m)>0);
changepoints = [changepoints;changepoints+1];
changepoints = sort(changepoints);

% Remove all points that aren't changepoints.
a = m(changepoints);
b = x(changepoints);

scoreMapping = struct('Raw',b,'Calibrated',a);
end

Ссылки

[1] Г. Пиркер, М. Уохлмэр, С. Петрик и Ф. Пернкопф, "Корпус Отслеживания Тангажа с Оценкой на Сценарии Отслеживания Мультитангажа", Межречь, стр 1509-1512, 2011.

[2] ван Лиувен, Дэвид А. и Нико Браммер. "Введение в Не зависящую от приложения Оценку Систем Распознавания Динамика". Читайте лекции Примечаниям в Информатике, 2007, 330–53.

[3] Никулеску-Мизил, A., & Каруана, R. (2005). Предсказание хороших вероятностей с контролируемым изучением. Продолжения 22-й Международной конференции по вопросам Машинного обучения - ICML '05. doi:10.1145/1102351.1102430

[4] Brocker, Йохен и Леонард А. Смит. “Увеличивая Надежность Схем Надежности”. Погода и Прогнозирование 22, № 3 (2007): 651–61. https://doi.org/10.1175/waf993.1.