古文書

前陣子因為想練習python和想把elasticsearch-kuromoji換掉,所以就試著用看看janome
畢竟只是要分詞的話不需要用到elasticsearch這麼大的服務。

除了janome之外,這邊會另外用到flask,因為打算寫個HTTP API來呼叫使用。

python的程式碼內容如下:

# index.py
from janome.tokenizer   import Tokenizer
from janome.analyzer    import Analyzer
from janome.charfilter  import *
from janome.tokenfilter import *

from flask import Flask , request , jsonify

# 

POS_STOP = [
    '判定詞',
    '助動詞',
    '接続詞',
    '指示詞',
    '助詞',
    '接頭辞',
    '接尾辞',
    '特殊',
    '接頭詞',
    '記号',
]

char_filters = [
    UnicodeNormalizeCharFilter(),
    RegexReplaceCharFilter(':+\w+(?: \w+)*:', u''),
    RegexReplaceCharFilter(':_+\w+(?: \w+)*:', u''),
    RegexReplaceCharFilter('[A-Za-z0-9!,*)@#%(&$_?.^:~]', u''),
]

token_filters = [
    CompoundNounFilter(), 
    POSStopFilter(POS_STOP), 
    LowerCaseFilter()
]

t = Tokenizer("user.dic.csv", udic_type="simpledic", udic_enc="utf8")

a = Analyzer(char_filters=char_filters , tokenizer=t, token_filters=token_filters)

# 

app = Flask(__name__)

@app.route("/")
def index():
    return jsonify({ "result" : 'not here' })

@app.route("/parse", methods=['POST'])
def work():
    output = []
    inputs = request.get_json()

    content = inputs['content'] if 'content' in inputs else ''

    if content != '':
        for token in a.analyze(content):
            word = token.surface
                
            if word not in output:
                output.append(word)

    return jsonify(output)

其中的POS_STOPchar_filterstoken_filters是用來過濾不需要的詞或是字元。

接下來寫個dockerfile來包裝:

# Dockerfile
FROM python:3.10-alpine
WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

ENV FLASK_APP=index
ENV FLASK_ENV=development

COPY [ "requirements.txt" , "user.dic.csv" , "index.py" , "/app/" ]

RUN pip install --no-cache-dir -r requirements.txt

CMD exec python -m flask run --host=0.0.0.0 --port=$PORT

requirements.txt的內容:

janome
flask
gunicorn

user.dic.csv是自定的字典檔,格式不只一種。這邊使用的是udic_type="simpledic",所以這邊會是像這樣:

マリカ,カスタム名詞,マリカ

詞性部分就都用カスタム名詞。畢竟不懂日文,只是想要簡單分個詞而已。

dockerfile和需要的檔案建立好後,接下來就可以跑build了:

docker build -t janome-flask . --no-cache

接著就跑起來吧:

docker run -itd --name janome-flask -e PORT=8080 -p 8181:8080 -v ${PWD}/index.py:/app/index.py janome-flask

這邊先用-v來方便除錯。

最後就可以使用curl指令來測試了:

curl -s -X POST -H "Content-Type: application/json" -d '{ "content" : "にじさんじとは、ANYCOLOR株式会社が運営するバーチャルライバーグループです。YouTube、bilibili、ツイキャスなどで活動しています。" }' "http://127.0.0.1:8181/parse" 

順利的話,輸出結果會是:

[
  "にじさんじ",
  "株式会社",
  "運営",
  "する",
  "バーチャル",
  "ライバーグループ",
  "ツイキャス",
  "活動",
  "し",
  "い"
]