Обработка естественного языка
Текст в вектор | Обработка естественного языка в JavaScript
Обработка естественного языка — это метод или область машинного обучения, в которой мы пытаемся найти смысл или найти закономерность в текстовых данных.
Самый простой пример — обзоры продуктов, и мы также будем использовать образцы данных обзоров для упражнений.
как мы знаем, методы машинного обучения (математики) применяются только к числовым данным, поэтому мы также преобразуем наши текстовые данные в числовые данные, и каждое слово как функция позволяет увидеть его на примере
скажем, у нас есть некоторые данные отзывов, как показано ниже
всего 7 отзывов
каждый отзыв состоит из текста и оценки
оценка 1 означает положительный отзыв, а оценка 0 означает отрицательный отзыв
const review = [ { text: "this product is amazing", score: 1 }, { text: "this product is great", score: 1 }, { text: "this product is horrible", score: 0 }, { text: "this product is bad", score: 0 }, { text: "this is amazing and tasty food", score: 1 }, { text: "this food is fabulus", score: 1 }, { text: "this product is tasteless", score: 0 }, { text: "this smells bad", score: 0 }, ];
если мы увидим это в таблице, это будет выглядеть примерно так
Мешок слов
Сумка слов - это просто сумка или набор слов и их количество в предложении.
он также известен как частота терминов, поскольку он подсчитывает появление слова в предложении.
Стоп-слова — это слова, которые оказывают меньшее влияние на результаты, например, это их так много слов, но сейчас мы будем использовать только ограниченный набор слов для нашего примера.
шаги:
- Получить все слова во всех обзорах
- Для каждого предложения подсчитайте, сколько раз встречается это слово
const stopwords = ["is", "this", "are"]; // step 1 const totalWords = [ ...new Set( review.flatMap((a) => a.text.split(" ").filter((a) => stopwords.indexOf(a) === -1) ) ), ]; console.log(totalWords) output will be ['product', 'amazing', 'great', 'horrible', 'bad', 'and', 'tasty', 'food', 'fabulus', 'tasteless', 'smells']
Теперь все эти слова являются нашими функциями, и мы посмотрим, как каждое слово влияет на оценку.
Теперь шаг 2. Для каждого предложения подсчитайте, сколько раз встречается это слово.
const bagOfWords = review.map((a) => { const obj = {}; totalWords.forEach((key) => { obj[key] = a.text.includes(key) ? 1 : 0; }); return obj; }); console.table(bagOfWords)
На изображении выше показано, сколько раз слова появлялись в предложении, например
отзыв: этот продукт потрясающий
он состоит из 3 слов (так как они будут удалены стоп-словами на шаге 1), и в таблице мы видим, что в первой строке «этот» «продукт» «изумительный» имеет значение 1, а другие имеют значение 0
Проблема с мешком слов
если мы видим первую строку для всех 3 слов «этот», «продукт», «удивительный», мы имеем одинаковое значение, которое равно единице, и нам трудно определить влияние слов
например, «это» слово не так полезно для положительных отзывов, аналогично «продукт» также бесполезен для положительной оценки, поэтому им следует придавать меньшее значение, а «потрясающему» следует придавать больший вес.
TF-IDF (Термин Частота Обратной Частоты Документа)
поскольку мы подсчитали частоту термина, мы посчитаем обратную частоту документа и умножим оба
так что в коде это будет очень просто
- Рассчитайте количество предложений, содержащих каждое слово из нашего шага 1 выше
const WordsWithSentences = [ ...new Set( totalWords.map((a) => { return { word: a, reviews: review.filter((b) => b.text.includes(a)).length, }; }) ), ]; console.log('WordsWithSentences', WordsWithSentences);
Таким образом, это в основном похоже на то, что продукт присутствует в 5 обзорах
удивительный присутствует в двух обзорах и так далее.
2. Рассчитать Td-Idf для каждого слова
const tfidf = reviews.map((a) => { const obj = {}; const totalWordsInReview = a.text.split(" ").length; totalWords.forEach((key) => { const numberOfSentenceswithTheWord = WordsWithSentences.find( (b) => b.word == key ); // calculate Tf const tf = (a.text.includes(key) ? 1 : 0) / totalWordsInReview; // calculate IDF const idf = Math.log( numberOfReviews / numberOfSentencesContainingTheWords.reviews ); // multiple both to get weight of word on score obj[key] = tf * idf; }); obj.output = a.score; return obj; });
Полный код будет выглядеть следующим образом
Теперь мы видим, что термину «удивительный» придается больше веса, чем термину «продукт» и т. д.
теперь мы можем использовать эти данные и применять модели и методы классификации.
Напишу больше о том, как применить наивную теорему Байеса к этим данным в простом JavaScript.
Пожалуйста, оставляйте свои ответы, это мотивирует писать больше, если вам это нравится.