В этом примере показано, как сравнить решатели скрытого выделения Дирихле (LDA) путем сравнения качества подгонки и время, потраченное, чтобы подбирать модель.
Чтобы воспроизвести результаты этого примера, установите rng
к 'default'
.
rng('default')
Загрузите данные в качестве примера. Файл weatherReports.csv
содержит прогнозы погоды, включая текстовое описание и категориальные метки для каждого события. Извлеките текстовые данные из поля event_narrative
.
filename = "weatherReports.csv"; data = readtable(filename,'TextType','string'); textData = data.event_narrative;
Отложите 10% документов наугад для валидации.
numDocuments = numel(textData);
cvp = cvpartition(numDocuments,'HoldOut',0.1);
textDataTrain = textData(training(cvp));
textDataValidation = textData(test(cvp));
Маркируйте и предварительно обработайте текстовые данные с помощью функционального preprocessText
который перечислен в конце этого примера.
documentsTrain = preprocessText(textDataTrain); documentsValidation = preprocessText(textDataValidation);
Создайте модель сумки слов из учебных материалов. Удалите слова, которые не появляются больше чем два раза всего. Удалите любые документы, содержащие слова.
bag = bagOfWords(documentsTrain); bag = removeInfrequentWords(bag,2); bag = removeEmptyDocuments(bag);
Для каждого из решателей LDA подбирайте модель LDA с 60 темами. Чтобы отличить решатели при графическом выводе результатов на тех же осях, задайте различные свойства линии для каждого решателя.
numTopics = 60; solvers = ["cgs" "avb" "cvb0" "savb"]; lineSpecs = ["+-" "*-" "x-" "o-"];
Для данных о валидации создайте модель сумки слов из документов валидации.
validationData = bagOfWords(documentsValidation);
Для каждого из решателей LDA подбирайте модель, установите начальную концентрацию темы на 1 и задайте, чтобы не соответствовать параметру концентрации темы. Используя данные в FitInfo
свойство подбиравших моделей LDA, постройте недоумение валидации, и время протекло. Постройте время, истекшее в логарифмическом масштабе. Это может занять до часа, чтобы запуститься.
Код для удаления NaNs необходим из-за причуды стохастического решателя 'savb'
. Для этого решателя функция оценивает недоумение валидации после каждой передачи данных. Функция не оценивает недоумение валидации для каждой итерации (мини-пакет) и сообщает о NaNs в FitInfo
свойство. Чтобы построить недоумение валидации, удалите NaNs из значений, о которых сообщают.
figure for i = 1:numel(solvers) solver = solvers(i); lineSpec = lineSpecs(i); mdl = fitlda(bag,numTopics, ... 'Solver',solver, ... 'InitialTopicConcentration',1, ... 'FitTopicConcentration',false, ... 'ValidationData',validationData, ... 'Verbose',0); history = mdl.FitInfo.History; timeElapsed = history.TimeSinceStart; validationPerplexity = history.ValidationPerplexity; % Remove NaNs. idx = isnan(validationPerplexity); timeElapsed(idx) = []; validationPerplexity(idx) = []; semilogx(timeElapsed,validationPerplexity,lineSpec) hold on end hold off xlabel("Time Elapsed (s)") ylabel("Validation Perplexity") legend(solvers)
Для стохастического решателя "savb"
, функция, по умолчанию, проходит через обучающие данные однажды. Чтобы обработать больше передач данных, установите 'DataPassLimit'
к большему значению (значение по умолчанию равняется 1). Для пакетных решателей ("cgs"
, "avb"
, и "cvb0"
), сокращать количество итераций раньше подбирало модели, устанавливало 'IterationLimit'
опция к нижнему значению (значение по умолчанию равняется 100).
Более низкое недоумение валидации предлагает лучшую подгонку. Обычно, решатели "savb"
и "cgs"
сходитесь быстро к хорошей подгонке. Решатель "cvb0"
может сходиться к лучшей подгонке, но она может взять намного дольше, чтобы сходиться.
Для FitInfo
свойство, fitlda
функционируйте оценивает недоумение валидации от вероятностей документа в оценках наибольшего правдоподобия вероятностей на тематику документа. Это обычно быстрее, чтобы вычислить, но может быть менее точным, чем другие методы. В качестве альтернативы вычислите недоумение валидации с помощью logp
функция. Эта функция вычисляет более точные значения, но может занять больше времени, чтобы запуститься. Для примера, показывающего, как вычислить недоумение с помощью logp
, смотрите Вычисляют Логарифмические Вероятности Документа из Матрицы Для подсчета количества слов.
Функциональный preprocessText
выполняет следующие шаги:
Маркируйте текст с помощью tokenizedDocument
.
Lemmatize слова с помощью normalizeWords
.
Сотрите пунктуацию с помощью erasePunctuation
.
Удалите список слов остановки (такой как "и", и) использование removeStopWords
.
Удалите слова с 2 или меньшим количеством символов с помощью removeShortWords
.
Удалите слова с 15 или больше символами с помощью removeLongWords
.
function documents = preprocessText(textData) % Tokenize the text. documents = tokenizedDocument(textData); % Lemmatize the words. documents = addPartOfSpeechDetails(documents); documents = normalizeWords(documents,'Style','lemma'); % Erase punctuation. documents = erasePunctuation(documents); % Remove a list of stop words. documents = removeStopWords(documents); % Remove words with 2 or fewer characters, and words with 15 or greater % characters. documents = removeShortWords(documents,2); documents = removeLongWords(documents,15); end
addPartOfSpeechDetails
| bagOfWords
| erasePunctuation
| fitlda
| ldaModel
| logp
| normalizeWords
| removeEmptyDocuments
| removeInfrequentWords
| removeLongWords
| removeShortWords
| removeStopWords
| tokenizedDocument
| wordcloud