欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nodejs 中文分詞常用模塊用法分析

 更新時間:2023年05月06日 09:32:59   作者:多比熊  
這篇文章主要介紹了Nodejs 中文分詞常用模塊用法,結合具體案例形式分析了node.js常用分詞模塊的基本功能、用法、效率與相關使用特點,需要的朋友可以參考下

???
???
???????????????(生活只有在平淡無味的人看來才是空虛而平淡無味的。 —— 車爾尼雪夫斯基)
???
???
????????????????在這里插入圖片描述

中文分詞器

引用百度的說明 ~~

中文分詞就是將連續(xù)的字序列按照一定的規(guī)范重新組合成詞序列的過程。我們知道,在英文的行文中,單詞之間是以空格作為自然分界符的,而中文只是字、句和段能通過明顯的分界符來簡單劃界,唯獨詞沒有一個形式上的分界符,雖然英文也同樣存在短語的劃分問題,不過在詞這一層上,中文比之英文要復雜得多、困難得多

  • 與英文為代表的拉丁語系語言相比,英文以空格作為天然的分隔符,而中文由于繼承自古代漢語的傳統(tǒng),詞語之間沒有分隔。 古代漢語中除了連綿詞和人名地名等,詞通常就是單個漢字,所以當時沒有分詞書寫的必要。而現(xiàn)代漢語中雙字或多字詞居多,一個字不再等同于一個詞。
  • 在中文里,“詞”和“詞組”邊界模糊
    現(xiàn)代漢語的基本表達單元雖然為“詞”,且以雙字或者多字詞居多,但由于人們認識水平的不同,對詞和短語的邊界很難去區(qū)分。
    例如:“對隨地吐痰者給予處罰”,“隨地吐痰者”本身是一個詞還是一個短語,不同的人會有不同的標準,同樣的“海上”“酒廠”等等,即使是同一個人也可能做出不同判斷,如果漢語真的要分詞書寫,必然會出現(xiàn)混亂,難度很大。
    中文分詞的方法其實不局限于中文應用,也被應用到英文處理,如手寫識別,單詞之間的空格就不很清楚,中文分詞方法可以幫助判別英文單詞的邊界

NodeJS中的中文分詞器

mmseg-node

https://github.com/zzdhidden/mmseg-node
一個基于 libmmseg 的 NodeJS 驅(qū)動

安裝流程

sudo apt-get install make gcc g++ automake libtool
wget http://www.coreseek.cn/uploads/csft/3.2/mmseg-3.2.14.tar.gz
sudo tar zxvf mmseg-3.2.14.tar.gz 
cd mmseg-3.2.14
./bootstrap 
./configure
make && make install
npm install mmseg

示例代碼

const mmseg = require("mmseg");
const q = mmseg.open('/usr/local/etc/');
console.log(q.segmentSync("我是中文分詞"));

從該包的下載量和issue的解決程度來看,不推薦使用,很容易碰到問題,而沒有得到有效的解決

nseg

https://github.com/mountain/nseg
Chih-Hao Tsai發(fā)明的MMSG,一種非常流行的中文分詞算法。許多實現(xiàn)可在不同的平臺上使用,包括Python,Java等

安裝流程

npm install nseg

示例代碼

const dict  = require('../data/dict'),
    freq  = require('../data/freq'),
    date  = require('../lex/datetime'),
    sina  = require('../lex/sina');
const opts  = {
        dict: dict,
        freq: freq,
        lexers: [date, sina],
    };
const nseg = require('nseg').normal(opts);
nseg('研究生源計劃', (result) => {
    console.log(result);
});

mmseg一樣,雖然在其他環(huán)境(比如Java,Python)有著較為成熟的應用和場景,但包的維護者重心可能不在nodejs上,所以還是不太建議使用…

node-segment

https://github.com/leizongmin/node-segment
盤古分詞組件中的詞庫為基礎, 算法設計也部分參考了盤古分詞組件中的算法

