php实现FMM分词算法
FMM算法,即正向最大匹配法(forward maximum matching method, FMM),是基于词表的分词方法。
对于一段文本从左至右进行扫描,利用词典里面的词汇切分出长度最长的词,单词的颗粒度越大,所能表示的含义越确切。
以下简单实现
<?php
class FMM
{
//简单定义一个词典数组
private $dict = [];
private $result = []; //结果集
//是否为词典中的词
private function inDict($str)
{
$flag = false;
//遍历整个词典
for ($i = 0; $i < count($this->dict); $i++) {
// 是否有词典的词相等或者是前缀相同
if ($str == mb_substr($this->dict[$i], 0, mb_strlen($str))) {
$flag = true;
break;
}
}
return $flag;
}
public function loadDict(array $array)
{
$this->dict = $array;
}
public function split($sentence)
{
$this->result = []; //重置结果集
$wordlen = 1; //切分词的长度
$s1 = ""; //匹配出的字符串
//从左到右扫描字符串
for ($i = 0; $i < mb_strlen($sentence); $i = $i + $wordlen) {
//切出部分待验证的字符串
$tmp = $s1 . mb_substr($sentence, $i, $wordlen);
if ($this->inDict($tmp)) {
//将匹配到的词放入$1并继续匹配,因为要确保匹配出的词为最大匹配
$s1 = $tmp;
} else {
//如果找不到,则将当前匹配的字符串作为结果
$this->result[] = $s1;
//同时从下一个词开始切新词
$s1 = mb_substr($sentence, $i, $wordlen);
}
}
//将剩下来未匹配的词也加入进来
$this->result[] = $s1;
}
public function getResultText()
{
return implode(" \ ", $this->result);
}
}
使用方式
$FMM = new FMM();
$FMM->loadDict(['的确', '王公', '实在', '在理', '公子', '确实']);
$FMM->split('王公子说的确实在理');
echo $FMM->getResultText() . "\n";
效果
王公 子 说 的确 实在 理
接下来可以看看下篇关于BMM分词的效果
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