一种汉语句子提词的算法构想

(也许有人比我更早想出来了)

原本我很多想法都是想等我完全做出来之后在写的..
但是博客太久没有更新了 还是得过来水几句…


众所周知 软件理解汉语句子的第一步就是分词 在这之后才能对其进行句意理解
虽然Github上的汉语词库已经很丰富了 再去新建一个词库毫无意义 而且分词并不是理解句子的难点
但是技术和想法不可能是没有价值的 说不定哪天就可以以另一种方式得到应用。

不过相比于Github上的一般汉语词库 这个词库会自带词语出现频率 来更好的计算各种分词算法对应的准确率
并且这个词库会随着爬虫数据积累量的增加 越来越准 用语也会与时俱进

英文分词就不说了 空格就是分词符 根本用不到什么词库或者分词算法..
但是像汉语这样的不自带分词符的语言就比较坑了…

这个想法大概是这样的:
利用现有的QQ机器人平台 创建个QQ小号派到各个群里 然后自动爬取各个群的聊天记录 并对其进行分析:
比如现在获取到了一条消息:

1
2
虽然Github上的汉语词库已经很丰富了 再去新建一个词库毫无意义  
但是技术和想法不可能是没有价值的 说不定哪天就可以以另一种方式得到应用。

原理部分

首先进行非汉语字符分割
然后这句话就被分成以下5个语句

1
2
3
4
5
虽然
上的汉语词库已经很丰富了
再去新建一个词库毫无意义
但是技术和想法不可能是没有价值的
说不定哪天就可以以另一种方式得到应用

然后再分别对语句1 2 3 4 5分别进行 二字词 三字词 四字词 进行循环依次分割

句子1就不说了 直接也只能分为一个潜在二字词 “虽然”

以句子2来做二字词分割举例:
句子2在二字词分割时 会分别产生以下潜在二字词 “上的” “的汉” “汉语” “语词” “词库” “库已”..
n-1个潜在二字词

同样的 对句子2进行三字词分割 则会产生如下结果
“上的汉” “的汉语” “汉语词” “语词库”….
n-2个潜在三字词

显然,经过非常多次爬取训练之后,在这些 潜在二字词 中 “汉语” “词库” “已经” “丰富” 出现频率要远远高于 “的汉” “语词” 等无意义的 潜在二字词
然后分别对上述潜在二字词 三字词等进行频次统计 组成数据库即可 这样 我们就得到了一个非常丰富的潜在二字词 以及潜在二字词出现的频率/频次。

对于三字词 四字词就更有趣了
虽然由于排列组合 爬取到的”潜在三字词”可能数量远远多于”潜在二字词” 但是由于汉语中三字词的数量要远比二字词少 所以 “潜在三字词” 中 “有效三字词” 和 “无效三字词”统计下来的频率差距会更大,数据有效性更高。

应用部分

在产生潜在词库之后 因为我们在爬取的时候 就已经进行了频率/频次统计 再利用其数据库对其进行句子分词的时候 仍然先对句子进行分割
接下来以这句话为例:

1
并且这个词库会随着爬虫数据积累量的增加 越来越准 用语也会与时俱进

首先会被分割为以下的分句

1
2
3
并且这个词库会随着爬虫数据积累量的增加
越来越准
用语也会与时俱进

然后进行二字词切割的时候 因为 “并且” “这个” “词库” “随着” “爬虫” “数据” 等词在词库中出现频次的增加 这样切割得到的总频率会远高于其他切割组合。

三字词 四字词同理。

可行性分析

首先是考虑速度

我觉得绝大多数人聊天打字还是会带上标点或者英文或者数字或者符号等非汉语字符的肯定不会像我这一句一样又臭又长难以分析
所以一般来说,爬虫在对其进行第一次切割后 产生的子语句不会很长 一般很少超过20个字符
所以在爬取的时候 如果遇到子语句超过50字符的话 可以直接不对其进行采样
那么 假设我们对N字符的子语句进行 2-5字词分析(一般来说已经够用了) 需要分割多少次呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
N为50时 为235次
对一台性能正常电脑配合C++来使用 肯定是毫秒级 速度不用担心。

对应用的时候情况类似 只是多了一步浮点运算而已。只要句子不长(比如几千个字符的一个子语句) 速度肯定不是问题。

## 储存占用
也许很多人都会担心储存占用的问题
不如做个简单计算
```汉字共有90000多个,常用字有7000个左右```
按照10000个常用汉字来算
大概二字词有10^8 次方个组合(其实我估计顶多采集到10^7种)
每一个词 算上本身 以及出现的频次(因为遇到重复的词 我们只在频次那里+1 不会重复记录) 顶多占用20个字节(应该绰绰有余吧...)
然后对于二字词 其占用体积顶多不会超过 2*10^9 字节 也就是100MB左右 完全可以接受
不过三字词就相对复杂了... 不过及时做好垃圾回收 1GB肯定够用。

有关于清理的问题 可以见上文

对于三字词 四字词就更有趣了
虽然由于排列组合 爬取到的”潜在三字词”可能数量远远多于”潜在二字词”
但是由于汉语中三字词的数量要远比二字词少
所以 “潜在三字词” 中 “有效三字词” 和 “无效三字词”统计下来的频率差距会更大,数据有效性更高。

```
这样一来 垃圾回收算法也不是问题。

爬虫数据来源

这么多QQ群 这么多沙雕网友 还不够你爬的?

常见疑问的Q&A

Q: 如果出现样本中英混杂的情况怎么办?
A: Too young too simple! 这些样本简直就是送人头的 因为前文提到
首先进行非汉语字符分割
这样 中英混杂的样本反而会大幅度减少计算量 我希望这样的样本越多越好

Q: 这个项目很占用储存空间吧..
A: 你往前翻…

另外一种应用思路

前文提到 Github上有现成的汉语词库 但是并没有(或者很少见?)对具体某一个词的出现频率进行标注 我们可以进行切割法 只统计 “潜在N字词” 出现频数 对现有词库进行加强 也是一个不错的应用。

项目进度

…在做了,在做了

其实我之前用C++和Mirai机器人平台尝试过这个项目…
但是我死在了第一步…

这个是我遇到的坑:
汉字在C++中并不完全是 UTF-8 还有部分 UTF-16 所以按照 UTF-8 来进行解码和正则表达式(感谢林大佬给我正则表达式判断中文的思路)是行不通的…
然后又得考虑 UTF-8 和 UTF-16 混用的问题…
没错 我救死在了这一步…

QT框架好像有提取中文的api 但是作为一个C++初学者 直接上QT有点违背正常学习顺序了…

那为啥不学C++呢? 因为我学C++是用我iPad学的.. 我iPad前段时间阵亡了…

PS:
林大佬的博客: https://uint128.com/


关于博客更新:
最近一直在忙于比赛和机器人,就当做我一直在攒大招吧… 等我做好之后我肯定会扔博客上的…
也许几个月之后你会发现,这篇帖子前后的博客,是两个技术等级。
emmm…也许对巨佬来说,可能并没有差别←_←