形態素解析を実装する必要があったのでメモ。
思った以上に簡単に始められた。
MeCabのインストール
データのダウンロード
MeCab、IPA辞書(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年末版 形態素解析器の比較」