虽然没多少人关注这个话题,但还是发个帖,开个头,希望有后来人。
——以下两段代码只能说是“实现了功能”,但效率很差。假如是自制的小字典还可以,使用大词库就非常吃力了。经测试,使用大词库,一句话可能要一两分钟才能切分词语!~
——分词好像是好多学校计算机专业的作业题哦,搜索过几篇分词的学生毕业论文,有些IT大企业面试题……
——这个帖子重点讨论使用批处理进行中文分词的可能性,欢迎你参与……
以下是相关帖:
http://www.bathome.net/thread-9183-1-1.html
词库下载:
http://cjiabing.qupan.com/6627766.html
中文分词介绍:
http://baike.baidu.com/view/19109.htm
文章介绍:
http://hi.baidu.com/cjiabing/blog/item/4c95b91bf3abaa178718bff4.html
中文分词规范:
http://wenku.baidu.com/view/1dbd3fc58bd63186bcebbc7d.html
分词介绍 - 分词,简单地说,就是将一句话拆解/切分成独立的词语。
- 通常,句子由字和词组成,分词就是将句子变回字和词。
- 如句子:
- 我喜欢音乐。
- 分词就是把句子中的词语用空格等方式分开,变成:
- 我 喜欢 音乐。
- 分词的目的是为了提取句子中的词语/关键词以便做搜索、摘要等等用途。
- 分词属于计算机自然语言处理的基础,是有难度的,如上例的切分结果可能有两种:
- 1、我 | 喜欢 | 音乐。
- 2、我 | 喜 | 欢音 | 乐。
- 要正确分词需要“消除歧义”。另外,还要“登陆新词”,也就是如新词、姓名等如何切分?
复制代码
测试题
- 以下是测试题,用以测试你分词的准确率:
-
- 我喜欢坐在面包车上一边吃面包一边看北京天安门门楼的门
- 我喜欢坐在面包车上一边吃面包一边看北京大学生活动中心门楼的门
- 我喜欢坐在面包车上一边吃面包一边看北京大学生活在音乐里
- 我喜欢坐在面包车上一边吃面包一边看北京大学生活很好
- 我喜欢坐在面包车上一边吃面包一边看北京大学的学生生活在音乐里
- 我喜欢坐在面包车上一边吃面包一边看北京大学的学生活在音乐里
- 广西大学生活很好
- 我喜欢吃鸭肉
- 我喜欢音乐
- 我喜欢吃面条
- 伟大学生生活
- 大学生活动
- 大学生活动中心
- 大学生活好
- 发展中国家庭养猪事业
- 你说的确实在理
- 中华人民共和国万岁
- 吃面包
复制代码
批处理中文分词之正向最大匹配法 - @ECHO OFF&SETLOCAL ENABLEDELAYEDEXPANSION
- :FJJZ
- CLS
- SET /P INF= 你对电脑说:
- ECHO.
- CD.>S.TXT
- FOR /L %%I IN (0,1,100) DO (
- SET STRDD=!INF:~%%I,4!&IF DEFINED STRDD SET STRDDO=!STRDD:~3,1!&IF DEFINED STRDDO FOR /F "TOKENS=1,*" %%A IN (DICTIONARY.TXT) DO IF "%%A"=="!STRDD!" ECHO 4 %%I %%A %%B %%I,4
- REM 截取四个字组成的词语,如“刻舟求剑”————意味着缺陷:四个字以上的词语如“中华人民共和国”不在截取范围。
- SET STRCC=!INF:~%%I,3!&IF DEFINED STRCC SET STRCCO=!STRDD:~2,1!&IF DEFINED STRCCO FOR /F "TOKENS=1,*" %%E IN (DICTIONARY.TXT) DO IF "%%E"=="!STRCC!" ECHO 3 %%I %%E %%F %%I,3
- REM 截取三个字组成的词语,如“批处理”————前面判断字符是否赋值,后面用于与词库匹配。
- SET STRBB=!INF:~%%I,2!&IF DEFINED STRBB SET STRBBM=!STRBB:~1,1!&IF DEFINED STRBBM FOR /F "TOKENS=1,*" %%X IN (DICTIONARY.TXT) DO IF "%%X"=="!STRBB!" ECHO 2 %%I %%X %%Y %%I,2
- REM 截取两个字组成的词语,如“胜利”————后面结果保留字符长度和偏移量。
- SET STRAA=!INF:~%%I,1!&IF DEFINED STRAA FOR /F "TOKENS=1,*" %%M IN (DICTIONARY.TXT) DO IF "%%M"=="!STRAA!" ECHO 1 %%I %%M %%N %%I,1
- REM 截取一个字组成的词语,如“锅”。
- )>>S.TXT
- REM 以上代码很好地解释了字符串的截取和匹配,思路很清晰,但效率很差,原因在于每截取一个字词就匹配一下词库,FOR使用得太频繁。
- rem 一般我写代码都是,首先着重在于描述过程,达到目的后优化代码,提高效率。我是按人的思路写代码,不是按机器的思路写代码,所以效率差了。
- REM 改良的思路应该是,先将截取结果写入一个临时文件,然后使用“FINDSTR /I /X /G:TMP.TXT DICTIONARY.TXT>>S3.TXT”与词库匹配,试了一下,效果明显提高。有空再改。
- SET VAR=-1
- ECHO 切分结果:
- ECHO.
- :LP
- SET /A VAR+=1
- FOR /F "TOKENS=1,2,3,*" %%I IN (S.TXT) DO (
- IF !VAR!==%%J (
- SET /P K= 【%%K】<NUL
- REM ECHO %%K 1
- SET /A VAR=%%J+%%I
- )
- )
- IF %VAR% LSS 30 GOTO LP
- REM 上面这个比较简单,就是将切分出来的词语按照字符长度和偏移量重新组装句子,并用空格和【】隔开以突出词语。
- REM 前面有过一段时间为这几行字母折腾了好几天,后来想通了原来竟是这么简单。
- ECHO.
- ECHO.
- PAUSE
- GOTO FJJZ
复制代码
批处理中文分词之交集型词语匹配 (包含正向最大匹配) -
- @echo off&setlocal enabledelayedexpansion
- :fjjz
- cls
- set /p inf= 输入句子:
- cd.>S.TXT
- for /l %%i in (0,1,100) do (
- set strdd=!inf:~%%i,4!&if defined strdd set strddo=!strdd:~3,1!&if defined strddo for /f "tokens=1,*" %%a in
- (dictionary.txt) do if "%%a"=="!strdd!" echo 4 %%i %%a %%b %%i,4
- set strcc=!inf:~%%i,3!&if defined strcc set strcco=!strdd:~2,1!&if defined strcco for /f "tokens=1,*" %%e in
- (dictionary.txt) do if "%%e"=="!strcc!" echo 3 %%i %%e %%f %%i,3
- set strbb=!inf:~%%i,2!&if defined strbb set strbbm=!strbb:~1,1!&if defined strbbm for /f "tokens=1,*" %%x in
- (dictionary.txt) do if "%%x"=="!strbb!" echo 2 %%i %%x %%y %%i,2
- set straa=!inf:~%%i,1!&if defined straa for /f "tokens=1,*" %%m in (dictionary.txt) do if "%%m"=="!straa!" echo 1 %%i %%m %
- %n %%i,1
- )>>S.TXT
- cd.>zk1.txt
- set var=-1
- :lp
- set /a var+=1
- for /f "tokens=1,2,3,*" %%i in (S.txt) do (
- if !var!==%%j (
- set /p k= %%k<nul
- set /a var=%%j+%%i
- )
- )>>zk1.txt
- if %var% lss 30 goto lp
- echo.
- cd.>zk2.txt
- for /f "tokens=1,2,3,*" %%a in (S.txt) do if %%a==2 set /p s= %%c<nul>>zk2.txt
- set /p wj=<zk1.txt
- set /p wj1=<zk2.txt
- for %%i in (!wj!) do (
- for %%a in (!wj!) do (
- set dfa=%%i
- set ahe=!dfa:~2,1!
- for %%e in (!wj1!) do (
- for %%x in (!wj1!) do (
- if defined ahe if "%%i%%a"=="%%e%%x" set vdae=%%e&set vdaea=%%x&set vdbe=%%i&set vdbea=%%a
- )
- )
- )
- )
- echo.
- set /p lied=<zk1.txt
- for %%i in (!lied!) do (
- if "%%i"=="!vdbe!" (echo !vdae! !vdaea!) else (if not "!vdaea:~1,1!"=="%%i" echo %%i)
- )
- echo.
- pause
- del zk1.txt,zk2.txt
- goto fjjz
复制代码
|