В этом примере показано, как решить подходящее количество тем для модели латентного распределения Дирихле (LDA).
Чтобы определиться с подходящим количеством тем, можно сравнить качество подгонки моделей LDA с различной подгонкой тем. Можно оценить качество подгонки модели LDA, вычислив недоумение удерживаемого набора документов. Недоумение указывает, насколько хорошо модель описывает набор документов. Меньшее недоумение предполагает лучшую подгонку.
Загрузите данные примера. Файл factoryReports.csv
содержит заводские отчеты, включая текстовое описание и категориальные метки для каждого события. Извлеките текстовые данные из поля Description
.
filename = "factoryReports.csv"; data = readtable(filename,'TextType','string'); textData = data.Description;
Токенизация и предварительная обработка текстовых данных с помощью функции preprocessText
который перечислен в конце этого примера.
documents = preprocessText(textData); documents(1:5)
ans = 5×1 tokenizedDocument: 6 tokens: item occasionally get stuck scanner spool 7 tokens: loud rattle bang sound come assembler piston 4 tokens: cut power start plant 3 tokens: fry capacitor assembler 3 tokens: mixer trip fuse
Выделите 10% документов случайным образом для валидации.
numDocuments = numel(documents);
cvp = cvpartition(numDocuments,'HoldOut',0.1);
documentsTrain = documents(cvp.training);
documentsValidation = documents(cvp.test);
Создайте модель мешка слов из обучающих документов. Удалите слова, которые не появляются более двух раз в общей сложности. Удалите все документы, не содержащие слов.
bag = bagOfWords(documentsTrain); bag = removeInfrequentWords(bag,2); bag = removeEmptyDocuments(bag);
Цель состоит в том, чтобы выбрать ряд тем, которые минимизируют недоумение по сравнению с другим количеством тем. Это не единственный фактор: для сближения моделей, соответствующих большему количеству тем, может потребоваться больше времени. Чтобы увидеть эффекты компромисса, вычислите и качество подгонки, и время подгонки. Если оптимальное количество тем велико, тогда вы можете выбрать меньшее значение, чтобы ускорить процесс подгонки.
Подгонка некоторых моделей LDA для области значений значений для количества тем. Сравните время подгонки и недоумение каждой модели на сохраненном наборе тестовых документов. Недоумение является вторым выходом в logp
функция. Чтобы получить второй выход, не присваивая первый выход чему-либо, используйте ~
символ. Время подгонки является TimeSinceStart
значение для последней итерации. Это значение находится в History
struct FitInfo
свойство модели LDA.
Для более быстрой подгонки задайте 'Solver'
чтобы быть 'savb'
. Чтобы подавить подробный выход, установите 'Verbose'
на 0
. Это может занять несколько минут.
numTopicsRange = [5 10 15 20 40]; for i = 1:numel(numTopicsRange) numTopics = numTopicsRange(i); mdl = fitlda(bag,numTopics, ... 'Solver','savb', ... 'Verbose',0); [~,validationPerplexity(i)] = logp(mdl,documentsValidation); timeElapsed(i) = mdl.FitInfo.History.TimeSinceStart(end); end
Покажите недоумение и прошедшее время для каждого количества тем на графике. Постройте график недоумения на левой оси и времени, прошедшего на правой оси.
figure yyaxis left plot(numTopicsRange,validationPerplexity,'+-') ylabel("Validation Perplexity") yyaxis right plot(numTopicsRange,timeElapsed,'o-') ylabel("Time Elapsed (s)") legend(["Validation Perplexity" "Time Elapsed (s)"],'Location','southeast') xlabel("Number of Topics")
График предполагает, что подгонка модели с 10-20 темами может быть хорошим выбором. Недоумение невелико по сравнению с моделями с разным количеством тем. С помощью этого решателя прошло время для этого многих тем также разумно. С помощью других решателей можно обнаружить, что увеличение количества тем может привести к лучшему подгонке, но подбор кривой модели занимает больше времени, чтобы сходиться.
Функция preprocessText
, выполняет следующие шаги по порядку:
Преобразуйте текстовые данные в строчные с помощью lower
.
Токенизация текста с помощью tokenizedDocument
.
Удалите пунктуацию с помощью erasePunctuation
.
Удалите список стоповых слов (таких как «and», «of», и «the») с помощью removeStopWords
.
Удалите слова с 2 или меньшим количеством символов, используя removeShortWords
.
Удалите слова с 15 или более символами, используя removeLongWords
.
Лемматизируйте слова, используя normalizeWords
.
function documents = preprocessText(textData) % Convert the text data to lowercase. cleanTextData = lower(textData); % Tokenize the text. documents = tokenizedDocument(cleanTextData); % 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); % Lemmatize the words. documents = addPartOfSpeechDetails(documents); documents = normalizeWords(documents,'Style','lemma'); end
addPartOfSpeechDetails
| bagOfWords
| bagOfWords
| erasePunctuation
| fitlda
| ldaModel
| logp
| normalizeWords
| removeEmptyDocuments
| removeInfrequentWords
| removeLongWords
| removeShortWords
| removeStopWords
| tokenizedDocument