0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MeCab ver.0.996の辞書ファイルの設定【Windows】

Last updated at Posted at 2021-09-03

#1. はじめに
 この記事では、日本語形態素解析エンジン MeCab ver.0.996 における辞書ファイルの設定について記載しています。OSは、Windowsを前提としています。
 MeCab: Yet Another Part-of-Speech and Morphological Analyzerには、何故かWindowsのインストールについては、自己解凍インストーラの話しか書いてありません。辞書ファイルの設定が何も記載されていません。

Windows
バイナリをインストールする場合は, 自己解凍インストーラ (mecab-X.X.exe) を実行してください. 辞書も同時にインストールされます。

 以下は、MeCab ver.0.996 のソースコードから読み取った手探りです。
 なお、以下のソリューションでデパッグすると、以下の動作がトレース可能です。

 https://github.com/k-ayaki/mecab-msvc

#2. MeCabの辞書ファイルについて
 MeCabの辞書ファイルは、以下のものです。これは、C:\Program Files (x86)\MeCab\dic\ipadic に格納されているものです。

ファイル名 機能
sys.dic システム辞書
unk.dic 未知語辞書
dicrc IPA辞書の定義ファイル

 辞書の定義ファイルには、sys.dicとunk.dic のコストファクター、評価サイズ、文字コードなどが記載されています。これは書き換えたことはありません。

dicrc
;
; Configuration file of IPADIC
;
; $Id: dicrc,v 1.4 2006/04/08 06:41:36 taku-ku Exp $;
;
cost-factor = 800
bos-feature = BOS/EOS,*,*,*,*,*,*,*,*
eval-size = 8
unk-eval-size = 4
config-charset = SHIFT-JIS

; yomi
node-format-yomi = %pS%f[7]
unk-format-yomi = %M
eos-format-yomi  = \n

; simple
node-format-simple = %m\t%F-[0,1,2,3]\n
eos-format-simple  = EOS\n

; ChaSen
node-format-chasen = %m\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[4]\t%f[5]\n
unk-format-chasen  = %m\t%m\t%m\t%F-[0,1,2,3]\t\t\n
eos-format-chasen  = EOS\n

; ChaSen (include spaces)
node-format-chasen2 = %M\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[4]\t%f[5]\n
unk-format-chasen2  = %M\t%m\t%m\t%F-[0,1,2,3]\t\t\n
eos-format-chasen2  = EOS\n

 この辞書ファイルの場所を指定しているのが、C:\Program Files (x86)\MeCab\etc\mecabrc です。
 dicdir に、ipa辞書のパスが格納されています。なお、$(rcpath)は、当該ファイルのパスのことです。

mecabrc
;
; Configuration file of MeCab
;
; $Id: mecabrc.in,v 1.3 2006/05/29 15:36:08 taku-ku Exp $;
;
dicdir =  $(rcpath)\..\dic\ipadic

; userdic = /home/foo/bar/user.dic

; output-format-type = wakati
; input-buffer-size = 8192

; node-format = %m\n
; bos-format = %S\n
; eos-format = EOS\n

 MeCabのライブラリである libmecab.dll は、mecabrcを読み込んでipa辞書ファイルを特定したのち、sys.dic, unk.dic, dicrcなどを読み込んでいます。

#3. libmecab.dll による mecabrc パスの特定方法

#3.1. 環境変数による特定
 環境変数 HOMEがあれば、mecabrcのパスとして読み取ります。
 次に環境変数MECABRCがあれば、mecabrcのパスとして読み取ります。

 なお、コンパイル時のマクロ HAVE_GETENV を定義しないとき、libmecab.dll は環境変数を読み取らなくなります。

utils.cpp
#ifdef HAVE_GETENV
  if (rcfile.empty()) {
    const char *homedir = getenv("HOME");
    if (homedir) {
      const std::string s = MeCab::create_filename(std::string(homedir),
                                                   ".mecabrc");
      std::ifstream ifs(WPATH(s.c_str()));
      if (ifs) {
        rcfile = s;
      }
    }
  }

  if (rcfile.empty()) {
    const char *rcenv = getenv("MECABRC");
    if (rcenv) {
      rcfile = rcenv;
    }
  }
