首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 中文分詞系統實作:整合 ICTCLAS 斷詞引擎完整教學

     編輯:PHP 相關知識

PHP 站內搜尋核心:中文分詞技術實作指南

中文分詞是中文搜尋引擎、文字探勘、自然語言處理的基石。單字切分精度不足,詞級分詞能大幅提升搜尋相關性。本文介紹如何在 PHP 中整合 ICTCLAS (中科院計算所分詞系統) 實現高精度中文分詞。

ICTCLAS 簡介

ICTCLAS (Institute of Computing Technology, Chinese Lexical Analysis System) 是中科院計算所開發的中文分詞系統,特點:

  • 分詞正確率達 97.58% (PKU 語料庫測試)
  • 支援詞性標註 (名詞、動詞、形容詞等)
  • 支援未登錄詞辨識 (人名、地名、機構名等)
  • 提供 C/C++、Java、C#、Python 等多語言介面

PHP 整合架構設計

由於 ICTCLAS 為原生二進位程式,PHP 透過 proc_open() 建立管道與其通訊:

<?php
class ChineseTokenizer {
    private static $binPath = '';

    // 設定 ICTCLAS 執行檔目錄 (不含檔名)
    public static function setBinaryPath(string $path): void {
        self::$binPath = rtrim($path, '/\\');
    }

    // 執行分詞指令
    private static function execute(string $text): string {
        $cmd = self::$binPath . DIRECTORY_SEPARATOR . 'ictclas';
        $descriptors = [
            0 => ['pipe', 'r'],  // stdin
            1 => ['pipe', 'w'],  // stdout
            2 => ['pipe', 'w']   // stderr
        ];

        $proc = proc_open($cmd, $descriptors, $pipes);
        if (!is_resource($proc)) {
            throw new RuntimeException('無法啟動 ICTCLAS 程序');
        }

        // ICTCLAS 內部使用 GBK 編碼
        $input = iconv('UTF-8', 'GBK//IGNORE', $text);
        fwrite($pipes[0], $input);
        fclose($pipes[0]);

        $output = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        
        $returnCode = proc_close($proc);
        if ($returnCode !== 0 && $stderr) {
            error_log("ICTCLAS stderr: $stderr");
        }

        // 輸出轉回 UTF-8
        return iconv('GBK', 'UTF-8//IGNORE', trim($output));
    }

    // 公開介面:分詞並回傳結構化結果
    public static function tokenize(string $text): array {
        $output = self::execute($text);
        $tokens = [];

        if ($output) {
            // ICTCLAS 輸出格式: "詞/詞性 詞/詞性 ..."
            $parts = preg_split('/\s+/', $output);
            foreach ($parts as $part) {
                if (strpos($part, '/') !== false) {
                    [$word, $pos] = explode('/', $part, 2);
                    $tokens[] = [
                        'word' => $word,
                        'pos' => $pos,
                        'pos_name' => self::getPosName($pos)
                    ];
                }
            }
        }
        return $tokens;
    }

    // 簡易模式:僅回傳詞語陣列
    public static function segment(string $text): array {
        return array_column(self::tokenize($text), 'word');
    }

    // 詞性代碼對照表 (部分)
    private static function getPosName(string $pos): string {
        $map = [
            'n' => '名詞', 'nr' => '人名', 'ns' => '地名', 'nt' => '機構名',
            'v' => '動詞', 'vd' => '動副詞', 'vn' => '名動詞', 'a' => '形容詞',
            'd' => '副詞', 'm' => '數詞', 'q' => '量詞', 'r' => '代詞',
            'p' => '介詞', 'c' => '連詞', 'u' => '助詞', 'e' => '嘆詞',
            'wp' => '標點符號', 'ws' => '外文', 'x' => '非語素字'
        ];
        return $map[$pos] ?? $pos;
    }
}

// 設定執行檔路徑 (確保 ictclas 執行檔與詞典在同目錄)
ChineseTokenizer::setBinaryPath(__DIR__ . '/ictclas');

// 使用範例
$text = '台灣積體電路製造公司是全球最大的晶圓代工廠。';
$tokens = ChineseTokenizer::tokenize($text);

echo "<pre>";
print_r($tokens);
echo "</pre>";