具有以下特點

  • 純JavaScript編寫,可以在任何支持ECMAScript5的引擎上執(zhí)行(需要稍微修改部分代碼)
  • 基于詞性進行聯(lián)想識別
  • 可使用JavaScript編寫自定義的分詞模塊

安裝流程

npm install segment --save

示例代碼

const Segment = require('segment');
const segment = new Segment();
segment.useDefault(); // 載入默認詞典
segment.loadDict('test.text'); // 載入字典,詳見dicts目錄,或者是自定義字典文件的絕對路徑
const text = "歡迎來到CSDN開發(fā)者博客論壇~~";
console.log(segment.doSegment(text, {
  stripPunctuation: true //去除標點符號
}));

定制化示例文件 .text

0x00100000代表16進制的詞性,但在返回時轉(zhuǎn)換為了十進制來標識

  • 名詞 十進制:1048576 十六進制:0x00100000
  • 動詞 十進制:4096 十六進制:0x00001000
  • 機構團體 十進制:20 十六進制:0x00000020
  • 時間 十進制:16384 十六進制:0x00004000
  • 人名 十進制:128 十六進制:0x00000080
  • 標點符號 十進制:2048 十六進制:0x00000800

101代表了這個詞語的權重,在后續(xù)匹配詞語時,若匹配到近似詞,則以權重優(yōu)先匹配

架構師|0x00100000|101
程序員|0x00100000|101
運維工程師|0x00100000|101

該包使用純JavaScript編寫,github上的star量有1k,但通過查看issue,該包的維護著似乎已經(jīng)不太關心這個包了。但如果對性能要求沒那么高,且多關注內(nèi)存,使用得當?shù)脑挘€是可以考慮的

nodejieba

https://github.com/yanyiwu/nodejieba
NodeJieba是"結巴(jieba)"中文分詞的 Node.js 版本實現(xiàn), 由CppJieba提供底層分詞算法實現(xiàn), 是兼具高性能和易用性兩者的 Node.js 中文分詞組件

具有以下特點

  • 詞典載入方式靈活,無需配置詞典路徑也可使用,需要定制自己的詞典路徑時也可靈活定制。
  • 底層算法實現(xiàn)是C++,性能高效。
  • 支持多種分詞算法,各種分詞算法見CppJieba的README.md介紹。
  • 支持動態(tài)補充詞庫。

安裝流程

npm install nodejieba

但在安裝該包的時候可能會遇到npm下載權限的問題,因為底層使用了CppJieba,當使用sudo npm安裝時會提示權限不足

在這里插入圖片描述

github issue問題

npm 官方解釋

解決辦法

  1. 單獨下載該包文件
    sudo npm install nodejieba --unsafe-perm
  2. 將該包緩存至全局
    sudo npm install nodejieba -g --unsafe-perm
  3. 配置npm
    sudo su -
    npm config set unsafe-perm
  4. 切換至root身份運行
    sudo su -
    npm i

示例代碼

jieba詞性

  • 獲取文本分詞標注結果
  • n 名詞
  • v 動詞
  • nt 機構名稱
  • t 時間
  • nr 人名

示例自定義文件 .utf-8

客戶模板 n
客戶狀態(tài) n
客戶手機號 n
自定義 n
自定義字段 n
云通訊 n
const nodejieba = require("nodejieba");
jieba.load({ userDict: `self.utf-8`}); // 自定義詞典
const text = '紅掌撥清波';
const tags = ['n', 'v', 'nt', 'nr', 't'];
const docuemnt = jieba.tag(text).filter((v) => tags.includes(v.tag)).map((v) => v.word);
console.log(docuemnt);

目前NodeJS中性能最強的分詞器,且github上star量達到2k+,但開發(fā)者可能會遇到安裝的問題,因為底層依賴了python g++,如果版本過低或者過高,在安裝時會比較棘手。但如果能夠?qū)C器環(huán)境配置好的話,還是推薦使用該工具的,畢竟性能很強~~

