NAV
Python JS

Articut

Articut 服務介紹

基於人類習得語言的機制,透過「語法規則」建立中文語言處理的斷詞系統。
只用結構就能解決中文斷詞問題,不需要大數據,修改快且離線就能跑。
沒有內建字典,不認識的詞彙都是 OOV,不需要擔心新詞彙出現,無法處理。
不只有斷詞,它還能推理詞性標記 (POS) 與命名實體 (NER)。
同時計算 中文斷詞 + 詞性標記 + 命名實體
讓電腦把詞彙以「在該句子內的意義」為單位切割出來。

Articut 啟動方法

請登入 卓騰 API 會員資料Articut 標籤下的 打包 Docker 項目中,勾選 [啟動器] 並選擇 [Articut][LokiTool] 的版本後,按下 下載 ArticutDocker 按鈕。 (檔案名稱 ArticutDocker.zip)

解壓縮後將檔案放至於同一目錄下,目錄結構請參考:

Step 1

[Docker]

$ sudo gpasswd -a $USER docker

請確認 Server 的[啟用帳號]已經加到 Docker Group,不需要 sudo 可以直接使用 Docker 指令
若沒有設定請輸入右側 shell 指令:

[nerdctl]

$ containerd-rootless-setuptool.sh install

請確認 Server 的[啟用帳號],已安裝 rootless 的 nerdctl,參考文件

Step 2

# sudo apt install net-tools    # Ubuntu
# sudo yum install net-tools    # RHEL
$ ifconfig

請確認以下項目資訊 (卓騰收到的主機資訊):

[MAC ADDRESS]

[主機 SSH KEY 的位置]

Step 3

啟動 ArticutStarter

$ ./ArticutStarter

啟動 ArticutStarter,第一次會比較久,需要建立 articut docker image,大約 2~3 分鐘,第二次以後會直接啟動 Articut,不需要建立 docker image。

CPU core = 4, Worker = 2 (最高可設為 CPU * 2 = 8)

$ ./ArticutStarter -w 2

若需要使用多個 Worker,可在啟動時加上 -w {Num} 參數, {Num} 不能大於主機 CPU 核心數量 * 2。

啟動成功

啟動失敗

Step 4

安裝 ArticutAPI

python3 -m pip install ArticutAPI

下載 ArticutAPI

git clone git@github.com:Droidtown/ArticutAPI.git

測試 Server 的 Articut Docker 是否正常運作。

  1. 請先安裝 ArticutAPI 或 下載 https://github.com/Droidtown/ArticutAPI
  2. 測試 Articut Docker
from ArticutAPI.MP_ArticutAPI import MP_Articut

PORT = 8964
URL = "127.0.0.1"
articut = MP_Articut(url=URL, port=PORT)
result = articut.parse("完成初始狀態, Articut Docker Pro 系統運作正常")

print(result)

請將變數 URL 改為您的 Domain Name 或 IP 位置,Port: 8964。

更新 ArticutDocker

$ ./ArticutStarter -l

請登入 卓騰 API 會員資料Articut 標籤下的 打包 Docker 項目中,選擇要使用的版本並下載 ArticutDocker.zip。 解壓縮後將所有檔案覆蓋ArticutDocker 資料夾內的所有檔案,並執行右側 shell 指令:

設定 Articut Service

which nerdctl
# /home/droidtown/.local/bin/nerdctl
echo $XDG_RUNTIME_DIR
# /run/user/1000

修改 ArticutServiceChecker.py

若是使用 nerdctl 方法啟動 Articut,請修改 ArticutServiceChecker.py 內的兩個變數(pathLIST 與 XDG_RUNTIME_DIR)。
Docker 版本請直接跳過此設定。
- 取得環境變數 $XDG_RUNTIME_DIR 位置,修改 os.environ["XDG_RUNTIME_DIR"] 變數
- 若 nerdctl 不是安裝在 /usr/local/bin 下,請在 pathLIST 新增 nerdctl 路徑

crontab -e
# 此範例為每一分鐘檢查一次 Articut Service 是否正常運作
# ARTICUT_WORKING_PATH 為 Articut 的運作位置
*/1 * * * * python3 /ARTICUT_WORKING_PATH/ArticutServiceChecker.py >> /ARTICUT_WORKING_PATH/logs/ArticutServiceChecker.log 2>&1

設定檢查時間

因 Articut Docker Pro 是在 Containerd 下運行,可使用 crontabsystemd 兩種設定方法,預設每一分鐘檢查一次。

crontab
使用 crontab 設定時間定期檢查 Articut Service 服務是否正常運作,可依據需求調整檢查時間,若 Articut Service 不存在則會自動重啟它。

articut.service

User=USERNAME   # 您的主機啟動 Articut 的 USERNAME
Group=GROUP     # 您的主機啟動 Articut 的 GROUP

# WorkingDirectory 與 ExecStart 必須使用絕對路徑
WorkingDirectory=ARTICUT_WORKING_PATH    # Articut 的運作位置
ExecStart=/bin/sh -c "python3 ARTICUT_WORKING_PATH/ArticutServiceChecker.py"
sudo cp ./articut.service /etc/systemd/system/articut.service
sudo cp ./articut.timer /etc/systemd/system/articut.timer
sudo systemctl daemon-reload
sudo systemctl enable articut.timer    # 開機自動啟動
sudo systemctl start articut.timer     # 執行 articut.timer

sudo systemctl list-timers             # 檢查 articut.timer 是否在排程裡

systemd
請開啟 articut.service 修改 ARTICUT_WORKING_PATH 設定 Articut 的運作位置,若要調整檢查時間請修改 articut.timer,時間格式請參考 systemd timer
將 articut.service 與 articut.timer 放進 /etc/systemd/system/ 目錄,執行右側 shell 指令:

檢查是否已將 articut.timer 設定至排程內:

Articut 進階設定

進階設定檔案 settings.conf 在 ArticutDocker 目錄下,可依據您的機器規格設定 worker 數量 (建議是 CPU 數量)、timeout 時間或 Port 位置 (預設為 8964)...等。

設定內容如下圖:

參數說明請參考:Gunicorn Doc

使用 Articut API