/*
輸出範例:
Array
(
    [0] => Array ( [word] => 台灣 [pos] => ns [pos_name] => 地名 )
    [1] => Array ( [word] => 積體電路 [pos] => n [pos_name] => 名詞 )
    [2] => Array ( [word] => 製造 [pos] => v [pos_name] => 動詞 )
    [3] => Array ( [word] => 公司 [pos] => n [pos_name] => 名詞 )
    [4] => Array ( [word] => 是 [pos] => v [pos_name] => 動詞 )
    [5] => Array ( [word] => 全球 [pos] => n [pos_name] => 名詞 )
    [6] => Array ( [word] => 最大 [pos] => a [pos_name] => 形容詞 )
    [7] => Array ( [word] => 的 [pos] => u [pos_name] => 助詞 )
    [8] => Array ( [word] => 晶圓 [pos] => n [pos_name] => 名詞 )
    [9] => Array ( [word] => 代工 [pos] => vn [pos_name] => 名動詞 )
    [10] => Array ( [word] => 廠 [pos] => n [pos_name] => 名詞 )
    [11] => Array ( [word] => 。 [pos] => wp [pos_name] => 標點符號 )
)
*/
?>

ICTCLAS 部署步驟 (Linux)

# 1. 下載 ICTCLAS Linux 版本
wget https://ictclas.nlpir.org/downloads/ictclas_linux_64bit.tar.gz
tar zxvf ictclas_linux_64bit.tar.gz
cd ictclas

# 2. 確認執行權限
chmod +x ictclas

# 3. 測試執行
echo "測試分詞" | ./ictclas

# 4. 部署至專案目錄
cp -r ictclas /var/www/html/myproject/

效能優化:常駐進程模式

頻繁啟動 proc_open 效能較差,高流量建議使用常駐進程:

<?php
class PersistentTokenizer {
    private $proc;
    private $pipes;

    public function __construct(string $binPath) {
        $cmd = $binPath . '/ictclas_server'; // 需支援 server 模式的版本
        $descriptors = [
            0 => ['pipe', 'r'],
            1 => ['pipe', 'w'],
            2 => ['pipe', 'w']
        ];
        $this->proc = proc_open($cmd, $descriptors, $this->pipes);
        if (!is_resource($this->proc)) {
            throw new RuntimeException('無法啟動常駐分詞服務');
        }
    }

    public function tokenize(string $text): array {
        $input = iconv('UTF-8', 'GBK//IGNORE', $text) . "\n";
        fwrite($this->pipes[0], $input);
        $output = fgets($this->pipes[1]); // 讀取單行回應
        return $this->parseOutput($output);
    }

    public function __destruct() {
        if (is_resource($this->proc)) {
            fclose($this->pipes[0]);
            fclose($this->pipes[1]);
            fclose($this->pipes[2]);
            proc_close($this->proc);
        }
    }
    // parseOutput 同前...
}
?>

替代方案:純 PHP 分詞庫

若無法部署二進位程式,可考慮純 PHP 實作:

# Composer 安裝 jieba-php
composer require fukuball/jieba-php

# 使用範例
require 'vendor/autoload.php';
use Fukuball\Jieba\Jieba;

Jieba::init();
$seg = Jieba::cut('台灣積體電路製造股份有限公司');
print_r($seg);
// Array ( [0] => 台灣 [1] => 積體電路 [2] => 製造 [3] => 股份有限公司 )

搜尋引擎整合建議

  1. 索引建立:分詞後儲存至倒排索引 (Inverted Index)
  2. 同義詞擴展:結合同義詞典擴充查詢詞
  3. 停用詞過濾:移除「的」、「是」、「在」等高頻低價值詞
  4. 權重計算:TF-IDF、BM25 等演算法計算詞項重要性
  5. 前綴匹配:支援輸入法聯想、自動完成功能

掌握中文分詞核心技術,能建構高精度的站內搜尋、文字分析、推薦系統等 NLP 應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
專案特點Composer 套件
jieba-php結巴分詞 PHP 移植版,支援自定義詞典fukuball/jieba-php
SCWS簡易中文分詞系統,C 擴充套件效能佳pecl/scws
PHPAnalysis純 PHP 實作,無需編譯擴充套件phpanalysis/phpanalysis