这不仅仅是一篇介绍插件的文章 ,也是一篇自我成长的教程 灵感来于jieba-php
上传文件夹到application 有默认的演示方法 直接访问 /Part/index/init 查看效果
使用方法见控制器
我们在控制器中 加载了插件依赖
比如:请不要忘记设置
ini_set('memory_limit', '1024M');

打印后结果为:


打印结果为:其中txt为举例文本


打印结果为:可直接返回关键词

<?php
ini_set('memory_limit', '1024M');
defined('IN_YZMPHP') or exit('Access Denied'); 
yzm_base::load_model('MultiArray', 'Part', 0);
yzm_base::load_model('MultiArrayFactory', 'Part', 0);
yzm_base::load_model('Part', 'Part', 0);
yzm_base::load_model('Finalseg', 'Part', 0);
// 提取关键词
yzm_base::load_model('Analyse', 'Part', 0);
// 词性分词
yzm_base::load_model('Posseg', 'Part', 0);
class Index
{
    /**
     * 初始化分词模型并进行分词
     *
     * @author zhaosong
     */
    public function init()
    {
        Part::init();
        Finalseg::init();
        $seg_list = Part::cut("怜香惜玉也得要看对象啊!");
        var_dump($seg_list);
    }
    /**
     * 初始化分词模型、最终分词模型和分析模型,并提取关键词
     *
     * @author zhaosong
     */
    public function inits()
    {
        Part::init(array('mode'=>'test','dict'=>'small'));
        Finalseg::init();
        Analyse::init();
        $top_k = 10;
        $content = file_get_contents(dirname(dirname(__FILE__))."/dict/lyric.txt", "r");
        $tags = Analyse::extractTags($content, $top_k);
        var_dump($tags);
    }
    /**
     * 初始化分词模型、最终分词模型和词性标注模型,并进行词性标注
     *
     * @author zhaosong
     */
    public function initss()
    {
        Part::init();
        Finalseg::init();
        Posseg::init();
        $seg_list = Posseg::cut("这是一个伸手不见五指的黑夜。我只会一丢丢PHP,我热爱YzmCms,我喜欢编程!");
        var_dump($seg_list);
    }
}加载词典和模型文件,需要加载预先训练好的词典和模型文件,
这些文件包含了词汇、词频、词性等信息。所以我字典很大 所以插件也是很大。
    /**
     * 加载模型文件
     *
     * @param string $f_name 模型文件名
     * @param array $options 选项数组
     * @return array 模型数据
     * @author zhaosong
     */
    public static function loadModel($f_name, $options = array())
    {
        $defaults = array(
            'mode'=>'default'
        );
        $options = array_merge($defaults, $options);
        return json_decode(file_get_contents($f_name), true);
    }对输入的文本进行分词。使用维特比算法进行中文分词(待分词的句子,选项数组)。
$text = "我来到北京清华大学"; $seg_list = Part::cut($text); print_r($seg_list);
什么是维特比算法 :是一种动态规划算法,用于在隐马尔可夫模型(Hidden Markov Model, HMM)中寻找最可能的状态序列。维特比算法广泛应用于自然语言处理、语音识别、生物信息学等领域。
以下是使用 PHP 实现维特比算法的示例:
// 初始状态概率
$pi = array('yzm' => 0.6, 'qh' => 0.4);
// 状态转移概率矩阵
$A = array(
    'yzm' => array('yzm' => 0.7, 'qh' => 0.3),
    'qh' => array('yzm' => 0.4, 'qh' => 0.6)
);
// 观测概率矩阵
$B = array(
    'yzm' => array('normal' => 0.5, 'cold' => 0.4, 'dizzy' => 0.1),
    'qh' => array('normal' => 0.1, 'cold' => 0.3, 'dizzy' => 0.6)
);
// 观测序列
$observations = array('normal', 'cold', 'dizzy');举例:
function viterbis($pi, $A, $B, $observations) {
    $T = count($observations);
    $N = count($pi);
    $delta = array();
    $psi = array();
    // 初始化
    for ($i = 0; $i < $N; $i++) {
        $delta[0][$i] = $pi[$i] * $B[$i][$observations[0]];
        $psi[0][$i] = 0;
    }
    // 递推
    for ($t = 1; $t < $T; $t++) {
        for ($j = 0; $j < $N; $j++) {
            $max_prob = 0;
            $max_state = 0;
            for ($i = 0; $i < $N; $i++) {
                $prob = $delta[$t - 1][$i] * $A[$i][$j];
                if ($prob > $max_prob) {
                    $max_prob = $prob;
                    $max_state = $i;
                }
            }
            $delta[$t][$j] = $max_prob * $B[$j][$observations[$t]];
            $psi[$t][$j] = $max_state;
        }
    }
    // 终止
    $max_prob = 0;
    $max_state = 0;
    for ($i = 0; $i < $N; $i++) {
        if ($delta[$T - 1][$i] > $max_prob) {
            $max_prob = $delta[$T - 1][$i];
            $max_state = $i;
        }
    }
    // 回溯
    $states = array();
    $states[$T - 1] = $max_state;
    for ($t = $T - 2; $t >= 0; $t--) {
        $states[$t] = $psi[$t + 1][$states[$t + 1]];
    }
    return $states;
}处理分词结果 返回一个包含分词结果的数组。可以对这个数组进行处理,例如将分词结果拼接成字符串、统计词频等。
分词模式精确模式、全模式和搜索引擎模式。精确模式是默认模式,将句子最精确地切开,
适用于文本分析;全模式是将句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解决歧义;
搜索引擎模式在精确模式的基础上,对长词再次切分,提高召回率 列如:
   /**
     * 分词方法(搜索引擎模式)
     *
     * @param string $sentence 句子
     * @param array $options 选项数组
     * @return array 分词结果数组
     * @author zhaosong
     */    
    public static function cutForSearch($sentence, $options = array("HMM" => true))
    {
        $defaults = array(
            'mode'=>'default'
        );
        $options = array_merge($defaults, $options);
        $seg_list = array();
        $cut_seg_list = Part::cut($sentence, false, array("HMM" => $options["HMM"]));
        foreach ($cut_seg_list as $w) {
            $len = mb_strlen($w, 'UTF-8');
            if ($len>2) {
                for ($i=0; $i<($len-1); $i++) {
                    $gram2 = mb_substr($w, $i, 2, 'UTF-8');
                    if (isset(self::$FREQ[$gram2])) {
                        $seg_list[] = $gram2;
                    }
                }
            }
            if (mb_strlen($w, 'UTF-8')>3) {
                for ($i=0; $i<($len-2); $i++) {
                    $gram3 = mb_substr($w, $i, 3, 'UTF-8');
                    if (isset(self::$FREQ[$gram3])) {
                        $seg_list[] = $gram3;
                    }
                }
            }
            $seg_list[] = $w;
        }
        return $seg_list;
    }总结:实现分词的逻辑主要包括加载词典和模型文件、对输入文本进行分词、处理分词结果以及释放资源。
在实际应用中,可以根据需求调整分词模式和处理分词结果的方式。
使用插件要灵活 可自己添加字典 但基本的字典已经完全够用
登录后可查看详情!
 
  
						 1年前
						1年前