Skip to content

技术文档-统计高频词

需求描述

上传小说时,为了方便后续搜索,可以手动创建文档标签,便于后续搜索。如果批量上传文档时,手动创建标签不方便,那么可以使用自动获取高频词,然后存储到标签中。

技术基础

自然语言处理(NLP)中分词和停用词是两个重要步骤,它们在文本分析和处理中起着至关重要的作用。

分词(Tokenization)

分词是指将文本数据分解成单个词语或符号的过程。分词的目的是将文本数据转换成机器学习算法可以处理的形式。分词作用:

  1. 提取关键词:分词可以帮助我们提取文本中的关键词,这些关键词可以用来训练机器学习模型。
  2. 去除噪音:分词可以帮助我们去除文本中的噪音,例如标点符号、特殊字符等。
  3. 标准化文本:分词可以帮助我们标准化文本数据,使其更容易被机器学习算法处理。

停用词(Stopwords)

停用词是指在自然语言中频繁出现,但对文本的含义没有贡献的词语。停用词通常包括常见的介词、连词、冠词等。停用词作用:

  1. 减少噪音:停用词可以帮助我们减少文本中的噪音,使得机器学习模型更容易捕捉到文本的主要含义。
  2. 提高效率:停用词可以帮助我们提高机器学习模型的训练效率,因为它们可以减少模型需要处理的词语数量。
  3. 改善模型性能:停用词可以帮助我们改善机器学习模型的性能,因为它们可以帮助模型更好地聚焦于文本的主要含义。

分词和停用词的关系

分词和停用词是紧密相关的两个步骤。分词可以帮助我们提取文本中的关键词,而停用词可以帮助我们过滤掉这些关键词中的噪音。通过结合分词和停用词,我们可以更好地处理文本数据,并训练出更好的机器学习模型。

实例

例如,我们有一个文本数据:"我爱吃苹果,苹果是我的最爱。"

  1. 分词:我们可以将文本数据分解成单个词语,例如:"我"、"爱"、"吃"、"苹果"、"是"、"我的"、"最爱"。
  2. 停用词:我们可以过滤掉一些停用词,例如:"我"、"是"、"我的",因为它们对文本的含义没有贡献。
  3. 提取关键词:我们可以提取剩余的关键词,例如:"爱"、"吃"、"苹果"、"最爱"。

通过这种方式,我们可以更好地处理文本数据,并训练出更好的机器学习模型。

技术调研

获取高频词在机器学习中涉及到一部分,具体使用 Python 的库函数(python 的 jieba 等)。这个项目中服务器是 express 所以使用 nodejs 的库实现。使用了 AI 辅助写代码,但是 AI 不能分辨不同的第三方库,因为第三方库的名称类似,踩了一些坑。

能用:https://www.npmjs.com/package/nodejieba

能用:https://www.npmjs.com/package/analytics-node

不能用:https://www.npmjs.com/package/jieba

不能用:https://www.npmjs.com/package/node-segment

能用:https://www.npmjs.com/package/stopword

不能用:https://www.npmjs.com/package/stopwords

分词库 nodejieba

NodeJieba是"结巴"中文分词的 Node.js 版本实现, 由 c++ 的 jieba 提供底层分词算法实现,兼具高性能和易用性两者的 Node.js 中文分词组件,支持定制自己的词典。API 和 cpp 的 API 一致,就是用 nodejs 封装了一层。

let nodejieba = require("nodejieba");
let result = nodejieba.cut("南京市长江大桥");

nodejieba 自定义用户分词库:将自定义的分词库 user.dict.utf8

替换到 node_modules/nodejieba/submodules/cppjieba/dict/user.dict.utf8 默认分词库即可

停用词库 stopword

stopword is a module for node and the browser that allows you to strip stopwords from an input text.

默认支持英文停用词

const { removeStopwords } = require('stopword')

const oldString = 'a really Interesting string with some words'.split(' ')
const newString = removeStopwords(oldString)
// newString is now [ 'really', 'Interesting', 'string', 'words' ]

中文需要单独配置:停用词库关键是中英文的不同,英文韩文自带空格,中文日文没有空格,所以无法直接使用停用词,需要手动处理。

// https://github.com/fergiemcdowall/stopword?tab=readme-ov-file
const { removeStopwords, zho } = require('stopword');

const words = nodejieba.cut(chineseText);
// words 是一个字符串数组,先经过分词库进行切分处理
const results = removeStopwords(words, zho);

代码实现

const nodejieba = require("nodejieba");
const { removeStopwords, zho } = require('stopword');

function getTags(text) {
  let chineseText = text.replace(/[a-zA-Z\n\r\t\f\v]/g, ' ');
  const words = nodejieba.cut(chineseText);
  const results = removeStopwords(words, zho);
  const doubleWord = results.filter(item => { return item.length > 1; });
  const wordFrequency = {};
  for (const word of doubleWord) {
    if (wordFrequency[word]) {
      wordFrequency[word]++;
    } else {
      wordFrequency[word] = 1;
    }
  }
  const sortedWords = Object.keys(wordFrequency).sort((a, b) => wordFrequency[b] - wordFrequency[a]);
  const top10Words = sortedWords.slice(0, 10);
  return top10Words.join(',');
}