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]
- 實體網卡名稱 (不能是 lo, docker 的虛擬網卡)
- MAC_ADDRESS
etherxx:xx:xx:xx:xx:xx

[主機 SSH KEY 的位置]
- USERNAME
- SSH_PRIVATE_KEY
/home/{USERNAME}/.ssh/{SSH_PRIVATE_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 是否正常運作。
- 請先安裝 ArticutAPI 或 下載 https://github.com/Droidtown/ArticutAPI
- 測試 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 下運行,可使用 crontab 或 systemd 兩種設定方法,預設每一分鐘檢查一次。
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 | 其值為 True 或 False。 |
| 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)
「實詞」是詞類的一種,又稱「名詞」,可以獨立成句。可指代人、物、事、時、地、情感、概念、方位的名詞等實體或抽象事物的詞。
有幾個詞組組合規則如下:
- 連續的 nouny 可以被視為是同一個大名詞組 (e.g., 咖啡(ENTITY_nouny) 杯(ENTITY_nouny) 就直接視為「咖啡杯」(ENTITY_NP)
- 遇到 nounHead 時,會向前疊加成為名詞組。(e.g., 小(MODIFIER) 紅(MODIFIER_color) 帽(ENTITY_nounHead) 會被疊加成為「小紅帽(ENTITY_nouny)」;遊樂(ACTION_verb) 場(ENTITY_nounHead) 會被疊加成「遊樂場」(ENTITY_nouny)
- 相對於前項,nouny 則不會跟動詞 (ACTION_verb) 做疊加成名詞組,只會在擔任動詞的受詞,而成為動詞組。(e.g., 認識(ACTION_verb) 字(ENTITY_nouny) 會變成「認識字」(VerbP)
| 標記名稱 | 說明 |
|---|---|
<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_noun、ENTITY_nouny、ENTITY_nounHead 或 ENTITY_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 | 其值為 True 或 False。 |
| 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 | 其值為 True 或 False。 |
| 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 | 其值為 True 或 False。 |
| 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
如果要改用 MySQL 或 PostgreSQL 資料庫,請打開 myproject/database.json 修改 engine 欄位爲要使用的資料庫 (mysql / postgresql),並填入資料庫的連線資訊,修改完畢後請執行一次 資料遷移。
啟動 LokiTool
啟動 LokiTool
$ python3 manage.py runserver
接著利用 manage.py runserver 啟動本機的 LokiTool 就能開始建立 NLU 專案,以及編寫各個意圖的內容了。

LokiTool 快速上手指南
打開 LokiTool
在瀏覽器網址列輸入 http://localhost:8000/loki/ 開始使用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 的網址後儲存,並在重新分析所有意圖的句子。

建立基本意圖
進入
[專案]後點擊[建立基本意圖]。
輸入意圖名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊
[建立意圖]。
若有
自定義詞彙,可以自行新增;若無,則進入下一步。
輸入意圖文句後點擊
[單句分析],建議一次一句,若有標點符號,系統會自動忽略。可大量輸入完再點擊[全句分析]。
勾選意圖所需
[參數](通常是會變動的值或詞彙,電腦需要計算的實體)。Loki 提供兩種方法勾選意圖參數:
Graph 勾選
[參數]

直接勾選
[參數]

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

輸入版本號,點擊
[佈署模型]。
輸入文句點擊
[意圖分析],測試意圖文句,確認是否有偵測到第 4 步所勾選的意圖與參數。
重複 4 至 6 步驟,直到全部訓練的文句皆可偵測其
意圖。
建立進階意圖
進入
[專案]後點擊[建立進階意圖]。
輸入意圖名稱 (僅接受英文 [a-z, A-Z]、數字 [0-9] 和底線 [_]),點擊
[建立意圖]。
若有
自定義詞彙,可以自行新增;若無,則進入下一步。
輸入意圖文句後點擊
[分析],系統會賦予預設的正規表達式 (Regex),根據需求自行調整,最後點擊[檢驗]驗證正規表達式 (Regex) 是否適用於意圖文句。
輸入版本號,點擊
[佈署模型]。
輸入文句點擊
[意圖分析],測試意圖文句,確認是否有偵測到意圖。
重複 4 至 5 步驟,直到全部訓練的文句皆可偵測其
意圖。
Loki 互動說明
簡單示意 Loki 如何使用相似結構 (Structural Pattern) 比對出最適合的 Utterance。

讀取 ATM 模型
打開 LokiTool
在瀏覽器網址列輸入 http://localhost:8000/loki/ 開始使用LokiTool。

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

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

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

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

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

分析並生成模型
後續請從 快速上手指南步驟 4 繼續完成。
使用 Loki 範本
Loki 目前提供 Python 和 Java (Android) 兩種程式範本,未來會支援更多的程式語言。
編譯專案意圖的計算邏輯
Loki 範本目錄結構
Project.py
intent/Loki_Intent.py
intent/Loki_xxxxx.py
回到 Loki 首頁,點擊
[專案範本]的程式語言 (如:Python) 開始下載。
解壓縮 .zip 檔案。檔案目錄結構如下:
在
Project.py檔案,修改LOKI_URL(預設已填上 ARTICUT_URL)。
在
intent/Loki_Intent.py檔案,開始編譯意圖語意的計算方法。
導入專案開始使用
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} 替換成相對應的內容,否則無法載入該模型。
LiteLLM
支援市面上常見的模型,請參考 LiteLLM 文件 設定模型 (model) 及相對應的環境變數 (env)。
REST API
API 可連線至客製化的 LLM 伺服器,但可能因 request 及 response 的格式不同而無法使用,內容格式必須包含
(url, header, payload),url為字串,header及payload為字典格式,而payload中必須存在字串{{MESSAGES}}。
在系統執行 preview_run 或 run_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-tw 或 taigi。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意圖的類型,只能是 basic 或 advance。func: create_intent |
| data.user_defined | dict | {} | 要更新的自定義辭典。{key: value_list}func: update_userdefined |
| data.utterance | str[] | [] | 要分析的句子。 func: insert_utterance match_utterance |
回傳內容說明
| 回傳訊息 | 型態 | 說明 |
|---|---|---|
| status | bool | 其值為 True 或 False。 |
| 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 | "" | 意圖類型,只能是 basic 或 advance 。 |
| utterance | str | "" | 建立單筆要分析的句子。 |
| list | [] | 建立多筆要分析的句子。 |
回傳內容說明
| 回傳訊息 | 型態 | 說明 |
|---|---|---|
| status | bool | 其值為 True 或 False。 |
| 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 | 建立句子的結果。 |