lv2 範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/API/"
payload = {
    "input_str": "我想過過過兒過過的日子。"
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str":"我想過過過兒過過的日子"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 1.0382442474365234,
    "result_pos": ["<ENTITY_pronoun>我</ENTITY_pronoun><ACTION_verb>想</ACTION_verb><ACTION_quantifiedVerb>過過</ACTION_quantifiedVerb><ENTITY_pronoun>過兒</ENTITY_pronoun><VerbP>過過</VerbP><FUNC_inner>的</FUNC_inner><ENTITY_noun>日子</ENTITY_noun>","。"],
    "result_segmentation": ["我/想/過過/過兒/過過/的/日子","。"],
    "result_obj": [[{"text": "我", "pos": "ENTITY_pronoun"},
                    {"text": "想", "pos": "ACTION_verb"},
                    {"text": "過過", "pos": "ACTION_quantifiedVerb"},
                    {"text": "過兒", "pos": "ENTITY_pronoun"},
                    {"text": "過過", "pos": "VerbP"},
                    {"text": "的", "pos": "FUNC_inner"},
                    {"text": "日子", "pos": "ENTITY_noun"}],
                   [{"text": "。","pos": "PUNCTUATION"}]],
    "level": "lv2",
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

lv3 範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/API/"
payload = {
    "input_str": "蔡英文總統在今年五月二十日就職。",
    "time_ref": "2016-01-01 00:00:00",
    "level": "lv3"
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "蔡英文總統在今年五月二十日就職。",
    "time_ref": "2016-01-01 00:00:00",
    "level": "lv3"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "person": [[[0, 3, "蔡英文"]]],
    "event": [["總統", "就職"]],
    "time": [[{"absolute": true,
               "datetime": "2020-05-20 00:00:00",
               "text": "五月二十日",
               "time_span": {"year": [2020, 2020],
                             "month": [5, 5],
                             "weekday": [3, 3],
                             "day": [20, 20],
                             "hour": [0, 23],
                             "minute": [0, 59],
                             "second": [0, 59],
                             "time_period": "night"}}]],
    "site": [[]],
    "entity": [[[3, 5, "總統"]]],
    "number": {},
    "user_defined": [[]],
    "utterance": ["ㄘㄞˋ ㄧㄥ ㄨㄣˊ /ㄗㄨㄥˇ ㄊㄨㄥˇ /ㄗㄞˋ /ㄐㄧㄣ ㄋㄧㄢˊ /ㄨˇ ㄩㄝˋ /ㄦˋ ㄕˊ ㄖˋ /ㄐㄧㄡˋ ㄓˊ ", "。"],
    "input": [[0, 15]],
    "exec_time": 1.4158449172973633,
    "result_pos": ["<ENTITY_person>蔡英文</ENTITY_person><ENTITY_noun>總統</ENTITY_noun><FUNC_inner>在</FUNC_inner><TIME_year>今年</TIME_year><TIME_month>五月</TIME_month><TIME_day>二十日</TIME_day><ACTION_verb>就職</ACTION_verb>",  "。"],
    "result_segmentation": ["蔡英文/總統/在/今年/五月/二十日/就職",  "。"],
    "level": "lv3",
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

POST http://ARTICUT_URL/Articut/API/

參數說明

參數 型態 預設 功能
input_str str "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
level str "lv2" 可為 "lv1"、"lv2" 或 "lv3"。
指定為 lv1 時,將直接透過句子本身的語法結構進行推算,可視為「沒有百科知識」,只有語法能力的斷詞結果。
若指定為 lv2 時,則會額外引入卓騰的百科知識庫輔助運算。
若指定為 lv3 時,能夠計算出人、事、時、地、物、數字及拼音
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
opendata_place bool False 政府開放平台 OpenData 中存有「交通部觀光局蒐集各政府機關所發佈空間化觀光資訊」。Articut 可取用其中的資訊,並標記為 <KNOWLEGED_place>
wikidata bool False 取自 Wikidata 資料的中文名稱 (Label),並標記為<KNOWLEGED_wikiData>
Wikidata 不包含以下類型:
- 單一文字 (不含週期表元素)
- 電影、戲劇、節目名稱 (含系列)
- 電玩遊戲名稱 (含系列)
- 漫畫、動畫名稱
- 小說、書本名稱
- 專輯、歌曲名稱
- 藝術作品名稱
- 提名或入圍獎項
- 動詞、時間
- Wikimedia、Wikidata 列表
chemical bool True Articut 能夠辨識出化學成分,並標記爲<KNOWLEDGE_chemical>
如果文本中沒有化學物質,可關閉功能加快執行速度。
emoji bool True Articut 能夠偵測出 Emoji 符號,並標記爲<ENTITY_oov>
如果文本中沒有 Emoji 符號,可關閉功能加快執行速度。
time_ref str "" "lv3" 功能,時間格式:"yyyy-mm-dd HH:MM:SS",將 input_str 的句子內的時間依據此參數時間為基準,計算句子裡的相對時間或絕對時間並回傳 datetime 格式。

例如:
input_str = "蔡英文總統在今年五月二十日就職"
time_ref = "2016-01-01 00:00:00"
結果為 datetime = "2016-05-20 00:00:00"

若無,則會依據系統時間為基準計算最接近的時間,
假設目前系統時間 = 2020-10-01
結果為 datetime = "2020-05-20 00:00:00"
pinyin str "BOPOMOFO" "lv3" 提供 "BOPOMOFO""HANYU" 兩種,文字轉聲音的標記 (包含破音字)。

回傳內容說明

回傳訊息 型態 說明
status bool 若成功執行並收到斷詞結果,回傳 True;失敗,則回傳 False
msg str 可能為以下的文字:
- Success!: 順利完成斷詞作業。
- Specified level does not exist.: 無法找到您指定的知識程度。知識程度只能為 "lv1"、"lv2" 或 "lv3"。
- Authtication failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
result_pos list 列表中含有每一句各自分開的斷詞結果,詞組前後另外加上了詞性標記 (Part-Of-Speech)。
result_obj list 列表中含有每一句各自分開的斷詞物件結果,包含詞組與詞性標記(Part-Of-Speech)。
result_segmentation str 完整的輸入文句已經斷詞處理並以斜線 ( / ) 標出詞彙斷點。回傳時以字串回傳。
exec_time float 本次斷詞作業耗費的伺服器時間。
version str 本次斷詞作業所使用的演算法版本。
level str 本次斷詞作業所使用的知識能力等級。

使用 Articut Bulk API

lv2 範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/BulkAPI/"
payload = {
    "input_list": ["我想過過過兒過過的日子。", "蔡英文總統在今年五月二十日就職。"]
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/BulkAPI/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_list": ["我想過過過兒過過的日子。", "蔡英文總統在今年五月二十日就職。"]
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "result_list": [
        {"exec_time": 0.37946605682373047,
         "result_pos": ["<ENTITY_pronoun>我</ENTITY_pronoun><ACTION_verb>想</ACTION_verb><ACTION_quantifiedVerb>過過</ACTION_quantifiedVerb><ENTITY_pronoun>過兒</ENTITY_pronoun><VerbP>過過</VerbP><FUNC_inner>的</FUNC_inner><ENTITY_noun>日子</ENTITY_noun>", "。"],
         "result_segmentation": ["我/想/過過/過兒/過過/的/日子", "。"],
         "result_obj": [[{"text": "我", "pos": "ENTITY_pronoun"},
                         {"text": "想", "pos": "ACTION_verb"},
                         {"text": "過過", "pos": "ACTION_quantifiedVerb"},
                         {"text": "過兒", "pos": "ENTITY_pronoun"},
                         {"text": "過過", "pos": "VerbP"},
                         {"text": "的", "pos": "FUNC_inner"},
                         {"text": "日子", "pos": "ENTITY_noun"}],
                        [{"text": "。", "pos": "PUNCTUATION"}]]},
        {"exec_time": 0.43135738372802734,
         "result_pos": ["<ENTITY_person>蔡英文</ENTITY_person><ENTITY_noun>總統</ENTITY_noun><FUNC_inner>在</FUNC_inner><TIME_year>今年</TIME_year><TIME_month>五月</TIME_month><TIME_day>二十日</TIME_day><ACTION_verb>就職</ACTION_verb>", "。"],
         "result_segmentation": ["蔡英文/總統/在/今年/五月/二十日/就職", "。"],
         "result_obj": [[{"text": "蔡英文", "pos": "ENTITY_person"},
                         {"text": "總統", "pos": "ENTITY_noun"},
                         {"text": "在", "pos": "FUNC_inner"},
                         {"text": "今年", "pos": "TIME_year"},
                         {"text": "五月", "pos": "TIME_month"},
                         {"text": "二十日", "pos": "TIME_day"},
                         {"text": "就職", "pos": "ACTION_verb"}],
                        [{"text": "。", "pos": "PUNCTUATION"}]]}],
    "level": "lv2",
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

POST http://ARTICUT_URL/Articut/BulkAPI/

參數說明

參數 型態 預設 功能
input_list list "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
level str "lv2" 可為 "lv1"、"lv2" 或 "lv3"。
指定為 lv1 時,將直接透過句子本身的語法結構進行推算,可視為「沒有百科知識」,只有語法能力的斷詞結果。
若指定為 lv2 時,則會額外引入卓騰的百科知識庫輔助運算。
若指定為 lv3 時,能夠計算出人、事、時、地、物、數字及拼音
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
opendata_place bool False 政府開放平台 OpenData 中存有「交通部觀光局蒐集各政府機關所發佈空間化觀光資訊」。Articut 可取用其中的資訊,並標記為 <KNOWLEGED_place>
wikidata bool False 取自 Wikidata 資料的中文名稱 (Label),並標記為<KNOWLEGED_wikiData>
Wikidata 不包含以下類型:
- 單一文字 (不含週期表元素)
- 電影、戲劇、節目名稱 (含系列)
- 電玩遊戲名稱 (含系列)
- 漫畫、動畫名稱
- 小說、書本名稱
- 專輯、歌曲名稱
- 藝術作品名稱
- 提名或入圍獎項
- 動詞、時間
- Wikimedia、Wikidata 列表
chemical bool True Articut 能夠辨識出化學成分,並標記爲<KNOWLEDGE_chemical>
如果文本中沒有化學物質,可關閉功能加快執行速度。
emoji bool True Articut 能夠偵測出 Emoji 符號,並標記爲<ENTITY_oov>
如果文本中沒有 Emoji 符號,可關閉功能加快執行速度。
time_ref str "" "lv3" 功能,時間格式:"yyyy-mm-dd HH:MM:SS",將 input_str 的句子內的時間依據此參數時間為基準,計算句子裡的相對時間或絕對時間並回傳 datetime 格式。

例如:
input_str = "蔡英文總統在今年五月二十日就職"
time_ref = "2016-01-01 00:00:00"
結果為 datetime = "2016-05-20 00:00:00"

若無,則會依據系統時間為基準計算最接近的時間,
假設目前系統時間 = 2020-10-01
結果為 datetime = "2020-05-20 00:00:00"
pinyin str "BOPOMOFO" "lv3" 提供 "BOPOMOFO""HANYU" 兩種,文字轉聲音的標記 (包含破音字)。

回傳內容說明

回傳訊息 型態 說明
status bool 若成功執行並收到斷詞結果,回傳 True;失敗,則回傳 False
msg str 可能為以下的文字:
- Success!: 順利完成斷詞作業。
- Specified level does not exist.: 無法找到您指定的知識程度。知識程度只能為 "lv1"、"lv2" 或 "lv3"。
- Authtication failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Insufficient word count balance.: 您帳號下的字數餘額不足以處理本次斷詞需求。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
result_pos list 列表中含有每一句各自分開的斷詞結果,詞組前後另外加上了詞性標記 (Part-Of-Speech)。
result_obj list 列表中含有每一句各自分開的斷詞物件結果,包含詞組與詞性標記(Part-Of-Speech)。
result_segmentation str 完整的輸入文句已經斷詞處理並以斜線 ( / ) 標出詞彙斷點。回傳時以字串回傳。
exec_time float 本次斷詞作業耗費的伺服器時間。
version str 本次斷詞作業所使用的演算法版本。
level str 本次斷詞作業所使用的知識能力等級。

使用 Articut WebSocket API

lv2 範例程式:

from websocket import create_connection
import json

url = "ws://ARTICUT_URL/Articut/WebSocket/API/"
payload = {
    "input_str": "我想過過過兒過過的日子。"
}

ws = create_connection(url)
ws.send(json.dumps(payload))
response = json.loads(ws.recv())
var url = "http://ARTICUT_URL/Articut/WebSocket/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "我想過過過兒過過的日子。"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 0.0897529125213623,
    "result_pos": ["<ENTITY_pronoun>我</ENTITY_pronoun><ACTION_verb>想</ACTION_verb><ACTION_quantifiedVerb>過過</ACTION_quantifiedVerb><ENTITY_pronoun>過兒</ENTITY_pronoun><VerbP>過過</VerbP><FUNC_inner>的</FUNC_inner><ENTITY_noun>日子</ENTITY_noun>","。"],
    "result_segmentation": ["我/想/過過/過兒/過過/的/日子","。"],
    "result_obj": [[{"text": "我", "pos": "ENTITY_pronoun"},
                    {"text": "想", "pos": "ACTION_verb"},
                    {"text": "過過", "pos": "ACTION_quantifiedVerb"},
                    {"text": "過兒", "pos": "ENTITY_pronoun"},
                    {"text": "過過", "pos": "VerbP"},
                    {"text": "的", "pos": "FUNC_inner"},
                    {"text": "日子", "pos": "ENTITY_noun"}],
                   [{"text": "。","pos": "PUNCTUATION"}]],
    "level": "lv2",
    "version": "v225",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

lv3 範例程式:

from websocket import create_connection
import json

url = "ws://ARTICUT_URL/Articut/WebSocket/API/"
payload = {
    "input_str": "蔡英文總統在今年五月二十日就職。",
    "time_ref": "2016-01-01 00:00:00",
    "level": "lv3"
}

ws = create_connection(url)
ws.send(json.dumps(payload))
response = json.loads(ws.recv())
var url = "http://ARTICUT_URL/Articut/WebSocket/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "蔡英文總統在今年五月二十日就職。",
    "time_ref": "2016-01-01 00:00:00",
    "level": "lv3"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "person": [[[0, 3, "蔡英文"]]],
    "event": [["總統", "就職"]],
    "time": [[{"absolute": true,
               "datetime": "2020-05-20 00:00:00",
               "text": "五月二十日",
               "time_span": {"year": [2020, 2020],
                             "month": [5, 5],
                             "weekday": [3, 3],
                             "day": [20, 20],
                             "hour": [0, 23],
                             "minute": [0, 59],
                             "second": [0, 59],
                             "time_period": "night"}}]],
    "site": [[]],
    "entity": [[[3, 5, "總統"]]],
    "number": {},
    "user_defined": [[]],
    "utterance": ["ㄘㄞˋ ㄧㄥ ㄨㄣˊ /ㄗㄨㄥˇ ㄊㄨㄥˇ /ㄗㄞˋ /ㄐㄧㄣ ㄋㄧㄢˊ /ㄨˇ ㄩㄝˋ /ㄦˋ ㄕˊ ㄖˋ /ㄐㄧㄡˋ ㄓˊ ", "。"],
    "input": [[0, 15]],
    "exec_time": 0.33067893981933594,
    "result_pos": ["<ENTITY_person>蔡英文</ENTITY_person><ENTITY_noun>總統</ENTITY_noun><FUNC_inner>在</FUNC_inner><TIME_year>今年</TIME_year><TIME_month>五月</TIME_month><TIME_day>二十日</TIME_day><ACTION_verb>就職</ACTION_verb>",  "。"],
    "result_segmentation": ["蔡英文/總統/在/今年/五月/二十日/就職",  "。"],
    "level": "lv3",
    "version": "v225",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

WebSocket Connection

WebSocket ws://ARTICUT_URL/Articut/WebSocket/API/

參數說明

參數 型態 預設 功能
input_str str "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
level str "lv2" 可為 "lv1"、"lv2" 或 "lv3"。
指定為 lv1 時,將直接透過句子本身的語法結構進行推算,可視為「沒有百科知識」,只有語法能力的斷詞結果。
若指定為 lv2 時,則會額外引入卓騰的百科知識庫輔助運算。
若指定為 lv3 時,能夠計算出人、事、時、地、物、數字及拼音
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
opendata_place bool False 政府開放平台 OpenData 中存有「交通部觀光局蒐集各政府機關所發佈空間化觀光資訊」。Articut 可取用其中的資訊,並標記為 <KNOWLEGED_place>
wikidata bool False 取自 Wikidata 資料的中文名稱 (Label),並標記為<KNOWLEGED_wikiData>
Wikidata 不包含以下類型:
- 單一文字 (不含週期表元素)
- 電影、戲劇、節目名稱 (含系列)
- 電玩遊戲名稱 (含系列)
- 漫畫、動畫名稱
- 小說、書本名稱
- 專輯、歌曲名稱
- 藝術作品名稱
- 提名或入圍獎項
- 動詞、時間
- Wikimedia、Wikidata 列表
chemical bool True Articut 能夠辨識出化學成分,並標記爲<KNOWLEDGE_chemical>
如果文本中沒有化學物質,可關閉功能加快執行速度。
emoji bool True Articut 能夠偵測出 Emoji 符號,並標記爲<ENTITY_oov>
如果文本中沒有 Emoji 符號,可關閉功能加快執行速度。
time_ref str "" "lv3" 功能,時間格式:"yyyy-mm-dd HH:MM:SS",將 input_str 的句子內的時間依據此參數時間為基準,計算句子裡的相對時間或絕對時間並回傳 datetime 格式。

例如:
input_str = "蔡英文總統在今年五月二十日就職"
time_ref = "2016-01-01 00:00:00"
結果為 datetime = "2016-05-20 00:00:00"

若無,則會依據系統時間為基準計算最接近的時間,
假設目前系統時間 = 2020-10-01
結果為 datetime = "2020-05-20 00:00:00"
pinyin str "BOPOMOFO" "lv3" 提供 "BOPOMOFO""HANYU" 兩種,文字轉聲音的標記 (包含破音字)。

回傳內容說明

回傳訊息 型態 說明
status bool 若成功執行並收到斷詞結果,回傳 True;失敗,則回傳 False
msg str 可能為以下的文字:
- Success!: 順利完成斷詞作業。
- Specified level does not exist.: 無法找到您指定的知識程度。知識程度只能為 "lv1"、"lv2" 或 "lv3"。
- Authtication failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
result_pos list 列表中含有每一句各自分開的斷詞結果,詞組前後另外加上了詞性標記 (Part-Of-Speech)。
result_obj list 列表中含有每一句各自分開的斷詞物件結果,包含詞組與詞性標記(Part-Of-Speech)。
result_segmentation str 完整的輸入文句已經斷詞處理並以斜線 ( / ) 標出詞彙斷點。回傳時以字串回傳。
exec_time float 本次斷詞作業耗費的伺服器時間。
version str 本次斷詞作業所使用的演算法版本。
level str 本次斷詞作業所使用的知識能力等級。

使用 Articut WebSocket Bulk API

lv2 範例程式:

from websocket import create_connection
import json

url = "ws://ARTICUT_URL/Articut/WebSocket/BulkAPI/"
payload = {
    "input_list": ["我想過過過兒過過的日子。", "蔡英文總統在今年五月二十日就職。"]
}

ws = create_connection(url)
ws.send(json.dumps(payload))
response = json.loads(ws.recv())
var url = "http://ARTICUT_URL/Articut/WebSocket/BulkAPI/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_list": ["我想過過過兒過過的日子。", "蔡英文總統在今年五月二十日就職。"]
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "result_list": [
        {"exec_time": 0.016541242599487305,
         "result_pos": ["<ENTITY_pronoun>我</ENTITY_pronoun><ACTION_verb>想</ACTION_verb><ACTION_quantifiedVerb>過過</ACTION_quantifiedVerb><ENTITY_pronoun>過兒</ENTITY_pronoun><VerbP>過過</VerbP><FUNC_inner>的</FUNC_inner><ENTITY_noun>日子</ENTITY_noun>", "。"],
         "result_segmentation": ["我/想/過過/過兒/過過/的/日子", "。"],
         "result_obj": [[{"text": "我", "pos": "ENTITY_pronoun"},
                         {"text": "想", "pos": "ACTION_verb"},
                         {"text": "過過", "pos": "ACTION_quantifiedVerb"},
                         {"text": "過兒", "pos": "ENTITY_pronoun"},
                         {"text": "過過", "pos": "VerbP"},
                         {"text": "的", "pos": "FUNC_inner"},
                         {"text": "日子", "pos": "ENTITY_noun"}],
                        [{"text": "。", "pos": "PUNCTUATION"}]]},
        {"exec_time": 0.035096168518066406,
         "result_pos": ["<ENTITY_person>蔡英文</ENTITY_person><ENTITY_noun>總統</ENTITY_noun><FUNC_inner>在</FUNC_inner><TIME_year>今年</TIME_year><TIME_month>五月</TIME_month><TIME_day>二十日</TIME_day><ACTION_verb>就職</ACTION_verb>", "。"],
         "result_segmentation": ["蔡英文/總統/在/今年/五月/二十日/就職", "。"],
         "result_obj": [[{"text": "蔡英文", "pos": "ENTITY_person"},
                         {"text": "總統", "pos": "ENTITY_noun"},
                         {"text": "在", "pos": "FUNC_inner"},
                         {"text": "今年", "pos": "TIME_year"},
                         {"text": "五月", "pos": "TIME_month"},
                         {"text": "二十日", "pos": "TIME_day"},
                         {"text": "就職", "pos": "ACTION_verb"}],
                        [{"text": "。", "pos": "PUNCTUATION"}]]}],
    "level": "lv2",
    "version": "v225",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

WebSocket Connection

WebSocket ws://ARTICUT_URL/Articut/WebSocket/BulkAPI/

參數說明

參數 型態 預設 功能
input_list list "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
level str "lv2" 可為 "lv1"、"lv2" 或 "lv3"。
指定為 lv1 時,將直接透過句子本身的語法結構進行推算,可視為「沒有百科知識」,只有語法能力的斷詞結果。
若指定為 lv2 時,則會額外引入卓騰的百科知識庫輔助運算。
若指定為 lv3 時,能夠計算出人、事、時、地、物、數字及拼音
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
opendata_place bool False 政府開放平台 OpenData 中存有「交通部觀光局蒐集各政府機關所發佈空間化觀光資訊」。Articut 可取用其中的資訊,並標記為 <KNOWLEGED_place>
wikidata bool False 取自 Wikidata 資料的中文名稱 (Label),並標記為<KNOWLEGED_wikiData>
Wikidata 不包含以下類型:
- 單一文字 (不含週期表元素)
- 電影、戲劇、節目名稱 (含系列)
- 電玩遊戲名稱 (含系列)
- 漫畫、動畫名稱
- 小說、書本名稱
- 專輯、歌曲名稱
- 藝術作品名稱
- 提名或入圍獎項
- 動詞、時間
- Wikimedia、Wikidata 列表
chemical bool True Articut 能夠辨識出化學成分,並標記爲<KNOWLEDGE_chemical>
如果文本中沒有化學物質,可關閉功能加快執行速度。
emoji bool True Articut 能夠偵測出 Emoji 符號,並標記爲<ENTITY_oov>
如果文本中沒有 Emoji 符號,可關閉功能加快執行速度。
time_ref str "" "lv3" 功能,時間格式:"yyyy-mm-dd HH:MM:SS",將 input_str 的句子內的時間依據此參數時間為基準,計算句子裡的相對時間或絕對時間並回傳 datetime 格式。

例如:
input_str = "蔡英文總統在今年五月二十日就職"
time_ref = "2016-01-01 00:00:00"
結果為 datetime = "2016-05-20 00:00:00"

若無,則會依據系統時間為基準計算最接近的時間,
假設目前系統時間 = 2020-10-01
結果為 datetime = "2020-05-20 00:00:00"
pinyin str "BOPOMOFO" "lv3" 提供 "BOPOMOFO""HANYU" 兩種,文字轉聲音的標記 (包含破音字)。

回傳內容說明

回傳訊息 型態 說明
status bool 若成功執行並收到斷詞結果,回傳 True;失敗,則回傳 False
msg str 可能為以下的文字:
- Success!: 順利完成斷詞作業。
- Specified level does not exist.: 無法找到您指定的知識程度。知識程度只能為 "lv1"、"lv2" 或 "lv3"。
- Authtication failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Insufficient word count balance.: 您帳號下的字數餘額不足以處理本次斷詞需求。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
result_pos list 列表中含有每一句各自分開的斷詞結果,詞組前後另外加上了詞性標記 (Part-Of-Speech)。
result_obj list 列表中含有每一句各自分開的斷詞物件結果,包含詞組與詞性標記(Part-Of-Speech)。
result_segmentation str 完整的輸入文句已經斷詞處理並以斜線 ( / ) 標出詞彙斷點。回傳時以字串回傳。
exec_time float 本次斷詞作業耗費的伺服器時間。
version str 本次斷詞作業所使用的演算法版本。
level str 本次斷詞作業所使用的知識能力等級。

取得目前版本

範例程式:

from requests import get

url = "http://ARTICUT_URL/Articut/Version/"

response = get(url)
var url = "http://ARTICUT_URL/Articut/Version/";

var xhr = new XMLHttpRequest();
xhr.open("GET", url);

xhr.setRequestHeader("Accept", "application/json");

xhr.onreadystatechange = function () {
   if (xhr.readyState === 4) {
      console.log(xhr.status);
      console.log(xhr.responseText);
   }};

xhr.send();

回傳結果 (JSON 格式):

{
    "status": true,
    "version": "v220",
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

GET http://ARTICUT_URL/Articut/Version/

回傳內容說明

回傳訊息 型態 說明
status bool 若成功執行並取回結果,回傳 True;失敗,則回傳 False
msg str 可能為以下的文字:
- Success!: 順利取得版本號。
- Authtication failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
version str 目前使用的 Articut 版本。

使用自定義辭典

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/API/"
payload = {
    "input_str": "我正在計劃地球人類補完計劃",
    "user_defined_dict_file": {"地球人類補完計劃": ["人類補完計劃", "補完計劃"]}
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "我正在計劃地球人類補完計劃",
    "user_defined_dict_file": {"地球人類補完計劃": ["人類補完計劃", "補完計劃"]}
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 0.9545776844024658,
    "result_pos": ["<ENTITY_pronoun>我</ENTITY_pronoun><ASPECT>正在</ASPECT><ACTION_verb>計劃</ACTION_verb><UserDefined>地球人類補完計劃</UserDefined>"],
    "result_segmentation": ["我/正在/計劃/地球人類補完計劃"],
    "result_obj": [[{"text": "我", "pos": "ENTITY_pronoun"},
                    {"text": "正在", "pos": "ASPECT"},
                    {"text": "計劃", "pos": "ACTION_verb"},
                    {"text": "地球人類補完計劃", "pos": "UserDefined"}]],
    "level": "lv2",
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

因為 Articut 只處理「語言知識」而不處理「百科知識」。
我們提供「使用者自定義」詞彙表的功能,並標記為 <UserDefined>
使用 Dictionary 格式,請自行編寫。

HTTP Request

POST http://ARTICUT_URL/Articut/API/

參數說明

參數 型態 預設 功能
input_str str "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 順利完成斷詞作業。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。

調用觀光資訊資料庫

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/API/"
payload = {
    "input_str": "花蓮的原野牧場有一間餐廳",
    "opendata_place": True
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "花蓮的原野牧場有一間餐廳",
    "opendata_place": true
}`;

xhr.send(data);

回傳內容 (JSON 格式):

{
    "exec_time": 0.5755200386047363,
    "result_pos": ["<LOCATION>花蓮</LOCATION><FUNC_inner>的</FUNC_inner><KNOWLEDGE_place>原野牧場</KNOWLEDGE_place><ACTION_verb>有</ACTION_verb><ENTITY_classifier>一間</ENTITY_classifier><ENTITY_noun>餐廳</ENTITY_noun>"],
    "result_segmentation": ["花蓮/的/原野牧場/有/一間/餐廳"],
    "result_obj": [[{"text": "花蓮", "pos": "LOCATION"},
                    {"text": "的", "pos": "FUNC_inner"},
                    {"text": "原野牧場", "pos": "KNOWLEDGE_place"},
                    {"text": "有", "pos": "ACTION_verb"},
                    {"text": "一間", "pos": "ENTITY_classifier"},
                    {"text": "餐廳", "pos": "ENTITY_noun"}]],
    "level": "lv2",
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

政府開放平台中存有「交通部觀光局蒐集各政府機關所發佈空間化觀光資訊」。
Articut 可取用其中的資訊,並標記為 <KNOWLEDGE_place>

HTTP Request

POST http://ARTICUT_URL/Articut/API/

詞性標記 (Part-of-speech, POS)

我(ENTITY_pronoun) 終生(ENTITY_nouny) 所(FUNC_inner) 追尋(ACTION_verb) 的(FUNC_inner) 標的(ENTITY_nouny)

只有斷詞結果,無法處理句子的意義,需要 POS 才能進行語意分析與理解。 主要依據詞彙意義對詞進行劃分每個單詞在句子內所扮演的詞性。

標記類別

類別 標記名稱
時間類 TIME
實體類 ENTITY
修飾詞 IDIOM、MODIFIER、MODIFIER_color、ModifierP、DegreeP、QUANTIFIER
動詞類 ACTION、ASPECT、MODAL、AUX
功能詞 FUNC
句型詞 CLAUSE
NER類 LOCATION、KNOWLEDGE、UserDefined、RANGE

實體類 (Entity)

「實詞」是詞類的一種,又稱「名詞」,可以獨立成句。可指代人、物、事、時、地、情感、概念、方位的名詞等實體或抽象事物的詞。

有幾個詞組組合規則如下:

標記名稱 說明
<ENTITY_num> 單純數字表示
<ENTITY_classifier> 量詞 (或中文系稱的「分類詞」)
<ENTITY_measurement> 量測詞 (表示是一個測量值。例如「一公斤」、「30公分」…等)
<ENTITY_person> 名詞,且系統推測應該指某個「人類」。(以漢人常見三字名、單名為主)
<ENTITY_pronoun> 代名詞。
(若有需要,可再細分「專指代名詞」(e.g., 爸爸) 或「泛指代名詞」(e.g., 老公公))
<ENTITY_possessive> 所有格名詞。
<ENTITY_noun> 系統已認得的名詞。
<ENTITY_nounHead> 名詞組的中心語。
<ENTITY_nouny> 系統推測應該是名詞。
<ENTITY_oov> 系統不知道是什麼,但把它當名詞用。
<ENTITY_DetPhrase> 限定詞詞組,由一個「限定詞 (這、那)」和一個「量詞 (一部,兩台)」組成。
e.g., <ENTITY_DetPhrase>這一台</ENTITY_DetPhrase>

動詞類 (Verb)

「動詞」用來表示動作、發生或是存在的狀態,可以單獨存在或與不同的修飾詞、助詞和主詞組成句子。

標記名稱 說明
<ACTION_lightVerb> 輕動詞 (e.g., 被、把、弄…)
<ACTION_verb> 動詞
<ACTION_eventQuantifier> 動作量詞,長得很像名詞的量詞。 e.g., 一部、兩台
它的測量目標是「動作的次數」,而不是「名詞的數量」。 e.g., 跑 <ACTION_eventQuantifier>一趟</ACTION_eventQuantifier>
<ACTION_quantifiedVerb> 量化動詞,表示該動作只做了一定程度的量。 e.g., 看一看、瞧瞧、嚐嚐看…等
<VerbP> 動詞組,指的是一個動詞 (Verb)加上時態 (ASPECT)受詞 (ENTITY)的動詞。 e.g.,
<ACTION\_verb></ACTION\_verb><ENTITY\_DetPhrase>這本</ENTITY\_DetPhrase><ENTITY\_noun></ENTITY\_noun>
<VerbP>讀過</VerbP><ENTITY\_DetPhrase>這本</ENTITY\_DetPhrase><ENTITY\_noun></ENTITY\_noun>
<ASPECT> 時態標記 (了、著…等)
<AUX> 助動詞 (e.g., 是、為…)
<MODAL> 情態標記詞 (e.g., 可以、能、會…)

時間類 (Time)

與時間相關的詞彙,包含相對時間、絕對時間與中文傳統的時間單位。

標記名稱 說明
<TIME_holiday> 和節日相關的時間。
<TIME_justtime> 和現在或瞬時相關的時間。
<TIME_day> 和以「天」為單位相關的時間。
<TIME_week> 和以「週」為單位相關的時間。
<TIME_month> 和以「月」為單位相關的時間。
<TIME_season> 和以「季」為單位相關的時間。
<TIME_year> 和以「年」為單位相關的時間。
<TIME_decade> 和以「比年還要長的時間」為單位相關的時間。

修飾詞 (Modifier)

用來修飾句子,使句子所要表達的意思更豐富、完整。

標記名稱 說明
<DegreeP> 程度詞詞組:由一個「形容詞」加上一個「程度中心語 (e.g.,很、非常…)」組成。
e.g., <DegreeP>很明顯</DegreeP>
<IDIOM> 成語或諺語。
<MODIFIER> 形容詞及副詞。
<MODIFIER_color> 顏色形容詞。
<ModifierP> 形容詞或副詞詞組。由一個「形容詞/副詞」加上一「…地」組成。
e.g., <ModifierP>明顯地</ModifierP>
<QUANTIFIER> 量化詞標記 (都、全…等)

功能詞 (Function Word)

指的是中文詞彙中沒有實際意義的詞,且無法獨立成句。
例如:副詞、介詞、連接詞、助詞、歎詞等。

標記名稱 說明
<FUNC_conjunction> 連接功能詞
<FUNC_degreeHead> 形容詞組的程度中心語(很、極、非常…等)。表示形容詞到這裡就不會再疊加了。其旁邊形容詞會和此程度中心語形成一個用來「描述程度」的修飾、形容用語。
<FUNC_determiner> 定冠詞 (或中文系稱的「定語」)
<FUNC_inner> 內向功能詞 (完整語意可在本句以內滿足。e.g., 在…)
<FUNC_inter> 外向功能詞 (完整語意需在本句以外滿足。e.g., 然而…)
<FUNC_modifierHead> 形容詞及副詞組的中心語。
<FUNC_negation> 否定功能詞

句型詞 (Clause)

問句類 (wh-問句及 yes-no 問句) 或直述句類。

標記名稱 說明
<CLAUSE_AnotAQ> 「A-not-A」問句
<CLAUSE_YesNoQ> 「是非」問句
<CLAUSE_WhoQ> 「誰」問句
<CLAUSE_WhatQ> 「物」問句
<CLAUSE_WhereQ> 「何地」問句
<CLAUSE_WhenQ> 「何時」問句
<CLAUSE_WhyQ> 「原因」問句
<CLAUSE_HowQ> 「程度/過程」問句
<CLAUSE_Particle> 沒什麼特別意義,就只是一個句子裡的小元素。(e.g., 啊、啦、喔…)

命名實體類 (Named Entity Recognition, NER)

實體指一個真實世界的物件,可能是地方、人物、組織、產品、抽象或具體的東西等具有專有名稱的物件。
識別文本中具有特定意義的實體 (中文人名、行政地名、其他名詞...等)

標記名稱 說明
<LOCATION> 地名
<RANGE_locality> 地名範圍標記
<RANGE_period> 時間範圍標記
<UserDefined> 使用者自定義的詞彙
<KNOWLEDGE_addTW> 台灣地址
<KNOWLEDGE_currency> 金錢。例如: <KNOWLEDGE_currency>100美元</KNOWLEDGE_currency><KNOWLEDGE_currency>100元</KNOWLEDGE_currency><ENTITY_noun>美金</ENTITY_noun>
<KNOWLEDGE_lawTW> 法條索引
<KNOWLEDGE_place> 政府開放平台中的觀光景點
<KNOWLEDGE_routeTW> 台灣道路名稱
<KNOWLEDGE_url> 網址
<KNOWLEDGE_wikiData> WikiData 開放資料
<KNOWLEDGE_chemical> 化學物質

進階功能

Articut Addons

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/Addons/"
payload = {
    "result_pos": ["<MODIFIER>剛剛</MODIFIER><ACTION_verb>得知</ACTION_verb><KNOWLEDGE_place>435藝文特區</KNOWLEDGE_place><AUX>是</ AUX><ENTITY_classifier>個</ENTITY_classifier><ACTION_verb>遛</ACTION_verb><ENTITY_nouny>小孩</ENTITY_nouny><FUNC_inner>的</FUNC_inner><MODIFIER>好</MODIFIER><ENTITY_noun>地方</ENTITY_noun>",
                   ",",
                   "<ENTITY_pronoun>你</ENTITY_pronoun><CLAUSE_YesNoQ><AUX>是</AUX><FUNC_negation>否</FUNC_negation></CLAUSE_YesNoQ><ACTION_verb>知道</ACTION_verb><TIME_day>傍晚</TIME_day><MODAL>可以</MODAL><ACTION_verb>到</ACTION_verb><KNOWLEDGE_place>觀音亭</KNOWLEDGE_place><ACTION_verb>去</ACTION_verb><ACTION_verb>看</ACTION_verb><ENTITY_nouny>夕陽</ENTITY_nouny><CLAUSE_Particle>喔</CLAUSE_Particle>",
                   "!",
                   "<TIME_day>今日</TIME_day><TIME_day>傍晚</TIME_day><FUNC_inner>在</FUNC_inner><LOCATION>新竹市</LOCATION><LOCATION>北區</LOCATION><ACTION_verb>溜</ACTION_verb><ENTITY_nouny>小狗</ENTITY_nouny>",
                   "。"],
    "func": ["get_all"],
    "index_with_pos": True
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Addons/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "result_pos": ["<MODIFIER>剛剛</MODIFIER><ACTION_verb>得知</ACTION_verb><KNOWLEDGE_place>435藝文特區</KNOWLEDGE_place><AUX>是</ AUX><ENTITY_classifier>個</ENTITY_classifier><ACTION_verb>遛</ACTION_verb><ENTITY_nouny>小孩</ENTITY_nouny><FUNC_inner>的</FUNC_inner><MODIFIER>好</MODIFIER><ENTITY_noun>地方</ENTITY_noun>",
                   ",",
                   "<ENTITY_pronoun>你</ENTITY_pronoun><CLAUSE_YesNoQ><AUX>是</AUX><FUNC_negation>否</FUNC_negation></CLAUSE_YesNoQ><ACTION_verb>知道</ACTION_verb><TIME_day>傍晚</TIME_day><MODAL>可以</MODAL><ACTION_verb>到</ACTION_verb><KNOWLEDGE_place>觀音亭</KNOWLEDGE_place><ACTION_verb>去</ACTION_verb><ACTION_verb>看</ACTION_verb><ENTITY_nouny>夕陽</ENTITY_nouny><CLAUSE_Particle>喔</CLAUSE_Particle>",
                   "!",
                   "<TIME_day>今日</TIME_day><TIME_day>傍晚</TIME_day><FUNC_inner>在</FUNC_inner><LOCATION>新竹市</LOCATION><LOCATION>北區</LOCATION><ACTION_verb>溜</ACTION_verb><ENTITY_nouny>小狗</ENTITY_nouny>",
                   "。"],
    "func": ["get_all"],
    "index_with_pos": true
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
"msg": "Success!",
"status": true,
"results": {"addtw_list": [[], [], [], [], [], []],
            "chemical_list": [[], [], [], [], [], []],
            "color_list": [[], [], [], [], [], []],
            "content_word_list": [[[10, 12, "剛剛"],
                                   [36, 38, "得知"],
                                   [159, 160, "遛"],
                                   [188, 190, "小孩"],
                                   [241, 242, "好"],
                                   [266, 268, "地方"]],
                                  [],
                                  [[122, 124, "知道"],
                                   [191, 192, "到"],
                                   [257, 258, "去"],
                                   [285, 286, "看"],
                                   [314, 316, "夕陽"]],
                                  [],
                                  [[132, 133, "溜"], [161, 163, "小狗"]],
                                  []],
            "currency_list": [[], [], [], [], [], []],
            "currency_greedy_list": [[], [], [], [], [], []],
            "location_stem_list": [[],
                                   [],
                                   [],
                                   [],
                                   [[82, 85, "新竹市"], [106, 108, "北區"]],
                                   []],
            "noun_stem_list": [[[188, 190, "小孩"],
                                [266, 268, "地方"]],
                               [],
                               [[314, 316, "夕陽"]],
                               [],
                               [[161, 163, "小狗"]],
                               []],
            "opendata_place_list": [[[69, 76, "435藝文特區"]],
                                    [],
                                    [[223, 226, "觀音亭"]],
                                    [],
                                    [],
                                    []],
            "person_and_pronoun_list": [[],
                                        [],
                                        [[16, 17, "你"]],
                                        [], 
                                        [], 
                                        []],
            "person_list": [[], [], [], [], [], []],
            "question_list": [[],
                              [],
                              [["<CLAUSE_YesNoQ>", "你是否知道傍晚可以到觀音亭去看夕陽喔"]],
                              [],
                              [],
                              []],
            "time_list": [[],
                          [],
                          [[148, 150, "傍晚"]],
                          [],
                          [[10, 12, "今日"],
                           [33, 35, "傍晚"]],
                          []],
            "verb_stem_list": [[[36, 38, "得知"], 
                                [159, 160, "遛"]],
                               [],
                               [[122, 124, "知道"],
                                [191, 192, "到"],
                                [257, 258, "去"],
                                [285, 286, "看"]],
                               [],
                               [[132, 133, "溜"]],
                               []],
            "wikidata_list": [[], [], [], [], [], []]}
}

可以依需求找出「名詞」、「動詞」或是「形容詞」…等詞彙語意本身已經完整的詞彙。

HTTP Request

POST http://ARTICUT_URL/Articut/Addons/

參數說明

參數 型態 預設 功能
result_pos dict Articut 斷詞結果標記。
index_with_pos bool True 計算所擷取的字串位置時,是否包含詞性標記 (POS)。
func list ["get_all"] 可設置為以下參數:
- get_all: 取出以下所有參數的結果。
- get_addtw: 取出斷詞結果中含有 <KNOWLEDGE_addTW> 標籤的台灣地址字串。例如「台北市中山區民權東路二段109號」。
- get_chemical: 取出斷詞結果中含有 <KNOWLEDGE_chemical> 標籤的化學物質。每個句子內的化學物質為一個 list。
- get_color: 取出斷詞結果中含有 <MODIFIER_color> 標籤的顏色字串。每個句子內的顏色為一個 list。
- get_content_word: 取出斷詞結果中的實詞 (content word)。每個句子內的實詞為一個 list。
- get_currency: 取出斷詞結果中含有 <KNOWLEDGE_currency> 標籤的貨幣金額字串。每個句子內的貨幣金額為一個 list。
- get_currency_greedy: 取出斷詞結果中含有 <KNOWLEDGE_currency> 標籤與 <ENTITY_noun> <ENTITY_num> 組合標籤的貨幣金額字串。每個句子內的貨幣金額為一個 list。
- get_location_stem: 取出斷詞結果中的地理位置 (location)。此處指的是地理位置標記的行政區地名詞彙,例如「台北」、「桃園」、「墨西哥」。每個句子內的地理位置列為一個 list。
- get_noun_stem: 取出斷詞結果中的名詞 (noun)。此處指的是 ENTITY_nounENTITY_nounyENTITY_nounHeadENTITY_oov 標記的名詞詞彙。每個句子內的名詞為一個 list。
- get_opendata_place: 取出斷詞結果中的景點 (KNOWLEDGE_place)。此處指的是景點 KNOWLEDGE_place 標記的非行政地點名稱詞彙,例如「鹿港老街」、「宜蘭運動公園」。每個句子內的景點為一個 list。
- get_person: 取出斷詞結果中的人名 (person)。每個句子內的人名為一個 list。
- get_person_and_pronoun: 取出斷詞結果中的人名 (person) 與代名詞 (pronoun)。每個句子內的人名與代名詞為一個 list。
- get_question: 取出斷詞結果中含有 <CLAUSE_Q> 標籤的句子。例如「是非問句:你認識他嗎?」
- get_time: 取出斷詞結果中的時間 (time)。每個句子內的時間列為一個 list。
- get_verb_stem: 取出斷詞結果中的動詞 (verb)。此處指的是 ACTION_verb 標記的動詞詞彙。每個句子內的動詞為一個 list。
- get_wikidata: 取出斷詞結果中含有 <KNOWLEDGE_wikiData> 標籤的 Wikidata 標題字串。每個句子內的 Wikidata 標題文字為一個 list。

NER

範例程式 (取得食物名稱):

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/NER/"
payload = 
{
    "result_pos": ["《",
                   "<ENTITY_nouny>小糧倉</ENTITY_nouny>",
                   "》",
                   "<ENTITY_oov>菜單</ENTITY_oov><ACTION_verb>販售</ACTION_verb><ENTITY_nounHead>品項</ENTITY_nounHead><TIME_justtime>十分</TIME_justtime><MODIFIER>多元</MODIFIER>",
                   ",",
                   "<ENTITY_oov>雞</ENTITY_oov><MODIFIER_color>白</MODIFIER_color><ENTITY_nounHead>湯拉麵</ENTITY_nounHead>",
                   "、",
                   "<ENTITY_oov>咖哩飯</ENTITY_oov>",
                   "、",
                   "<ENTITY_oov>鐵板漢堡</ENTITY_oov><ACTION_verb>排定</ACTION_verb><ENTITY_nouny>食</ENTITY_nouny><ACTION_verb>等</ACTION_verb>",
                   "。"],
    "func": ["get_food"]
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Toolkit/NER/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
   if (xhr.readyState === 4) {
      console.log(xhr.status);
      console.log(xhr.responseText);
   }};

var data = `{
    "result_pos": ["《",
                   "<ENTITY_nouny>小糧倉</ENTITY_nouny>",
                   "》",
                   "<ENTITY_oov>菜單</ENTITY_oov><ACTION_verb>販售</ACTION_verb><ENTITY_nounHead>品項</ENTITY_nounHead><TIME_justtime>十分</TIME_justtime><MODIFIER>多元</MODIFIER>",
                   ",",
                   "<ENTITY_oov>雞</ENTITY_oov><MODIFIER_color>白</MODIFIER_color><ENTITY_nounHead>湯拉麵</ENTITY_nounHead>",
                   "、",
                   "<ENTITY_oov>咖哩飯</ENTITY_oov>",
                   "、",
                   "<ENTITY_oov>鐵板漢堡</ENTITY_oov><ACTION_verb>排定</ACTION_verb><ENTITY_nouny>食</ENTITY_nouny><ACTION_verb>等</ACTION_verb>",
                   "。"],
    "func": ["get_food"]
}`;

xhr.send(data);

回傳內容 (JSON 格式):

{
    "msg": "Success!",
    "status": true,
    "results": {"law_article_list": [[],
                                     [],
                                     [],
                                     [],
                                     [],
                                     [[0, 98, "雞白湯拉麵"]],
                                     [],
                                     [[0, 28, "咖哩飯"]],
                                     [],
                                     [[0, 29, "鐵板漢堡"]],
                                     []]}
}

範例程式 (取得時間):

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/NER/"
payload = 
{
    "result_pos": ["<FUNC_inter>其實</FUNC_inter><TIME_day>早</TIME_day><FUNC_inner>在</FUNC_inner><TIME_month>五月</TIME_month><TIME_day>15日</TIME_day><ACTION_verb>開始</ACTION_verb><ACTION_verb>突破</ACTION_verb><ENTITY_classifier>百例</ENTITY_classifier><TIME_justtime>之前</TIME_justtime>",
                   ",",
                   "<ENTITY_DetPhrase>這起</ENTITY_DetPhrase><ENTITY_noun>社區</ENTITY_noun><MODIFIER>大</MODIFIER><ACTION_verb>爆發</ACTION_verb><ENTITY_nouny>疫情</ENTITY_nouny><FUNC_inner>就</FUNC_inner><ASPECT>已經</ASPECT><ACTION_verb>有</ACTION_verb><ENTITY_classifier>一些</ENTITY_classifier><VerbP>端倪</VerbP>",
                   "。",
                   "<TIME_week>上星期</TIME_week><ENTITY_pronoun>我們</ENTITY_pronoun><ACTION_verb>約</ACTION_verb><FUNC_degreeHead>好</FUNC_degreeHead><ASPECT>了</ASPECT>",
                   ",",
                   "<ENTITY_DetPhrase>這件</ENTITY_DetPhrase><ENTITY_nouny>事情</ENTITY_nouny><TIME_day>今天</TIME_day><TIME_day>下午</TIME_day><TIME_justtime>六點</TIME_justtime><AUX>到</AUX><TIME_justtime>八點</TIME_justtime><ACTION_verb>要</ACTION_verb><ACTION_verb>討論</ACTION_verb>",
                   "。"],
    "func": ["get_date",
             "get_time"]
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Toolkit/NER/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
   if (xhr.readyState === 4) {
      console.log(xhr.status);
      console.log(xhr.responseText);
   }};

var data = `{
    "result_pos": ["<FUNC_inter>其實</FUNC_inter><TIME_day>早</TIME_day><FUNC_inner>在</FUNC_inner><TIME_month>五月</TIME_month><TIME_day>15日</TIME_day><ACTION_verb>開始</ACTION_verb><ACTION_verb>突破</ACTION_verb><ENTITY_classifier>百例</ENTITY_classifier><TIME_justtime>之前</TIME_justtime>",
                   ",",
                   "<ENTITY_DetPhrase>這起</ENTITY_DetPhrase><ENTITY_noun>社區</ENTITY_noun><MODIFIER>大</MODIFIER><ACTION_verb>爆發</ACTION_verb><ENTITY_nouny>疫情</ENTITY_nouny><FUNC_inner>就</FUNC_inner><ASPECT>已經</ASPECT><ACTION_verb>有</ACTION_verb><ENTITY_classifier>一些</ENTITY_classifier><VerbP>端倪</VerbP>",
                   "。",
                   "<TIME_week>上星期</TIME_week><ENTITY_pronoun>我們</ENTITY_pronoun><ACTION_verb>約</ACTION_verb><FUNC_degreeHead>好</FUNC_degreeHead><ASPECT>了</ASPECT>",
                   ",",
                   "<ENTITY_DetPhrase>這件</ENTITY_DetPhrase><ENTITY_nouny>事情</ENTITY_nouny><TIME_day>今天</TIME_day><TIME_day>下午</TIME_day><TIME_justtime>六點</TIME_justtime><AUX>到</AUX><TIME_justtime>八點</TIME_justtime><ACTION_verb>要</ACTION_verb><ACTION_verb>討論</ACTION_verb>",
                   "。"],
    "func": ["get_date",
             "get_time"]
}`;

xhr.send(data);

回傳內容 (JSON 格式):

{
    "msg": "Success!",
    "status": true,
    "results": {"date_list": [[[75, 126, "五月15日"]], [], [], [], [], [], [], []],
                "time_list": [[[27, 49, "早"], [75, 102, "五月"], [102, 126, "15日"], [225, 258, "之前"]],
                               [],
                               [],
                               [],
                               [[0, 26, "上星期"]],
                               [],
                               [[70, 93, "今天"], [93, 116, "下午"], [116, 149, "六點"], [161, 194, "八點"]],
                               []]
    }
}

命名實體標記 (Named Entity Recognition, NER) 是許多 NLP 高階應用中會使用到的標記。Articut 原生支援數十種命名實體的辨識。為了方便理解與利用,以下列出其標記以及說明。
微軟亞洲研究院 (Microsoft Research Lab Asia, MSRA) 提出有 26 種命名實體標記 (Named Entity Recognition, NER) 和 Articut 對照表,請參考 Articut API

HTTP Request

POST http://ARTICUT_URL/Articut/Toolkit/NER/

參數說明

參數 型態 預設 功能
result_pos dict Articut 斷詞結果標記。
index_with_pos bool True 計算所擷取的字串位置時,是否包含詞性標記 (POS)。
func list ["get_all"] 可設置為以下參數:
- get_addtw: 在 KNOWLEDGE_addTW 裡的即為台灣地址字串。
- get_age: 一個 num 再加一個 ENTITY 歲。
- get_area: 一個 ENTITY 後有 RANGE_locality 表示前面的 ENTITY 空間的上下左右內外附近。
- get_date: 一個 month 再加一個 day。
- get_decimal: 內含小數點的 num。
- get_duration: 可能為 justtime/day/week/month/season/year/decade,視時間長度而定。
- get_emoji: 取得文本中的 emoji 符號。
- get_food: 取得文本中的食物名稱。
- get_food_with_location: 取得文本中的食物名稱連食物前的地方特色詞一起取得。
- get_integer: 在 num 裡,可兼容小數點、計位點和中文/阿拉伯數字夾雜及空格。
- get_location: 在 LOCATION 裡的即為地點。
- get_money: 在 currency 裡的都是金額。
- get_money_greedy: 都是金額取出斷詞結果中含有 <KNOWLEDGE_currency> 標籤與 <ENTITY_noun> <ENTITY_num> 組合標籤的貨幣金額字串。每個句子內的貨幣金額為一個 list。
- get_ordinal: 在 DetPhrase 中有「第」。
- get_person: 在 person 裡的即為人名。
- get_person_and_pronoun: 取得 person 人名與 pronoun 中的代名詞。
- get_time: 在 TIME_ 的分類下有超過年的時間/年/季/月/週/日/短於一日的時間/假日。
- get_angle: 在 measurement 裡有「度」。
- get_capactity: 在 measurement 裡有「公升」或其它容量單位。
- get_fraction: 在 measurement 裡有「分之」。
- get_frequency: 在 measurement 裡有「赫茲」這類頻率單位。
- get_measure: 在 measurement 裡的都是測量值。
- get_length: 在 measurement 裡有「公分」這類長度單位。
- get_percent: 在 measurement 中有「百分之」。
- get_rate: 在 measurement 中有「倍」。
- get_speed: 在 measurement 中有速度單位,或是 measurement 後跟著時間。
- get_temperature: 在 measurement 中有溫度單位。
- get_weight: 在 measurement 中有重量單位。
- get_www: 在 KNOWLEDGE_url 中的即為網址。

法律檢索工具

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/Laws/"
payload = 
{
    "result_pos": ["<ENTITY_nouny>被告</ENTITY_nouny><MODIFIER>前</MODIFIER><FUNC_inter>因</FUNC_inter><MODIFIER>非法</MODIFIER><ACTION_verb>持有</ACTION_verb><ENTITY_nouny>槍械</ENTITY_nouny>",
                   ",",
                   "<CLAUSE_particle>業</CLAUSE_particle><ACTION_verb>經</ACTION_verb><ENTITY_nouny>前案</ENTITY_nouny><ACTION_verb>判決</ACTION_verb><MODIFIER>非法</MODIFIER><ACTION_verb>持有</ACTION_verb><MODAL>可</MODAL><ACTION_verb>發射</ACTION_verb><ENTITY_nouny>子彈</ENTITY_nouny><ENTITY_nouny>具</ENTITY_nouny><ENTITY_nouny>殺傷力</ENTITY_nouny><FUNC_inner>之</FUNC_inner><ENTITY_nouny>槍枝</ENTITY_nouny><ENTITY_nouny>罪</ENTITY_nouny>",
                   ",",
                   "<ACTION_verb>處</ACTION_verb><MODIFIER>有期</MODIFIER><ENTITY_nounHead>徒刑</ENTITY_nounHead><TIME_year>參年</TIME_year><TIME_month>陸月</TIME_month>",
                   ",",
                   "<ACTION_verb>併</ACTION_verb><ENTITY_nounHead>科罰金</ENTITY_nounHead><ENTITY_noun>新臺幣</ENTITY_noun><KNOWLEDGE_currency>拾萬元</KNOWLEDGE_currency>",
                   "。",
                   "<FUNC_inner>於</FUNC_inner><ENTITY_nouny>前案</ENTITY_nouny><ACTION_verb>偵查</ACTION_verb><ENTITY_noun>過程</ENTITY_noun><RANGE_locality>中</RANGE_locality>",
                   ",",
                   "<ENTITY_nouny>南投縣</ENTITY_nouny><ENTITY_noun>政府</ENTITY_noun><ENTITY_nouny>警察局</ENTITY_nouny><LOCATION>集集</LOCATION><ENTITY_oov>分局</ENTITY_oov><FUNC_inner>之</FUNC_inner><ENTITY_nouny>員警</ENTITY_nouny>",
                   ",",
                   "<ACTION_verb>持</ACTION_verb><ENTITY_nouny>本院</ENTITY_nouny><ACTION_verb>核發</ACTION_verb><FUNC_inner>之</FUNC_inner><TIME_year>105年度</TIME_year><ENTITY_oov>聲</ENTITY_oov><VerbP>搜字</VerbP><KNOWLEDGE_lawTW>第165號</KNOWLEDGE_lawTW><ACTION_verb>搜索</ACTION_verb><ENTITY_nouny>票</ENTITY_nouny><ACTION_verb>搜索</ACTION_verb>",
                   "。"],
    "func": ["get_all"]
}
var url = "http://ARTICUT_URL/Articut/Toolkit/Laws/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "result_pos": ["<ENTITY_nouny>被告</ENTITY_nouny><MODIFIER>前</MODIFIER><FUNC_inter>因</FUNC_inter><MODIFIER>非法</MODIFIER><ACTION_verb>持有</ACTION_verb><ENTITY_nouny>槍械</ENTITY_nouny>",
                   ",",
                   "<CLAUSE_particle>業</CLAUSE_particle><ACTION_verb>經</ACTION_verb><ENTITY_nouny>前案</ENTITY_nouny><ACTION_verb>判決</ACTION_verb><MODIFIER>非法</MODIFIER><ACTION_verb>持有</ACTION_verb><MODAL>可</MODAL><ACTION_verb>發射</ACTION_verb><ENTITY_nouny>子彈</ENTITY_nouny><ENTITY_nouny>具</ENTITY_nouny><ENTITY_nouny>殺傷力</ENTITY_nouny><FUNC_inner>之</FUNC_inner><ENTITY_nouny>槍枝</ENTITY_nouny><ENTITY_nouny>罪</ENTITY_nouny>",
                   ",",
                   "<ACTION_verb>處</ACTION_verb><MODIFIER>有期</MODIFIER><ENTITY_nounHead>徒刑</ENTITY_nounHead><TIME_year>參年</TIME_year><TIME_month>陸月</TIME_month>",
                   ",",
                   "<ACTION_verb>併</ACTION_verb><ENTITY_nounHead>科罰金</ENTITY_nounHead><ENTITY_noun>新臺幣</ENTITY_noun><KNOWLEDGE_currency>拾萬元</KNOWLEDGE_currency>",
                   "。",
                   "<FUNC_inner>於</FUNC_inner><ENTITY_nouny>前案</ENTITY_nouny><ACTION_verb>偵查</ACTION_verb><ENTITY_noun>過程</ENTITY_noun><RANGE_locality>中</RANGE_locality>",
                   ",",
                   "<ENTITY_nouny>南投縣</ENTITY_nouny><ENTITY_noun>政府</ENTITY_noun><ENTITY_nouny>警察局</ENTITY_nouny><LOCATION>集集</LOCATION><ENTITY_oov>分局</ENTITY_oov><FUNC_inner>之</FUNC_inner><ENTITY_nouny>員警</ENTITY_nouny>",
                   ",",
                   "<ACTION_verb>持</ACTION_verb><ENTITY_nouny>本院</ENTITY_nouny><ACTION_verb>核發</ACTION_verb><FUNC_inner>之</FUNC_inner><TIME_year>105年度</TIME_year><ENTITY_oov>聲</ENTITY_oov><VerbP>搜字</VerbP><KNOWLEDGE_lawTW>第165號</KNOWLEDGE_lawTW><ACTION_verb>搜索</ACTION_verb><ENTITY_nouny>票</ENTITY_nouny><ACTION_verb>搜索</ACTION_verb>",
                   "。"],
    "func": ["get_all"]
}`;

xhr.send(data);

回傳內容 (JSON 格式):

{
    "msg": "Success!",
    "status": true,
    "results": {"law_article_list": ["第165號"],
                "crime_list": ["非法持有可發射子彈具殺傷力之槍枝罪"],
                "criminal_responsibility_list": ["有期徒刑參年陸月"],
                "event_ref_list": []}
}

HTTP Request

POST http://ARTICUT_URL/Articut/Toolkit/Laws/

參數說明

參數 型態 預設 功能
result_pos dict Articut 斷詞結果標記。
func list ["get_all"] 可設置為以下參數:
- get_all: 取出以下所有參數的結果。
- get_law_article: 取出斷詞結果中含有 <KNOWLEDGE_lawTW> 標籤的法條索引。
- get_crime: 取出斷詞結果中的犯罪罪名。
- get_criminal_responsibility: 取出斷詞結果中的判決刑責。
- get_event_ref: 取出斷詞結果中的事件參照。

LocalRE

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/LocalRE/"
payload = 
{
    "result_pos": ["<MODIFIER>滿</MODIFIER><MODIFIER>堂紅</MODIFIER><ENTITY_nouny>麻辣鍋</ENTITY_nouny>",
                   "!",
                   "<ENTITY_oov>地址</ENTITY_oov>",
                   ":",
                   "<KNOWLEDGE_addTW>台中市西區台灣大道二段459號14樓</KNOWLEDGE_addTW>"],
    "func": ["get_city",
             "get_road"]
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Toolkit/LocalRE/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
   if (xhr.readyState === 4) {
      console.log(xhr.status);
      console.log(xhr.responseText);
   }};

var data = `{
    "result_pos": ["<MODIFIER>滿</MODIFIER><MODIFIER>堂紅</MODIFIER><ENTITY_nouny>麻辣鍋</ENTITY_nouny>",
                   "!",
                   "<ENTITY_oov>地址</ENTITY_oov>",
                   ":",
                   "<KNOWLEDGE_addTW>台中市西區台灣大道二段459號14樓</KNOWLEDGE_addTW>"],
    "func": ["get_city",
             "get_road"]
}`;

xhr.send(data);

回傳內容 (JSON 格式):

{
    "msg": "Success!",
    "status": true,
    "results": {"city_list": [[], [], [], [], [[17, 20, "台中市"]]],
                "road_list": [[], [], [], [], [[22, 26, "台灣大道"]]]}
}

台灣 中文地址 資訊擷取工具

HTTP Request

POST http://ARTICUT_URL/Articut/Toolkit/LocalRE/

參數說明

參數 型態 預設 功能
result_pos dict Articut 斷詞結果標記。
index_with_pos bool True 計算所擷取的字串位置時,是否包含詞性標記 (POS)。
func list ["get_all"] 可設置為以下參數:
- get_all: 取出以下所有參數的結果。
- get_county: 取出是哪個「縣」。
- get_city: 取出是哪個「市」。
- get_district: 取出是哪個「區」。
- get_township: 取出是哪個「鄉」或「里」。
- get_town: 取出是哪個「鎮」。
- get_village: 取出是哪個「村」。
- get_neighborhood: 取出是哪個「鄰」。
- get_road: 取出是哪條「路」。
- get_section: 取出是哪一「段」。
- get_alley: 取出是哪一「巷弄」。
- get_number: 取出是幾「號」。
- get_floor: 取出是幾「樓」。
- get_room: 取出「室」的編號。

TF-IDF

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/TFIDF/"
payload = {
    "result_segmentation": "沒有/人/可以/決定/你/的/命運/,/命運/在/自己/的/手/上/。",
    "with_weight": True
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Toolkit/TFIDF/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "result_segmentation": "沒有/人/可以/決定/你/的/命運/,/命運/在/自己/的/手/上/。",
    "with_weight": true
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "status": true,
    "msg": "Success!",
    "tfidf": [["命運", 0.27356173082825286],
              ["你", 0.13678086541412643],
              ["手", 0.11362471190151249],
              ["決定", 0.10007923043569088],
              ["自己", 0.06731240487628462],
              ["人", 0.05667373578657066]],
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

基於 TF-IDF 算法的關鍵詞抽取

HTTP Request

POST http://ARTICUT_URL/Articut/Toolkit/TFIDF/

參數說明

參數 型態 預設 功能
result_segmentation str Articut 斷詞結果,提取關鍵詞的文本。
top_k int 50 提取幾個 TF-IDF 的關鍵詞。
with_weight bool False 為是否返回關鍵詞權重值。
allow_pos list 預設為空值,亦即全部抽取。抽取指定詞性。

TextRank

範例程式:

from requests import post

url = "http://ARTICUT_URL/Articut/Toolkit/TextRank/"
payload = {
    "result_pos": ["<FUNC_negation>沒有</FUNC_negation><ENTITY_nouny>人</ENTITY_nouny><MODAL>可以</MODAL><ACTION_verb>決定</ACTION_verb><ENTITY_pronoun>你</ENTITY_pronoun><FUNC_inner>的</FUNC_inner><ENTITY_nouny>命運</ENTITY_nouny>",
                   ",",
                   "<ENTITY_oov>命運</ENTITY_oov><FUNC_inner>在</FUNC_inner><ENTITY_pronoun>自己</ENTITY_pronoun><FUNC_inner>的</FUNC_inner><ENTITY_nouny>手</ENTITY_nouny><RANGE_locality>上</RANGE_locality>",
                   "。"],
    "with_weight": True
}

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Articut/Toolkit/TextRank/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "result_pos": ["<FUNC_negation>沒有</FUNC_negation><ENTITY_nouny>人</ENTITY_nouny><MODAL>可以</MODAL><ACTION_verb>決定</ACTION_verb><ENTITY_pronoun>你</ENTITY_pronoun><FUNC_inner>的</FUNC_inner><ENTITY_nouny>命運</ENTITY_nouny>",
                   ",",
                   "<ENTITY_oov>命運</ENTITY_oov><FUNC_inner>在</FUNC_inner><ENTITY_pronoun>自己</ENTITY_pronoun><FUNC_inner>的</FUNC_inner><ENTITY_nouny>手</ENTITY_nouny><RANGE_locality>上</RANGE_locality>",
                   "。"],
    "with_weight": true
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "status": true,
    "msg": "Success!",
    "textrank": [["命運", 5.591625666787958],
                 ["自己", 3.4637188376903927],
                 ["你", 3.4637188376903927],
                 ["決定", 3.4637188376903927],
                 ["手", 2.959546855830475],
                 ["人", 2.9595468558304745]],
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

基於 TextRank 算法的關鍵詞抽取

將待抽取關鍵詞的文本斷詞。
以固定的窗格大小 (預設值為 5,通過 span 屬性調整),詞之間的共現關係,建構出不帶權圖。
計算途中節點的 PageRank。
算法論文:TextRank: Bringing Order into Texts

HTTP Request

POST http://ARTICUT_URL/Articut/Toolkit/TextRank/

參數說明

參數 型態 預設 功能
result_pos list Articut 斷詞結果標記,提取關鍵詞的文本。
top_k int 10 提取幾個關鍵詞。
with_weight bool False 為是否返回關鍵詞權重值。
allow_pos list 預設為空值,亦即全部抽取。抽取指定詞性。

LokiServer

Loki 服務介紹

Loki 全文是 Linguistic Oriented Keyword Interface (語言導向的關鍵詞介面),是新一代的自然語言理解 (Natural Language Understanding, NLU) 引擎。

基於句法分析的方式,自動產生 Python 的 Regular Expression (正則表示式) 的條件式 (if...else...) 區塊程式碼。

Loki 相較於微軟的 LUIS 或 Google DiaglogFlow 等利用機器學習或統計機率的傳統方案,在訓練資料量的需求上,能省下極大的功夫。

參考連結:
Loki 的釋出說明影片
Loki 自然語言理解引擎 佈署優勢
用 Loki 解中文的數學應用問題

Loki 背景說明

Loki 目錄

├── 您的 Project1
│   ├── 意圖_intent1.atm
│   └── 意圖_intent2.atm
└── 您的 Project 2
│ ├── 意圖_intent3.atm
│ └── 意圖_intentN.atm
└──您的 Project N

LokiServer 隨 Articut Docker (Pro) 啟動後,將讀取 Loki 目錄中的所有 <*.atm> 模型,亦可使用 LokiTool 部屬模型。

使用 Loki API

範例程式:

from requests import post

url = "http://ARTICUT_URL/Loki/API/"
payload = {
    "input_str": "100美金能換多少台幣",
    "project": "FinExchange"
} 

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Loki/API/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_str": "100美金能換多少台幣",
    "project": "FinExchange"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 0.3015732765197754,
    "results": [{"intent": "Exchange",
                 "pattern": "<KNOWLEDGE_currency>[^<]*?</KNOWLEDGE_currency>(<MODAL>[^<]*?</MODAL>)?((<ACTION_verb>[^<不]*?[換][^<不]*?</ACTION_verb>)|(<VerbP>[^<不]*?[換][^<不]*?</VerbP>))<CLAUSE_HowQ>[^<]*?</CLAUSE_HowQ><ENTITY_UserDefined>[^<]*?</ENTITY_UserDefined>",
                 "utterance": "[100美金]能換多少[台幣]",
                 "argument": ["100美金", "台幣"]}],
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

POST http://ARTICUT_URL/Loki/API/

參數說明

參數 型態 預設 功能
input_str str "" 將要送上 Loki 分析意圖的文字。
project str "" 指定專案的名稱,Loki 會分析專案內所有意圖。
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
filter_list list [] 預設為空列表,亦即檢查所有意圖。檢查指定的意圖。
keyword_list list [] 分類或分群模型使用的關鍵字列表。
feature_list list [] 分類或分群模型使用的分析參數。
可設置以下參數:feature_time feature_unit feature_noun feature_verb feature_userdefined feature_location feature_person feature_modifier feature_color feature_idiom feature_chmical
count int 1 取得分類或分群模型的結果數量,範圍為 1 ~ 5。

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 順利完成意圖偵測。
- Authentication Failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- count Parsing ERROR. (Please check your the format and encoding.): count 格式錯誤,請檢查格式 (Int) 是否正確。
- featureLIST Parsing ERROR. (Please check your the format and encoding.): feature 無法載入,請檢查格式 (List) 或編碼 (UTF-8) 是否正確。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- Invalid Project.: 無效的專案。請再檢查一次您的專案名稱是否正確,並確保專案內所有模型都已生成。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
- keywordLIST Parsing ERROR. (Please check your the format and encoding.): keyword 無法載入,請檢查格式 (List) 或編碼 (UTF-8) 是否正確。。
- Loki PROJECT is running ...: 分類或分群模型正在預測結果中,請稍候再呼叫 API 取得結果。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
- No Match Intent!: 專案內未檢查到符合的意圖。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
version str 本次斷詞作業所使用的演算法版本。
results list 本次 Loki 意圖分析結果。

使用 Loki Bulk API

範例程式:

from requests import post

url = "http://ARTICUT_URL/Loki/BulkAPI/"
payload = {
    "input_list": [
        "100美金能換多少台幣",
        "台幣3000元能換多少美金"
    ],
    "project": "FinExchange"
} 

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Loki/BulkAPI/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "input_list": [
        "100美金能換多少台幣",
        "台幣3000元能換多少美金"
    ],
    "project": "FinExchange"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 0.3072061538696289,
    "result_list": [
        {"status": true,
         "msg": "Success!",
         "results": [{"intent": "Exchange",
                      "pattern": "<KNOWLEDGE_currency>[^<]*?</KNOWLEDGE_currency>(<MODAL>[^<]*?</MODAL>)?((<ACTION_verb>[^<不]*?[換][^<不]*?</ACTION_verb>)|(<VerbP>[^<不]*?[換][^<不]*?</VerbP>))<CLAUSE_HowQ>[^<]*?</CLAUSE_HowQ><ENTITY_UserDefined>[^<]*?</ENTITY_UserDefined>",
                      "utterance": "[100美金]能換多少[台幣]",
                      "argument": ["100美金", "台幣"]}]},
        {"status": true,
         "msg": "Success!",
         "results": [{"intent": "Exchange",
                      "pattern": "<ENTITY_UserDefined>[^<]*?</ENTITY_UserDefined><KNOWLEDGE_currency>[^<]*?</KNOWLEDGE_currency>(<MODAL>[^<]*?</MODAL>)?((<ACTION_verb>[^<不]*?[兌換][^<不]*?</ACTION_verb>)|(<VerbP>[^<不]*?[兌換][^<不]*?</VerbP>))<CLAUSE_HowQ>[^<]*?</CLAUSE_HowQ><ENTITY_UserDefined>[^<]*?</ENTITY_UserDefined>",
                      "utterance": "[美金][100元]可以兌換多少[台幣]",
                      "argument": ["台幣", "3000元", "美金"]}]}
    ],
    "version": "v220",
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

POST http://ARTICUT_URL/Loki/BulkAPI/

參數說明

參數 型態 預設 功能
input_list list "" 將要送上 Articut 進行斷詞暨詞性標記處理的文字。
注意!每次最多總字符不得超過 100000 個。
project str "" 指定專案的名稱,Loki 會分析專案內所有意圖。
user_defined_dict_file dict {} 使用者自定詞典,必須是 dictionary 格式。
(e.g. UserDefinedDICT = {"key": ["value1", "value2",...],...})。
filter_list list [] 預設為空列表,亦即檢查所有意圖。檢查指定的意圖。

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 順利完成意圖偵測。
- No Match Intent!: 專案內未檢查到符合的意圖。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Invalid arguments.: 上傳參數錯誤,請重新檢查上傳時的參數是否符合規則名稱。
- Authentication Failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Invalid Project.: 無效的專案。請再檢查一次您的專案名稱是否正確,並確保專案內所有模型都已生成。
- UserDefinedDICT Parsing ERROR. (Please check your the format and encoding.): 使用者自定詞典無法載入,請檢查格式 (Dict) 或編碼 (UTF-8) 是否正確。
- Maximum UserDefinedDICT file size exceeded! (UserDefinedDICT file shall be samller than 10MB.): 使用者自定詞典檔案大小超過 10MB。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
version str 本次斷詞作業所使用的演算法版本。
result_list list 本次 Loki 意圖分析結果。

使用 Loki Utterance

範例程式:

from requests import post

url = "http://ARTICUT_URL/Loki/Utterance/"
payload = {
    "project": "FinExchange"
} 

response = post(url, json=payload)
var url = "http://ARTICUT_URL/Loki/Utterance/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "project": "FinExchange"
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "exec_time": 0.1515732765197754,
    "results": {"Exchange": [
        "我想買100元美金",
        "100元美金要多少台幣",
        "美金100元可以換多少台幣",
        "美金100元是多少台幣",
        "100元美金要台幣多少",
        "100元美金可換台幣多少"
    ]},
    "status": true,
    "msg": "Success!",
    "info": "Articut Docker Pro only for Droidtown. Powered by Droidtown Linguist Tech."
}

HTTP Request

POST http://ARTICUT_URL/Loki/Utterance/

參數說明

參數 型態 預設 功能
project str "" 指定專案的名稱,Loki 會取得專案內所有意圖的句子。

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 順利完成意圖偵測。
- Utterance not found.: 專案不存在或專案內的意圖未存在任何句子。
- Invalid content_type.: 上傳格式必須為 Json 格式 (application/json)。
- Authentication Failed.: 您的認證似乎有錯,請聯絡卓騰解決。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
results list 本次取得 Loki 意圖句子的結果。

LokiTool

LokiTool 為一獨立的 Loki GUI Django 網站。可搭配 WSGI / ASGI 架設伺服器或複製至「可以連線至 Articut Docker (Pro)」的機器中啟動。

LokiTool 啟動方法

安裝 LokiTool 所需套件

$ pip3 install -r requirements.txt

在 LokiTool 目錄中,請先確保本機存在 Python3.6+ 環境,並依照 requirements.txt 將套件至少升級至指定的版本,或直接安裝指定版本。

範例架構:

ArticutDocker Server A: http://articut.server_a.com
ArticutDocker Server B: http://articut.server_b.com
ArticutDocker Server C: http://articut.server_c.com

LoadBalancer: http://articut.server.com

請將 ARTICUT_URL 與 DEPLOY_URL_LIST 填入以下內容
ARTICUT_URL = "http://articut.server.com"
DEPLOY_URL_LIST = ["http://articut.server_a.com",
                   "http://articut.server_b.com",
                   "http://articut.server_c.com"]

設定 ARTICUT_URL

確保環境準備完畢後,先找到 myproject/settings.py 中的 ARTICUT_URL 變數,將其值更改為您的 Articut Docker (Pro) 的位置。

若有購買多組 Articut Dokcer (Pro),且使用 Load Balancer 連結 Articut Dokcer (Pro) (如下圖),請設定 myproject/settings.py 中的 DEPLOY_URL_LIST 變數,系統將根據 DEPLOY_URL_LIST 佈署至所有 Articut Dokcer (Pro)

設定資料庫連線資訊

資料庫連線資訊

{
    "//engine": "sqlite / mysql / postgresql",
    "engine": "sqlite",
    "host": "",
    "port": "",
    "database": "",
    "username": "",
    "password": ""
}

執行資料遷移

$ python3 manage.py migrate --fake

如果要改用 MySQLPostgreSQL 資料庫,請打開 myproject/database.json 修改 engine 欄位爲要使用的資料庫 (mysql / postgresql),並填入資料庫的連線資訊,修改完畢後請執行一次 資料遷移

啟動 LokiTool

啟動 LokiTool

$ python3 manage.py runserver

接著利用 manage.py runserver 啟動本機的 LokiTool 就能開始建立 NLU 專案,以及編寫各個意圖的內容了。

LokiTool 快速上手指南

打開 LokiTool

在瀏覽器網址列輸入 http://localhost:8000/loki/ 開始使用LokiTool

LokiTool

建立專案

輸入專案名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊[建立專案]

專案名稱

使用外部近義詞 API

近義詞 API Request (json)

{
    "input_list": ["input1", "input2"]
}

近義詞 API Response (json)

{
    "status": true,
    "result": {
        "key": ["val1", "val2"]
    }
}

如果您希望專接上自定義的近似詞 API (請符合右側的格式),請輸入外部近義詞 API 的網址後儲存,並在重新分析所有意圖的句子。

近義詞API

建立基本意圖

  1. 進入[專案]後點擊[建立基本意圖]

    建立意圖

  2. 輸入意圖名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊[建立意圖]

    意圖名稱

  3. 若有自定義詞彙,可以自行新增;若無,則進入下一步。

    自定義詞彙

  4. 輸入意圖文句後點擊[單句分析],建議一次一句,若有標點符號,系統會自動忽略。可大量輸入完再點擊[全句分析]

    文本分析

  5. 勾選意圖所需[參數] (通常是會變動的值或詞彙,電腦需要計算的實體)。

    Loki 提供兩種方法勾選意圖參數:

    Graph 勾選[參數]
    Graph意圖參數

    直接勾選[參數]
    意圖參數

    PS. 若需要大量勾選相同參數名稱,請點選頁面右側 < 開啟參數勾選工具
    意圖參數工具-2

  6. 輸入版本號,點擊[佈署模型]

    佈署模型

  7. 輸入文句點擊[意圖分析],測試意圖文句,確認是否有偵測到第 4 步所勾選的意圖參數

    測試意圖

  8. 重複 4 至 6 步驟,直到全部訓練的文句皆可偵測其意圖

建立進階意圖

  1. 進入[專案]後點擊[建立進階意圖]

    建立意圖

  2. 輸入意圖名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊[建立意圖]

    意圖名稱

  3. 若有自定義詞彙,可以自行新增;若無,則進入下一步。

    自定義詞彙

  4. 輸入意圖文句後點擊 [分析] ,系統會賦予預設的正規表達式 (Regex),根據需求自行調整,最後點擊 [檢驗] 驗證正規表達式 (Regex) 是否適用於意圖文句。

    文本分析

  5. 輸入版本號,點擊[佈署模型]

    佈署模型

  6. 輸入文句點擊[意圖分析],測試意圖文句,確認是否有偵測到意圖

    測試意圖

  7. 重複 4 至 5 步驟,直到全部訓練的文句皆可偵測其意圖

Loki 互動說明

簡單示意 Loki 如何使用相似結構 (Structural Pattern) 比對出最適合的 Utterance。

互動說明

讀取 ATM 模型

打開 LokiTool

在瀏覽器網址列輸入 http://localhost:8000/loki/ 開始使用LokiTool

LokiTool

建立專案

輸入專案名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊[建立專案]

專案名稱

讀取模型

  1. 讀取 ArticutModel

    在專案下方選擇 ArticutModel 並依序點擊 [瀏覽] > 選擇 ref 檔 (最多 10 個) > [讀取意圖]。

    讀取意圖

  2. 讀取 TXT 純文字

    在專案下方選擇 Txt 並依序點擊 [瀏覽] > 選擇 txt 檔 (最多 10 個) > [讀取意圖]。

    建立意圖

  3. 讀取 LUIS 模型

    在專案下方選擇 LUIS 並依序點擊 [瀏覽] > 選擇 json 檔 (最多 10 個) > [讀取意圖]。

    建立意圖

  4. 讀取 DialogFlow 模型

    在專案下方選擇 DialogFlow 並依序點擊 [瀏覽] > 選擇 json 檔 (最多 10 個) > [讀取意圖]。

    建立意圖

分析並生成模型

後續請從 快速上手指南步驟 4 繼續完成。

使用 Loki 範本

Loki 目前提供 Python 和 Java (Android) 兩種程式範本,未來會支援更多的程式語言。

編譯專案意圖的計算邏輯

Loki 範本目錄結構

Project.py
intent/Loki_Intent.py
intent/Loki_xxxxx.py
  1. 回到 Loki 首頁,點擊[專案範本]的程式語言 (如:Python) 開始下載。

    專案範本

    解壓縮 .zip 檔案。檔案目錄結構如下:

  2. Project.py檔案,修改LOKI_URL(預設已填上 ARTICUT_URL)。

    Loki 參數

  3. intent/Loki_Intent.py檔案,開始編譯意圖語意的計算方法。

    意圖範本

  4. 導入專案開始使用Loki

設定大型語言模型 (LLM)

預設的 llm.json

{
    "[LiteLLM] OpenAI ChatGPT": {
        "type": "litellm",
        "model": "gpt-4o",
        "env": {
            "OPENAI_API_KEY": "${API_KEY}"
        }
    },
    "[LiteLLM] Azure ChatGPT": {
        "type": "litellm",
        "model": "azure/${DEPLOYMENT_NAME}",
        "env": {
            "AZURE_API_KEY": "${API_KEY}",
            "AZURE_API_BASE": "${ENDPOINT}",
            "AZURE_API_VERSION": "2023-05-15"
        }
    },
    "[LiteLLM] Google Gemini": {
        "type": "litellm",
        "model": "gemini/gemini-pro",
        "env": {
            "GEMINI_API_KEY": "${API_KEY}"
        }
    },
    "[LiteLLM] Anthropic Claude": {
        "type": "litellm",
        "model": "claude-opus-4-20250514",
        "env": {
            "ANTHROPIC_API_KEY": "${API_KEY}"
        }
    },
    "[LiteLLM] AWS Sagemaker": {
        "type": "litellm",
        "model": "sagemaker/${ENDPOINT_NAME}",
        "env": {
            "AWS_ACCESS_KEY_ID": "",
            "AWS_SECRET_ACCESS_KEY": "",
            "AWS_REGION_NAME": ""
        }
    },
    "[LiteLLM] Ollama": {
        "type": "litellm",
        "url": "http://localhost:11434",
        "model": "ollama/llama2"
    },
    "[API] Google Gemini": {
        "type": "api",
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${API_KEY}",
        "header": {
            "Content-Type": "application/json"
        },
        "payload": {
            "contents": [{
                "parts": [{
                    "text": "{{MESSAGES}}"
                }]
            }],
        }
    },
    "[API] Anthropic Claude": {
        "type": "api",
        "url": "https://api.anthropic.com/v1/messages",
        "header": {
            "x-api-key": "${API_KEY}",
            "anthropic-version": "2023-06-01",
            "content-type": "application/json"
        },
        "payload": {
            "model": "claude-3-7-sonnet-20250219",
            "max_tokens": 1024,
            "messages": "{{MESSAGES}}"
        }
    }
}

設定 LLM

設定或自訂 LLM,請先打開 llm.json,如果沒有該檔案,請先執行一次 LokiTool,系統將會產生出預設的 llm.json

系統支援 LiteLLM 及 REST API 兩種方法連接 LLM,請務必將 ${VAR} 替換成相對應的內容,否則無法載入該模型。

  1. LiteLLM

    支援市面上常見的模型,請參考 LiteLLM 文件 設定模型 (model) 及相對應的環境變數 (env)。

  2. REST API

    API 可連線至客製化的 LLM 伺服器,但可能因 request 及 response 的格式不同而無法使用,內容格式必須包含 (url, header, payload)url 為字串,headerpayload 為字典格式,而 payload 中必須存在字串 {{MESSAGES}}

在系統執行 preview_runrun_alias 時,會讀取選定的 LLM 設定,並將 payload 中的字串 {{MESSAGES}} 替換為參數 data.messages

使用 Call API

範例程式 1:

from requests import post

url = "http://LokiTool_URL/loki/call/"
payload = {
    "project": "ProjectName",
    "intent": "IntentName",
    "func": "insert_utterance",
    "data": {
        "utterance": ["今天天氣如何"],
        "checked_list": ["ENTITY_noun"]
    }
}

response = post(url, json=payload)
var url = "http://LokiTool_URL/loki/call/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "project": "ProjectName",
    "intent": "IntentName",
    "func": "insert_utterance",
    "data": {
        "utterance": ["今天天氣如何"],
        "checked_list": ["ENTITY_noun"]
    }
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "status": true,
    "msg": "Success!",
    "result_list": [{"status": true, "msg": "Success!"}]
}

範例程式 2:

from requests import post

url = "http://LokiTool_URL/loki/call/"
payload = {
    "project": "ProjectName",
    "intent": "IntentName",
    "func": "insert_assistant",
    "data": {"assistant": [
        {"title": "大雨", "content": {"DEFINE": "24 小時累積雨量達 80 毫米以上,或時雨量達 40 毫米以上之降雨現象。"}},
        {"title": "豪雨", "content": {"DEFINE": "24 小時累積雨量達 200 毫米以上,或 3 小時累積雨量達 100 毫米以上之降雨現象。"}},
        {"title": "大豪雨", "content": {"DEFINE": "24 小時累積雨量達 350 毫米以上,或 3 小時累積雨量達 200 毫米以上之降雨現象。"}},
        {"title": "超大豪雨", "content": {"DEFINE": "24 小時累積雨量達 500 毫米以上之降雨現象。"}}
    ]}
}

response = post(url, json=payload)
var url = "http://LokiTool_URL/loki/call/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "project": "ProjectName",
    "intent": "IntentName",
    "func": "insert_assistant",
    "data": {"assistant": [
        {"title": "大雨", "content": {"DEFINE": "24 小時累積雨量達 80 毫米以上,或時雨量達 40 毫米以上之降雨現象。"}},
        {"title": "豪雨", "content": {"DEFINE": "24 小時累積雨量達 200 毫米以上,或 3 小時累積雨量達 100 毫米以上之降雨現象。"}},
        {"title": "大豪雨", "content": {"DEFINE": "24 小時累積雨量達 350 毫米以上,或 3 小時累積雨量達 200 毫米以上之降雨現象。"}},
        {"title": "超大豪雨", "content": {"DEFINE": "24 小時累積雨量達 500 毫米以上之降雨現象。"}}
    ]}
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "status": true,
    "msg": "Success!"
}

使用 Loki Call 來完成 Loki 各種任務。

HTTP Request

POST http://LokiTool_URL/loki/call/

參數說明

參數 型態 預設 功能
project str "" 專案名稱,如果不存在會自動建立專案。
intent str "" 意圖名稱,如果不存在會自動建立意圖。
func str "" 可設置為以下參數:
- check_model: 取得分類或分群模型的部屬狀態。
- create_project: 建立新專案。
- create_intent: 建立新意圖。
- deploy_model: 部屬分類或分群模型。
- get_info: 取得專案資訊。
- get_source: 取得分群模型中 source 的原文出處。
- get_utterance: 取得意圖內的所有句子。
- insert_assistant: 新增大量的 ChatGPT Assistant 內容。
- insert_document: 新增大量的分類或分群文件。注意!標題與內容相同不會新增。
- insert_utterance: 新增大量的意圖句子。注意!相同結構的句子不會新增。
- match_utterance: 比對句子在意圖中是否有相同結構。
- preview_alias: 預覽套用別名的內容。
- reset_alias: 清空 Prompt 別名。
- reset_userdefined: 清空自定義辭典。
- run_alias: 套用別名並執行 ChatGPT API。
- set_llm: 設定專案的 LLM。
- update_alias: 更新 Prompt 別名。原有的別名並不會消失。
- update_prompt: 更新 ChatGPT Prompt 設定。
- update_userdefined: 更新自定義辭典。原有的辭典並不會消失。
data dict "" 根據 func 參數設置以下格式
data.alias dict {} 要更新的 Prompt 別名設定。
{text: {key: value_list}, regex: {key: value_list},
ner: {id: false, person: false, address: false, route: false, url: false}}
func: update_alias
data.assistant dict {} 要新增的 ChatGPT Assistant 內容。{title: value, content: {key: value}}
func: insert_assistant
data.checked_list str[] [] 設定新增句子時自動勾選的詞性 (參考詞性標記)。
func: insert_utterance
data.document dict {} 要新增到分類或分群的文件內容。{title: value, content: value, keyword: [], label: value}
func: insert_document
data.language str "zh-tw" 專案使用的語言,只能是 zh-twtaigi
func: create_project
data.llm str "" 設定專案使用的生成模型。
func: set_llm
data.messages dict {} 執行 ChatGPT API 的 messages 參數。[{role: user, content: value}]
func: preview_alias run_alias
data.name str "" 專案名稱。
func: create_project
data.prompt dict {} 要更新的 ChatGPT Prompt 設定。{system: value, assistant: value, user: value}
func: update_prompt
自定義分類及分群模型的 Prompt。
func: set_llm
data.source str "" 分群模型的 source。
func: get_source
data.type str "intent"
"basic"
專案的模型,只能是 intent / neuro_kumoko / greedy_slime
func: create_project
意圖的類型,只能是 basicadvance
func: create_intent
data.user_defined dict {} 要更新的自定義辭典。{key: value_list}
func: update_userdefined
data.utterance str[] [] 要分析的句子。
func: insert_utterance match_utterance

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 任務執行成功。
- Failure.: 任務執行失敗。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
result any 列出 preview_alias run_alias 的結果。
result_list list 列出 insert_utterance match_utterance get_utterance 的詳細結果。
alias_setting dict 列出 preview_alias 所套用的 Prompt 別名設定。

使用 Command API (建議改用 Loki Call)

範例程式:

from requests import post

url = "http://LokiTool_URL/loki/command/"
payload = {
    "project": "ProjectName",
    "intent": "IntentName",
    "type": "insert_utterance", # basic / advance
    "utterance": ["句子"]
}

response = post(url, json=payload)
var url = "http://LokiTool_URL/loki/command/";

var xhr = new XMLHttpRequest();
xhr.open("POST", url);

xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log(xhr.status);
        console.log(xhr.responseText);
    }
};

var data = `{
    "project": "ProjectName",
    "intent": "IntentName",
    "type": "IntentType", // basic / advance
    "utterance": ["句子"]
}`;

xhr.send(data);

回傳結果 (JSON 格式):

{
    "status": true,
    "msg": "Success!",
    "result_list": [{"status": true, "msg": "Success!"}]
}

使用 Loki Command 來爲意圖快速且大量地增加或比對句子。

HTTP Request

POST http://LokiTool_URL/loki/command/

參數說明

參數 型態 預設 功能
project str "" 專案名稱,如果不存在會自動建立專案。
intent str "" 意圖名稱,如果不存在會自動建立意圖。
type str "" 意圖類型,只能是 basicadvance
utterance str "" 建立單筆要分析的句子。
list [] 建立多筆要分析的句子。

回傳內容說明

回傳訊息 型態 說明
status bool 其值為 TrueFalse
msg str 可能為以下的文字:
- Success!: 順利完成意圖偵測。
- Project create success!: 建立專案成功。
- Intent create success!: 建立意圖成功。
- Project already exist!: 存在同樣名稱的專案。
- Intent already exist!: 專案內存在同樣名稱的意圖。
- Utterance already exist.: 意圖內存在同樣的句子。
- Pattern same as Utterance.: 意圖已存在相同結構的句子。
- Internal server error. (Your word count balance is not consumed, don't worry. System will reboot in 5min, please try again later.): 嗯…似乎出了點狀況。5 分鐘內會自動重啟,請稍後再試一次。如果一樣情況,請聯絡卓騰解決。
result_list list 建立句子的結果。