性能對比

起初在使用nodejieba時,遇到了很多安裝的問題,比如npm權限,g++版本不匹配等等,期間也嘗試了node-segment,但因為服務對性能的要求較高,所以還是選擇克服機器配置的問題,使用了nodejieba

在這里插入圖片描述

node-sgement和nodejieba的性能對比以及代碼分析

示例代碼

'use strict';
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const Segment = require('segment');
const segment = new Segment();
const nodejieba = require('nodejieba');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
segment.useDefault();
segment.loadDict('test.text');
app.post('/', function (req, res, next) {
  const text = req.body.text;
  const type = req.body.type;
  const num = req.body.num;
  let str = '';
  let array = [];
  for (let index = 0; index < num; index++) {
    str += text;
  }
  const tags = ['n', 'v', 'nt', 'nr', 't'];
  if (type === 'nodejieba') {
    array = nodejieba.tag(str).filter((v) => tags.includes(v.tag)).map((v) => v.word)
  } else {
    array = segment.doSegment(str).map((v) => v.w);
  }
  console.log(array);
  res.send(array);
});
app.listen(3000);

示例請求文件 .text

{
    "text": "生活只有在平淡無味的人看來才是空虛而平淡無味的。",
    "type": "segment",
    "num": 1
}
  • 使用apach bench進行測試

