---
title: "Mecab、 Qdrant（ベクトルデータベース）と Bert Japanese を試してみた | grasys blog"
url: "https://blog.grasys.io/post/susu/try-mecab-qdrant-bertjapanese/"
description: "はじめに こんにちは。2023 年 9 月に grasys に入社したミャンマー出身のスースーです。 この記事では、前回の「Mecabを試してみた」という記事の続きとして、Python を使って Mecab と Qdrant（ベクトルデータベース）を連携する方法を紹介します。 まだ前回のブログを読んでいない方は、そち…"
---

# Mecab、 Qdrant（ベクトルデータベース）と Bert Japanese を試してみた

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[susu](/authors/susu/)
-   公開日：2025年1月22日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#MeCab](/tags/mecab/)[#Qdrant](/tags/qdrant/)[#BERT Japanese](/tags/bert-japanese/)[#Python](/tags/python/)[#ベクトルデータベース](/tags/ベクトルデータベース/)

![Mecab、 Qdrant（ベクトルデータベース）と Bert Japanese を試してみた](/_astro/hero.04HbFs1b_xk8Xi.webp)

## はじめに

こんにちは。2023 年 9 月に grasys に入社したミャンマー出身のスースーです。

この記事では、前回の「Mecabを試してみた」という記事の続きとして、Python を使って Mecab と Qdrant（ベクトルデータベース）を連携する方法を紹介します。

まだ前回のブログを読んでいない方は、そちらを先に読んでみてください。

