Этот пример показывает, как обучить простой текстовый классификатор на количествах частотности слова с помощью модели сумки слов.
Можно создать простую модель классификации, которая использует количества частотности слова в качестве предикторов. Этот пример обучает простую модель классификации предсказывать тип события прогнозов погоды с помощью текстовых описаний.
Чтобы воспроизвести результаты этого примера, установите rng
на 'default'
.
rng('default')
Загрузите данные в качестве примера. Файл weatherReports.csv
содержит прогнозы погоды, включая текстовое описание и категориальные метки для каждого события.
filename = "weatherReports.csv"; data = readtable(filename,'TextType','string'); head(data)
ans=8×16 table
Time event_id state event_type damage_property damage_crops begin_lat begin_lon end_lat end_lon event_narrative storm_duration begin_day end_day year end_timestamp
____________________ __________ ________________ ___________________ _______________ ____________ _________ _________ _______ _______ _________________________________________________________________________________________________________________________________________________________________________________________________ ______________ _________ _______ ____ ____________________
22-Jul-2016 16:10:00 6.4433e+05 "MISSISSIPPI" "Thunderstorm Wind" "" "0.00K" 34.14 -88.63 34.122 -88.626 "Large tree down between Plantersville and Nettleton." 00:05:00 22 22 2016 22-Jul-0016 16:15:00
15-Jul-2016 17:15:00 6.5182e+05 "SOUTH CAROLINA" "Heavy Rain" "2.00K" "0.00K" 34.94 -81.03 34.94 -81.03 "One to two feet of deep standing water developed on a street on the Winthrop University campus after more than an inch of rain fell in less than an hour. One vehicle was stalled in the water." 00:00:00 15 15 2016 15-Jul-0016 17:15:00
15-Jul-2016 17:25:00 6.5183e+05 "SOUTH CAROLINA" "Thunderstorm Wind" "0.00K" "0.00K" 35.01 -80.93 35.01 -80.93 "NWS Columbia relayed a report of trees blown down along Tom Hall St." 00:00:00 15 15 2016 15-Jul-0016 17:25:00
16-Jul-2016 12:46:00 6.5183e+05 "NORTH CAROLINA" "Thunderstorm Wind" "0.00K" "0.00K" 35.64 -82.14 35.64 -82.14 "Media reported two trees blown down along I-40 in the Old Fort area." 00:00:00 16 16 2016 16-Jul-0016 12:46:00
15-Jul-2016 14:28:00 6.4332e+05 "MISSOURI" "Hail" "" "" 36.45 -89.97 36.45 -89.97 "" 00:07:00 15 15 2016 15-Jul-0016 14:35:00
15-Jul-2016 16:31:00 6.4332e+05 "ARKANSAS" "Thunderstorm Wind" "" "0.00K" 35.85 -90.1 35.838 -90.087 "A few tree limbs greater than 6 inches down on HWY 18 in Roseland." 00:09:00 15 15 2016 15-Jul-0016 16:40:00
15-Jul-2016 16:03:00 6.4343e+05 "TENNESSEE" "Thunderstorm Wind" "20.00K" "0.00K" 35.056 -89.937 35.05 -89.904 "Awning blown off a building on Lamar Avenue. Multiple trees down near the intersection of Winchester and Perkins." 00:07:00 15 15 2016 15-Jul-0016 16:10:00
15-Jul-2016 17:27:00 6.4344e+05 "TENNESSEE" "Hail" "" "" 35.385 -89.78 35.385 -89.78 "Quarter size hail near Rosemark." 00:05:00 15 15 2016 15-Jul-0016 17:32:00
Удалите строки с пустыми отчетами.
idx = strlength(data.event_narrative) == 0; data(idx,:) = [];
Преобразуйте метки в столбце event_type
таблицы к категориальному и просмотрите распределение классов в данных с помощью гистограммы.
data.event_type = categorical(data.event_type); figure h = histogram(data.event_type); xlabel("Class") ylabel("Frequency") title("Class Distribution")
Классы данных являются неустойчивыми с несколькими классами, содержащими немного наблюдений. Чтобы гарантировать, что можно разделить данные так, чтобы разделы содержали наблюдения для каждого класса, удалите любые классы, которые появляются меньше чем десять раз.
Получите подсчет частот классов и их имен от гистограммы.
classCounts = h.BinCounts; classNames = h.Categories;
Найдите классы, содержащие меньше чем десять наблюдений, и удалите эти нечастые классы из данных.
idxLowCounts = classCounts < 10; infrequentClasses = classNames(idxLowCounts); idxInfrequent = ismember(data.event_type,infrequentClasses); data(idxInfrequent,:) = [];
Разделите данные в учебный раздел и протянутый набор тестов. Задайте процент затяжки, чтобы быть 10%.
cvp = cvpartition(data.event_type,'Holdout',0.1);
dataTrain = data(cvp.training,:);
dataTest = data(cvp.test,:);
Извлеките текстовые данные и метки из таблиц.
textDataTrain = dataTrain.event_narrative; textDataTest = dataTest.event_narrative; YTrain = dataTrain.event_type; YTest = dataTest.event_type;
Создайте функцию, которая маркирует и предварительно обрабатывает текстовые данные, таким образом, они могут использоваться для анализа. Функциональный preprocessWeatherNarratives
, выполняет следующие шаги по порядку:
Маркируйте текст с помощью tokenizedDocument
.
Lemmatize слова с помощью normalizeWords
.
Сотрите пунктуацию с помощью erasePunctuation
.
Удалите список слов остановки (такой как "и", и) использование removeStopWords
.
Удалите слова с 2 или меньшим количеством символов с помощью removeShortWords
.
Удалите слова с 15 или больше символами с помощью removeLongWords
.
Используйте пример, предварительно обрабатывающий функциональный preprocessWeatherNarratives
, чтобы подготовить текстовые данные.
documents = preprocessWeatherNarratives(textDataTrain); documents(1:5)
ans = 5×1 tokenizedDocument: 5 tokens: large tree down plantersville nettleton 18 tokens: two foot deep standing water develop street winthrop university campus inch rain fall less hour vehicle stall water 9 tokens: nws columbia relay report tree blow down tom hall 10 tokens: medium report two tree blow down i40 old fort area 8 tokens: few tree limb great inch down hwy roseland
Создайте модель сумки слов из маркируемых документов.
bag = bagOfWords(documents)
bag = bagOfWords with properties: Counts: [25316×17524 double] Vocabulary: [1×17524 string] NumWords: 17524 NumDocuments: 25316
Удалите слова из модели сумки слов, которые не появляются больше чем два раза всего. Удалите любые документы, содержащие слова из модели сумки слов, и удалите соответствующие записи в метках.
bag = removeInfrequentWords(bag,2); [bag,idx] = removeEmptyDocuments(bag); YTrain(idx) = []; bag
bag = bagOfWords with properties: Counts: [25315×6534 double] Vocabulary: [1×6534 string] NumWords: 6534 NumDocuments: 25315
Обучите контролируемую модель классификации использование количеств частотности слова из модели сумки слов и меток.
Обучите мультикласс линейная модель классификации использование fitcecoc
. Задайте свойство Counts
модели сумки слов быть предикторами и метками типа события, чтобы быть ответом. Задайте учеников, чтобы быть линейными. Эти ученики поддерживают разреженный ввод данных.
XTrain = bag.Counts; mdl = fitcecoc(XTrain,YTrain,'Learners','linear')
mdl = classreg.learning.classif.CompactClassificationECOC ResponseName: 'Y' ClassNames: [1×39 categorical] ScoreTransform: 'none' BinaryLearners: {741×1 cell} CodingMatrix: [39×741 double] Properties, Methods
Для лучшей подгонки можно попытаться задать различные параметры линейных учеников. Для получения дополнительной информации о линейных шаблонах ученика классификации смотрите templateLinear
.
Предскажите метки тестовых данных с помощью обученной модели и вычислите точность классификации. Точность классификации является пропорцией меток, которые модель предсказывает правильно.
Предварительно обработайте тестовые данные с помощью тех же шагов предварительной обработки в качестве данных тренировки. Закодируйте получившиеся тестовые документы как матрицу количеств частотности слова согласно модели сумки слов.
documentsTest = preprocessWeatherNarratives(textDataTest); XTest = encode(bag,documentsTest);
Предскажите метки тестовых данных с помощью обученной модели и вычислите точность классификации.
YPred = predict(mdl,XTest); acc = sum(YPred == YTest)/numel(YTest)
acc = 0.8808
Классифицируйте тип события новых прогнозов погоды. Создайте массив строк, содержащий новые прогнозы погоды.
str = [ ... "A large tree is downed and blocking traffic outside Apple Hill." "Damage to many car windshields in parking lot." "Lots of water damage to computer equipment inside the office."]; documentsNew = preprocessWeatherNarratives(str); XNew = encode(bag,documentsNew); labelsNew = predict(mdl,XNew)
labelsNew = 3×1 categorical array
Thunderstorm Wind
Thunderstorm Wind
Flash Flood
Функциональный preprocessWeatherNarratives
, выполняет следующие шаги по порядку:
Маркируйте текст с помощью tokenizedDocument
.
Lemmatize слова с помощью normalizeWords
.
Сотрите пунктуацию с помощью erasePunctuation
.
Удалите список слов остановки (такой как "и", и) использование removeStopWords
.
Удалите слова с 2 или меньшим количеством символов с помощью removeShortWords
.
Удалите слова с 15 или больше символами с помощью removeLongWords
.
function documents = preprocessWeatherNarratives(textData) % Tokenize the text. documents = tokenizedDocument(textData); % Lemmatize the words. To improve lemmatization, first use % addPartOfSpeechDetails. 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 more % characters. documents = removeShortWords(documents,2); documents = removeLongWords(documents,15); end
addPartOfSpeechDetails
| bagOfWords
| encode
| erasePunctuation
| normalizeWords
| removeLongWords
| removeShortWords
| removeStopWords
| tokenizedDocument
| wordcloud