#endif

#if defined (HAVE_GETENV) && defined(_WIN32) && !defined(__CYGWIN__)
  if (rcfile.empty()) {
    scoped_fixed_array<wchar_t, BUF_SIZE> buf;
    const DWORD len = ::GetEnvironmentVariableW(L"MECABRC",
                                                buf.get(),
                                                buf.size());
    if (len < buf.size() && len > 0) {
      rcfile = WideToUtf8(buf.get());
    }
  }
#endif

#3.2. レジストリによる特定(Windows固有)
 環境変数が定義されておらず、且つ、レジストリ HKEY_LOCAL_MACHINE\software\mecab に、mecabrcキーがあれば、その値を mecabrcのパスとして読み取ります。
 レジストリ HKEY_CURRENT_USER\software\mecab に、mecabrcキーがあれば、その値を mecabrcのパスとして読み取ります。

 なお、Windows版のMeCab ver.0.996 をインストールしたときには、レジストリ HKEY_CURRENT_USER\software\mecabに、mecabrcキーが書き込まれます。

utils.cpp
#if defined(_WIN32) && !defined(__CYGWIN__)
  HKEY hKey;
  scoped_fixed_array<wchar_t, BUF_SIZE> v;
  DWORD vt;
  DWORD size = v.size() * sizeof(v[0]);

  if (rcfile.empty()) {
    ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"software\\mecab", 0, KEY_READ, &hKey);
    ::RegQueryValueExW(hKey, L"mecabrc", 0, &vt,
                       reinterpret_cast<BYTE *>(v.get()), &size);
    ::RegCloseKey(hKey);
    if (vt == REG_SZ) {
      rcfile = WideToUtf8(v.get());
    }
  }

  if (rcfile.empty()) {
    ::RegOpenKeyExW(HKEY_CURRENT_USER, L"software\\mecab", 0, KEY_READ, &hKey);
    ::RegQueryValueExW(hKey, L"mecabrc", 0, &vt,
                       reinterpret_cast<BYTE *>(v.get()), &size);
    ::RegCloseKey(hKey);
    if (vt == REG_SZ) {
      rcfile = WideToUtf8(v.get());
    }
  }

#3.3. libmecab.dllのパスによる特定(Windows固有)
 環境変数とレジストリが定義されていないならば、libmecab.dllのパスを取得して、mecabrcのパスとします。

utils.cpp(Windows固有)
  if (rcfile.empty()) {
    vt = ::GetModuleFileNameW(DllInstance, v.get(), size);
    if (vt != 0) {
      scoped_fixed_array<wchar_t, _MAX_DRIVE> drive;
      scoped_fixed_array<wchar_t, _MAX_DIR> dir;
      _wsplitpath(v.get(), drive.get(), dir.get(), NULL, NULL);
      const std::wstring path =
          std::wstring(drive.get()) + std::wstring(dir.get()) + L"mecabrc";
      if (::GetFileAttributesW(path.c_str()) != -1) {
        rcfile = WideToUtf8(path);
      }
    }
  }

#3.4. マクロ定義したパスによる特定
 マクロ MECAB_DEFAULT_RC で定義したパスを、mecabrcのパスとします。

utils.cpp
  if (rcfile.empty()) {
    rcfile = MECAB_DEFAULT_RC;
  }

#3.5. 特定したmecabrcパスの読み込み

 特定したmecabrcパスに基づき、dicdir(辞書パス)を読み込みます。

utils.cpp
  if (!param->load(rcfile.c_str())) {
    return false;
  }

#3.6. dicdir(辞書パス)の決定

 特定したmecabrcパスに基づき、dicdir(辞書パス)を読み込みます。

utils.cpp
  std::string dicdir = param->get<std::string>("dicdir");
  if (dicdir.empty()) {
    dicdir = ".";  // current
  }
  remove_filename(&rcfile);
  replace_string(&dicdir, "$(rcpath)", rcfile);
  param->set<std::string>("dicdir", dicdir, true);
  dicdir = create_filename(dicdir, DICRC);

  if (!param->load(dicdir.c_str())) {
    return false;
  }

  return true;
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?