測試方法:ab -n 1000 -p post.txt -c 200 -T application/json localhost:3000

  • -n 請求總數(shù)
  • -p post請求文件
  • -c 并發(fā)量
  • -T 請求格式
  • 請求返回參數(shù)說明
  • Document Path: /phpinfo.php #測試的頁面
  • Document Length: 50797 bytes #頁面大小
  • Concurrency Level: 200 #測試的并發(fā)數(shù)
  • Time taken for tests: 11.846 seconds #整個測試持續(xù)的時間
  • Complete requests: 1000 #完成的請求數(shù)量
  • Failed requests: 0 #失敗的請求數(shù)量
  • Write errors: 0
  • Total transferred: 204586997 bytes #整個過程中的網(wǎng)絡傳輸量
  • HTML transferred: 203479961 bytes #整個過程中的HTML內(nèi)容傳輸量
  • Requests per second: 337.67 [#/sec] (mean) #最重要的指標之一,每秒處理請求數(shù)
  • Time per request: 2961.449 [ms] (mean) #最重要的指標之二,平均等待時長
  • Time per request: 2.961 [ms] (mean, across all concurrent requests) #每個連接請求實際運行時間的平均值
  • Transfer rate: 16866.07 [Kbytes/sec] received #平均每秒網(wǎng)絡上的流量,可以幫助排除是否存在網(wǎng)絡流量過大導致響應時間延長的問題
  • 測試版本
  • node v12
  • segment v0.1.3
  • nodejieba v2.4.1
  • 測試結果
分詞類型字符長度請求總數(shù)并發(fā)條數(shù)平均每秒處理平均等待時長(ms)是否包含分隔符(標點符號等)
segment60100020129.47154.474
nodejieba601000202662.837.511
segment60100050137.51363.598
nodejieba601000502660.4117.222
segment601000100134.56753.688
nodejieba6010001002774.8936.038
segment601000200134.051491.937
nodejieba6010002002846.3070.267
--------
segment180100020067.402967.466
nodejieba18010002002390.5383.664
segment360100020042.554700.340
nodejieba36010002001801.97110.989
--------
segment60100020088.262265.952
nodejieba6010002002860.9569.907
segment6020050101.18494.188
nodejieba60200502688.3918.598
segment120200501.7328933.129
nodejieba120200501551.1132.235
segment36020050error(棧溢出)error(棧溢出)
nodejieba360200501117.4644.744
  • 測試結果點評
  • 從測試結果來看,nodejieba是node-sgement的20-30倍,這得益于nodejieba依賴的CppJieba,而node-sgement使用的純JS編寫,所以性能要遜色很多
  • nodejieba和node-sgement在處理分詞的請求都比較穩(wěn)定,但面對長文本,即便性能很強的nodejieba依然會有性能瓶頸問題
  • 面對不包含標點符號的文本,nodejieba和node-sgement性能都會有所影響
  • node-sgement在對長文本(360個無標點符號的字符)進行分詞時會導致棧溢出
  • 測試過程說明

查看node-sgement源碼發(fā)現(xiàn) 作者建議不要對較長且無任何標點符號的文本進行分詞的是發(fā)生在字典分詞階段
因為分詞是通過空格換行,通配符,特殊字符進行分離處理的(正是因為有了分離,所以每次分詞的文本不會很長)
而segment處理一串字符是通過循環(huán)每一個字符進行遞增匹配的,從而導致匹配的的次數(shù)是成倍的增長

…一開始想問原作者沒有特殊符號的長文導致時間倍增的具體原因,但是他可能很久沒有維護這個包了,就沒有提供有用的信息,然后只能看源碼去了解了

在這里插入圖片描述

  • node-segment 分詞邏輯
  • 例子 你好我是七陌,循環(huán)次數(shù)是6+5+4+3+2+1 = (1+n)*n/2
  • 第一輪對比

    你好
    你好我
  • 第二輪對比

    好我
    好我是
    好我是七

一共分為12個分詞模塊

  • 6個分詞模塊
    url識別
    通配符識別
    標點符號
    字母/數(shù)字識別
    字典識別
  • 6個優(yōu)化模塊
    中文姓
    人名
    中文人名
    日期時間
    詞典
    郵箱地址
  • 整體執(zhí)行邏輯

每次分詞會把紅框中的所有模塊文件執(zhí)行一遍
在這里插入圖片描述

  1. 將(空格/換行)進行分組,用于后續(xù)循環(huán)匹配字符和詞性,然后進行六個階段的分詞計算
  2. url識別 地址匹配,https/http… 如果命中則進行轉(zhuǎn)換,并返回數(shù)據(jù)和詞性,每次從當前下標開始截取協(xié)議名稱字符數(shù),如果是http則是7個。將截取的字符進行對比,直到循環(huán)非url字符時結束。此時將這段字符的前后分成三段返回
  3. 通配符識別 通過循環(huán)遍歷將命中的通配符返回,并在上層匹配通配符詞性
  4. 標點符號 和通配符識別邏輯相同
  5. 字母/數(shù)字識別 將匹配的英文和數(shù)字字符使用ASCII轉(zhuǎn)換,如果命中ASCII區(qū)間,則將區(qū)間對應的16進制轉(zhuǎn)換為10進制作為詞性并分離返回,分離后的結構和請求協(xié)議的結構相同
  6. 字典識別 將字符串的字符循環(huán)和每一個字典的內(nèi)的字符進行包含性對比
    第一次先從0下標開始查找,如果未命中則字符串截取數(shù)++,如果都沒有命中就將對比下標向前進一位,其中重復命中的會經(jīng)過一層優(yōu)化(去重打分),留下詞頻率最高,未識別詞最少的等等
  7. 中文人名識別
  8. 人名優(yōu)化

總結

當然是推薦使用nodejieba了,畢竟是目前nodejs性能最強的分詞,但對機器環(huán)境依賴較為苛刻,所以建議使用docker將分詞服務單獨部署,進行環(huán)境依賴的隔離。
但如果更改機器配置對其他服務影響較大,且服務對性能要求沒那么高的話,可以考慮使用node-segment,然后加一些避免棧溢出的代碼,效果還是不錯的~~

PS:筆者比較喜歡實用nodejieba分詞工具,但是針對某些領域(如:區(qū)塊鏈相關)的專業(yè)術語會出現(xiàn)分詞錯誤的情況,這個時候就需要去尋找相關的詞庫并手動加載進來使用。 

相關文章

  • 詳解如何在Node.js中執(zhí)行CPU密集型任務

    詳解如何在Node.js中執(zhí)行CPU密集型任務

    Node.js通常被認為不適合CPU密集型應用程序,Node.js的工作原理使其在處理I/O密集型任務時大放異彩,雖然執(zhí)行CPU密集型任務肯定不是Node的主要使用場景,但是我們依舊有方法來改善這些問題,本文詳細給大家介紹了如何在Node.js中執(zhí)行CPU密集型任務
    2023-12-12
  • nodejs腳本centos開機啟動實操方法

    nodejs腳本centos開機啟動實操方法

    在本篇文章里小編給大家整理的是關于nodejs腳本centos開機啟動實操方法,有興趣的朋友們參考下。
    2020-03-03
  • 用nodejs實現(xiàn)json和jsonp服務的方法

    用nodejs實現(xiàn)json和jsonp服務的方法

    本篇文章主要介紹了用nodejs實現(xiàn)json和jsonp服務的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 基于Node.js構建一個靈活的CLI命令行工具

    基于Node.js構建一個靈活的CLI命令行工具

    在軟件開發(fā)中,命令行界面(CLI)工具是必不可少的助手,本文主要介紹了如何使用Node.js構建一個靈活的CLI工具,涵蓋從基礎命令處理到復雜的交互式問答和遠程模板下載,需要的可以參考下
    2024-03-03
  • Nodejs之http的表單提交

    Nodejs之http的表單提交

    這篇文章主要為大家詳細介紹了Nodejs之http的表單提交,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 帶你了解NodeJS事件循環(huán)

    帶你了解NodeJS事件循環(huán)

    這篇文章主要介紹NodeJS事件循環(huán),Node中代碼從上到下同步執(zhí)行,在執(zhí)行過程中會將不同的任務添加到相應的隊列中,那具體有的循環(huán)又是怎么回事呢,限免現(xiàn)編就帶大家學習該詳細內(nèi)容,需要的朋友也可以參考一下
    2022-02-02
  • 使用Node.js插件給指定目錄下的所有圖片添加上文字水印

    使用Node.js插件給指定目錄下的所有圖片添加上文字水印

    加水印是為了保護圖片的版權和安全,在互聯(lián)網(wǎng)上,很容易將圖片下載或者截屏保存下來,然后進行二次使用,這就侵犯了原作者的版權,此外,水印也可以幫助識別圖片的來源和所有者,因此本文給大家介紹了如何使用Node.js插件給指定目錄下的所有圖片添加上文字水印
    2023-12-12
  • Node.js爬蟲如何獲取天氣和每日問候詳解

    Node.js爬蟲如何獲取天氣和每日問候詳解

    這篇文章主要給大家介紹了關于Node.js爬蟲如何獲取天氣和每日問候的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Node.js爬蟲具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • express.js如何做mysql注入與node-mysql中防止SQL注入方法解析

    express.js如何做mysql注入與node-mysql中防止SQL注入方法解析

    這篇文章主要介紹了express.js如何做mysql注入與node-mysql中防止SQL注入方法,結合實例形式分析了express框架使用mysql數(shù)據(jù)庫過程中SQL注入的原理與防范技巧,需要的朋友可以參考下
    2023-05-05
  • nodejs連接mongodb數(shù)據(jù)庫實現(xiàn)增刪改查

    nodejs連接mongodb數(shù)據(jù)庫實現(xiàn)增刪改查

    本篇文章主要結合了nodejs操作mongodb數(shù)據(jù)庫實現(xiàn)增刪改查,包括對數(shù)據(jù)庫的增加,刪除,查找和更新,有興趣的可以了解一下。
    2016-12-12

最新評論