未分類

NLP:すぐできる形態素解析。C++でMeCabとIPA辞書を使った形態素解析(Linux、Mac)

形態素解析を実装する必要があったのでメモ。

思った以上に簡単に始められた。

MeCabのインストール

データのダウンロード

MeCabIPA辞書(Googleドライブのためwgetなど不可)

インストール

//一般的なフリーソフトウェアと同じ手順でインストールできます。
tar zxfv mecab-X.X.tar.gz
cd mecab-X.X
./configure --with-charset=utf8
make
sudo make install
//辞書のインストール
tar zxfv mecab-ipadic-2.7.0-XXXX.tar.gz
mecab-ipadic-2.7.0-XXXX
./configure
make
sudo make install

iTerm2やTerminalが文字化けしてしまう場合

こちら参考で解決できました。

形態素解析

#include <iostream>
#include <mecab.h>

int main(int argc, char **argv)
{

    //解析する文章
    char input[1024] = "司馬牛君子を問う。子曰く、君子は憂えず懼れず、と。曰く、憂えず懼れざれば、斯ち之を君子と謂うか、と。子曰く、内に省みて疚しからざれば、夫れ何をか憂え何をか懼れん、と。";

    //  1語づつ品詞分類
    MeCab::Tagger *tagger = MeCab::createTagger("");
    //  スペース区切りの文章に出力
    //  MeCab::Tagger *tagger = MeCab::createTagger("-Owakati");

    const char *result = tagger->parse(input);
    //ターミナルに出力
    std::cout << result << std::endl;

    delete tagger;
}

main.cppとして保存して、以下を実行。(main.cppとtext.txtは同じディレクトリに置いて、そのフォルダで実行)

g++ `mecab-config --cflags` main.cpp  `mecab-config --libs` &&  ./test.out | head -n 30

http://www.mwsoft.jp/programming/nlp/mecab_cpp.html

品詞ごとの登場頻度を調べる。

#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <mecab.h>

using namespace std;

vector<string> split(string s, string c)
{
    vector<string> ret;
    for (int i = 0, n; i <= s.length(); i = n + 1)
    {
        n = s.find_first_of(c, i);
        if (n == string::npos)
            n = s.length();
        string tmp = s.substr(i, n - i);
        ret.push_back(tmp);
    }
    return ret;
}

typedef map<string, int>::const_iterator map_freq_it;
typedef std::vector<map_freq_it>::const_iterator vec_stu_citer_t;

bool compare(const map_freq_it &a, const map_freq_it &b)
{ 
    return (a->second > b->second);
}

int main(int argc, char **argv)
{
    ifstream fin("./text.txt");   //同じフォルダの「text.txt」
    string str;
    char c;
    while (fin.get(c))
    {
        str.push_back(c);
    }

    MeCab::Tagger *tagger = MeCab::createTagger("");
    const MeCab::Node *node = tagger->parseToNode(str.c_str());
    map<string, int> freq;

    map<string, int>::iterator it;

    for (node = node->next; node->next; node = node->next)
    {
        vector<string> strvec = split(node->feature, ", ");
        if (strvec[0] == "動詞")//品詞を指定
        {
            string noun = strvec[6];
            it = freq.find(noun);
            if (it != freq.end())
            {
                it->second += 1;
            }
            else
            {
                freq.insert(pair<string, int>(noun, 1));
            }
        }
    }

    vector<map_freq_it> sorted;
    for (map_freq_it mfi = freq.begin(); mfi != freq.end(); ++mfi)
        sorted.push_back(mfi);

    sort(sorted.begin(), sorted.end(), compare);

    for (vec_stu_citer_t it = sorted.begin(); it != sorted.end(); ++it)
    {
        cout << (*it)->first << ", ";
        cout << (*it)->second << endl;
    }
    delete tagger;
    return 0;
}

参考

 

自然言語処理の盛んな大学

自然言語処理が学べる研究室
https://cl.sd.tmu.ac.jp/prospective/labs

日本所属の言語処理トップカンファレンス論文 (2021年)
https://murawaki.org/misc/japan-nlp-2021.html

よく使われる自然言語処理ツール

日本語解析ライブラリ

MECAB和布蕪(めかぶ))京都大学
一番よく使われる(らしい?)

JUMAN++
言語モデルとして Recurrent Neural Network Language Model (RNNLM) を使用。

JANOME蛇の目
Pythonライブラリ

英語・ラテン語系解析

Tree Tagger

NLTK

日本語NLP比較

参考「2019年末版 形態素解析器の比較」

-未分類