[![関連記事『MeCabを試してみた』のアイキャッチ](/_astro/01-3e9ee0e37437a57a984c008a34452908-1024x536-5807ce7a.eK1NvfTq_ZbRgus.webp)](https://blog.grasys.io/post/susu/try-mecab/)

[Mecabを試してみた](https://blog.grasys.io/post/susu/try-mecab/)

では早速、Python で Mecab を使ってみましょう！

## Mecab を python で実施

Mecab は色々な言語をサポートしていますが、今回は python を使って実施方法を説明します。

Plain textcontent\_copy

```
mkdir mecab_blog
cd mecab_blog
rye init . --min-py 3.11 --no-pin --private --virtual
rye sync
touch mecab_qdrant.py
```

下記のコマンドを実行します。

Plain textcontent\_copy

```
mecab-config --dicdir
```

![Mecab を python で実施の画面](/_astro/02-image-9-d22b4673.BHWqcLZ2_yHaPD.webp)

mecab\_qdrant.py ファイルに下記のコードを記入します。

Plain textcontent\_copy

```
import MeCab

# MeCab タガーを初期化する
tagger = MeCab.Tagger("-d /opt/mecab/lib/mecab/dic/ipadic -Owakati")

#日本語の言葉を入力する
text = "旅行団体"

#テキストを解析する
parsed = tagger.parse(text)

#解析結果を表示する
print("結果:")
print(parsed)
```

ここでは、mecab-config –dicdir コマンドで実行した file path を Mecab.Tagger へ入れています。

私の file path は `/opt/mecab/lib/mecab/` なので `/opt/mecab/lib/mecab/dic/ipadic` へ入れています。

次に、下記のコマンドを実行します。

Plain textcontent\_copy

```
rye add mecab
rye sync
rye run python mecab_qdrant.py
```

こちらは python ファイルを実行した結果です。

Mecab では、本来「旅行団体」という言葉を「旅行」「団体」と二つの言葉に形態素解析しますが、前回のブログで Mecab の辞書へ「旅行団体」という言葉を追加しているので、今回の結果では一つの言葉として認識されています。

![MeCab タガーを初期化する画面](/_astro/03-image-10-077395d4.Z9AWrFRZ_ZQSsbW.webp)

## Mecab を Qdrant と Bert Japanese で実施

次に、形態素解析した結果を検索する方法を紹介します。

以下のような流れになります。

1.  Mecab を使って形態素解析した結果を
    
2.  Qdrant（ベクトルデータベース）に登録し
    
3.  BERT Japanese を使って検索する
    

Qdrant について知りたい方は、こちらのブログをチェックしてみてください。

[![Mecab を Qdrant と Bert Japanese で実施の画面（1）](/_astro/04-09680a05c9f40a4b155bf77f5815a51e-1024x536-d654950e.C4h1N7V3_Z2fzHMY.webp)](https://blog.grasys.io/post/susu/how-to-run-qdrant-with-docker-python-bertjapanese/)

[Qdrant （ベクトルデータベース）を試してみた](https://blog.grasys.io/post/susu/how-to-run-qdrant-with-docker-python-bertjapanese/)

Qdrant（ベクトルデータベース）が分かっている方はこのまま読み進めてください。

まずは、下記のコマンドを実行します。

Plain textcontent\_copy

```
touch qdrant.py
```

下記のコードを qdrant.py ファイルに記入してください。

Plain textcontent\_copy

```

from qdrant_client import models, QdrantClient
#docker に Qdrant のポート番号は 6333 で実行しているので 6333 を入れる
client = QdrantClient("0.0.0.0", port=6333)

client.recreate_collection(
    collection_name="dictionary_data", # 作成したい collection の名前をいれる
    vectors_config=models.VectorParams(
        size=768, # ベクトルサイズは使用するモデルによって定義される
        distance=models.Distance.EUCLID, # Euclidean distance を入れる
    ),
)
```

下記のコマンドを実行します。

Plain textcontent\_copy

```
rye add qdrant
rye sync
rye run python qdrant.py
```

下記のように dictionary\_data を Qdrant の collections に作成出来ました。

![Mecab を Qdrant と Bert Japanese で実施の画面（2）](/_astro/05-image-11-1024x381-cbfa5e31.BtdEI9Rz_ZvuSrN.webp)

japan\_words.xlsx ファイルに下記のようなデータを入れてください。自分が入れたい言葉を入れても大丈夫です。

![Mecab を Qdrant と Bert Japanese で実施の画面（3）](/_astro/06-image-12-1024x876-aea0d857.Dr_l8ksh_15tidL.webp)

下記のコマンドを実行します。

Plain textcontent\_copy

```
touch update_dicitonary_data.py
```

update\_dicitonary\_data.py のファイルに下記を記入してください。

Plain textcontent\_copy

```
from qdrant_client import models, QdrantClient
import pandas as pd
from transformers import AutoModel, AutoTokenizer

#bert japanese model を使って vector database にデータをインポートする。
model_name = "cl-tohoku/bert-base-japanese-v3"
bertjapanese = AutoModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

client = QdrantClient("0.0.0.0", port=6333)

#エクセルファイルのデータをインポートする
df = pd.read_excel('./japan_words.xlsx')
#dictionary に変換する
myDict = df.to_dict('records')

# bert japanese で日本語の言葉をベクトルで変換して Qdrant Collection にデータ登録する
client.upload_records(
    #インポートしたい collection の名前を記入する
    collection_name="dictionary_data",
    #bert japanese モデルは dimension = 768 なので 768 ベクトルでデータ登録する
    records=[
        models.Record(
            id=idx, vector=bertjapanese(**tokenizer(doc["word"], return_tensors="pt"))[0][0][0], payload=doc
        )
        for idx, doc in enumerate(myDict)
    ],
)

print ("データ登録成功になりました。")
```

下記のコマンドを実行します。

Plain textcontent\_copy

```
$ rye add pandas
$ rye add transformers
$ rye add torch
$ rye add fugashi
$ rye add unidic_lite
$ rye add openpyxl
$ rye sync
$ rye run python update_dicitonary_data.py
```

update\_dicitonary\_data.py を実行すると下記のようになります。Qdrant の collection にデータをアップロードしました。

![bert japanese で日本語の言葉をベクトルで変換して Qdrant Collection にデータ登録する画面（1）](/_astro/07-image-13-1024x328-4f75add4.B5WuO8hB_2tDMUK.webp)

![bert japanese で日本語の言葉をベクトルで変換して Qdrant Collection にデータ登録する画面（2）](/_astro/08-image-14-1024x559-d4099d07.C6W4Rs2m_1qNM3J.webp)

下記のコマンドを実行します。

Plain textcontent\_copy

```
touch mecab_separate.py
touch mecab_qdrant_search.py
```

mecab\_separate.py のファイルに下記を記入してください。

Plain textcontent\_copy

```
import MeCab
import pandas as pd

class CustomMeCabTagger:
    MECAB_COLUMNS = ['word',
                        'speech',
                        'subclassification_1',
                        'subclassification_2',
                        'subclassification_3',
                        'utilization_type',
                        'conjugation_form',
                        'original_form',
                        'reading',
                        'pronunciation',
                        'new_word_flag',
                        'remark',
                        ]

    def __init__(self, dicdir=None):
        if dicdir:
            self.tagger = MeCab.Tagger(f"-d {dicdir}")
        else:
            self.tagger = MeCab.Tagger()

    def parseToDataFrame(self, text: str) -> pd.DataFrame:
        """テキストを parse した結果を Pandas DataFrame として返す"""
        new_word_data = []
        new_word_pd = ""

        for line in self.tagger.parse(text).split('\n'):
            if line == 'EOS':
                break
            if '\t' not in line:
                continue
            surface, feature = line.split('\t')
            feature = [None if f == '*' else f for f in feature.split(',')]

            # mecab の基本列は 9 つなので、追加した2列の言葉だけを取得する場合は 10 以上のデータのみ取得する。
            if (len(feature) >= 10):
                new_word_data.append([surface, *feature])

        # 新しい言葉の合計
        word_total = len(new_word_data)

        # 新しい言葉だけ渡す
        if (len(new_word_data) > 0):
            new_word_pd = pd.DataFrame(new_word_data, columns=type(self).MECAB_COLUMNS)
        return new_word_pd, word_total
```

下記のコマンドを実行して、dicdir の filepath を取得します。

Plain textcontent\_copy

```
mecab-config --dicdir
```

mecab\_qdrant\_search.py のファイルに下記を記入してください。

dicdir の filepath には先ほど取得した file path を入れてください。

Plain textcontent\_copy

```
from qdrant_client import models, QdrantClient
from transformers import AutoModel, AutoTokenizer
import MeCab
import mecab_separate

#docker に Qdrant のポート番号は 6333 で実行しているので 6333 を入れる
client = QdrantClient("0.0.0.0", port=6333)

#bert japanese model を使って collection データを検索する。
model_name = "cl-tohoku/bert-base-japanese-v3"
bertjapanese = AutoModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Input Japanese text
text = "お疲れ様です。お元気ですか。旅行団体で旅行しますか？大学で学生集団しますか？"

tagger = mecab_separate.CustomMeCabTagger(dicdir='/opt/mecab/lib/mecab/dic/ipadic')
df, total_word_count = tagger.parseToDataFrame(text)

#新しい言葉だけを取得しているので新しい言葉の結果
print("結果:")
print(df['word'])

datas = df['word']

for word in datas:
    # collection データで言葉を検索する。
    # limit 3 は取得データ一つを取得するという意味です。
    print("qdrant で",word, "の検索結果:")
    hits_bertjp_eu = client.search(
        collection_name="dictionary_data",
        query_vector=bertjapanese(**tokenizer(word, return_tensors="pt"))[0][0][0],
        limit=3,
    )
    # 結果とスコアで表示する
    for bertjp_eu in hits_bertjp_eu:
        print(bertjp_eu.payload, "score:", bertjp_eu.score)
```

mecab\_blog の中に下記のようなファイルがあります。

![Input Japanese textの画面（1）](/_astro/09-image-15-1024x128-ab93c16f.qy7OSFAp_AXV0y.webp)

下記のコマンドを実行します。

Plain textcontent\_copy

```
rye run python mecab_qdrant_search.py
```

![Input Japanese textの画面（2）](/_astro/10-image-17-1024x443-562bff67.D6W6745O_1yJHEu.webp)

Qdrant で検索をすると、検索した言葉との類似度をスコアとして表示します。

完全一致している言葉のスコアは 0.0 で表示されます。今回は「旅行団体」という言葉を事前に登録していたので、スコアが 0.0 となっています。

完全一致ではない言葉はそれぞれのスコアが表示されます。今回はスコア 11〜13 までの言葉が表示されていますが、Qdrant へさらに多くの言葉を登録すると、上記よりもスコアの低い（類似している）言葉が表示されるようになると思います。

## まとめ

今回のブログでは Mecab と Qdrant と Bert Japanese の以下について説明してきました。

-   Mecab で形態素解析をする方法
    
-   Mecab の辞書に追加した二列のカラムに入っている言葉のみを形態素解析する方法
    
-   Mecab で形態素解析して新しい言葉だけを取得し、Qdrant のデータを Bert Japanese のモデルを使って検索する
    

Mecab と Qdrant と Bert Japanese に関する情報はまだまだ少ないので、このブログが学んでる人の助けになれば嬉しいです。

こちらのブログもぜひチェックしてみてください。

[![Qdrant （ベクトルデータベース）を試してみたの画面（1）](/_astro/04-09680a05c9f40a4b155bf77f5815a51e-1024x536-d654950e.C4h1N7V3_Z2fzHMY.webp)](https://blog.grasys.io/post/susu/how-to-run-qdrant-with-docker-python-bertjapanese/)

[Qdrant （ベクトルデータベース）を試してみた](https://blog.grasys.io/post/susu/how-to-run-qdrant-with-docker-python-bertjapanese/)

[![Qdrant （ベクトルデータベース）を試してみたの画面（2）](/_astro/01-3e9ee0e37437a57a984c008a34452908-1024x536-5807ce7a.eK1NvfTq_ZbRgus.webp)](https://blog.grasys.io/post/susu/try-mecab/)

[Mecabを試してみた](https://blog.grasys.io/post/susu/try-mecab/)

## この記事を書いた人

[![](/_astro/noicon.CTHOhNiB_Z24aAgM.webp)](/authors/susu/)

### [susu](/authors/susu/)

susuのプロフィールと執筆記事をご覧いただけます。

[プロフィールと記事一覧](/authors/susu/)