Выберите количество тем для модели LDA

В этом примере показано, как решить подходящее количество тем для модели латентного распределения Дирихле (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, выполняет следующие шаги по порядку:

  1. Преобразуйте текстовые данные в строчные с помощью lower.

  2. Токенизация текста с помощью tokenizedDocument.

  3. Удалите пунктуацию с помощью erasePunctuation.

  4. Удалите список стоповых слов (таких как «and», «of», и «the») с помощью removeStopWords.

  5. Удалите слова с 2 или меньшим количеством символов, используя removeShortWords.

  6. Удалите слова с 15 или более символами, используя removeLongWords.

  7. Лемматизируйте слова, используя 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

См. также

| | | | | | | | | | | | |

Похожие темы