## タグ付けに困る
記事を書く時、ブログ内検索をしやすくする為にカテゴリーは自分で考えてつけるようにしているが、タグはつけたりつけなかったりしている。つけた記事だとMarkdownで書けるようにした記事でライブラリ名に使ったかな?
カテゴリーは自身のサイトの縦の繋がりを強めるが、タグは他のサイトと共通できるため、横の繋がりができる。そういった役割を持つのにライブラリ名をタグにするのは誰とも繋がれなさそうな感じがする。
とは言っても、カテゴリーとタグで何を付けたらいいのか分からないので書いている記事の内容からある程度推測してくれるととても助かるなあと思ったので、実装することにした。丁度てぃーだブログ改善案にタグの自動生成があったので、それを実現していく。
## 形態素解析
そもそも形態素解析とは何なのか、Wikipedia先生に聞いてみた。
> 形態素解析(けいたいそかいせき、Morphological Analysis)とは、文法的な情報の注記の無い自然言語のテキストデータ(文)から、対象言語の文法や、辞書と呼ばれる単語の品詞等の情報にもとづき、形態素(Morpheme, おおまかにいえば、言語で意味を持つ最小単位)の列に分割し、それぞれの形態素の品詞等を判別する作業である。
例えばよく例に挙げられるのが「すもももももももものうち」という言葉遊びで、これを形態素解析すると、
「すもも|も|もも|も|もも|の|うち」と品詞分解ができる。これをタグの自動生成に活用する。
## kuromoji.js
形態素解析のためのライブラリは殆どの言語でカバーされている。今回はユーザが入力した文字列を解析してタグを生成したいので、javascriptのライブラリであるkuromoji.jsを使う。サーバサイドであるNode.jsで使うものなので、`npm install kuromoji`でkuromoji.jsをインストールし、必要なディレクトリとスクリプトだけを使う。
詳しいインストール方法は[React + Kuromoji を使ってブラウザ上で形態素解析](https://qiita.com/torao@github/items/45ad9640cf94d3169cae)を参考
サーバサイドを介しないで処理を行いたいので、ついでにVue.jsもインストール。Vue.jsはフロントサイドのフレームワークなのでCDNからインストールで簡単。Vue.jsについてはいずれ紹介する。
## 簡単に実装してみる
```javascript
const vm = new Vue({
el: '#app',
data: {
entryForm: {
body: null
},
tags: null
},
methods: {
createTags: () => {
const text = vm.entryForm.body;
kuromoji.builder({ dicPath: './dict' }).build((error, tokenizer) => {
if (error) {
console.log(error);
} else {
temp = tokenizer.tokenize(text);
let counts = [], result = [];
for (let val of temp) {
if ('名詞' === val.pos && ('一般' === val.pos_detail_1 || '固有名詞' === val.pos_detail_1)) {
counts[val.surface_form] = counts[val.surface_form] ? counts[val.surface_form] + 1 : 1;
}
}
for (let i in counts) {
result.push({
word: i,
count: counts[i],
});
}
result.sort((a, b) => {
return b.count - a.count;
});
result = result.filter(val => {
return 2 <= val.count;
});
return vm.tags = result;
}
});
}
}
});
```
とりあえずVue.jsでバインドしたtextareaの文字列を取得し、createTagsが呼ばれたときに処理を行う。
タグで必要と思われるのは名詞で、かつkuromoji.jsで分類される一般と固有名詞だけをタグの候補とする。
重複した単語を数え上げるという処理が全然頭のいい実装方法が思いつかなかったので素直な方法を取る。
あとは降順にソートして、2回以上現れた単語をタグとしてView側(.htm)に返す。
## まとめ
まとめ見出しまでの記事内容でタグ自動生成を行ってみると以下のようなものが得られる。
> タグ 形態素 js val kuromoji counts result 記事 Vue ライブラリ 言語 インストール count カテゴリー 単語 品詞 列 サイド 方法 vm error let pos surface form i return 内容 ブログ サイト 自動 文法 情報 すもも もも 文字 サーバ const entryForm body null tags createTags text tokenizer if temp for 名詞 amp 一般 detail 固有名詞 a b
うん......
頻度が2回以上の単語で、スクリプトまで見てしまっているのでとても酷い状態になってしまう。
ただ頻度を絞るだけだと、記事を紹介するに最も相応しい単語が省かれてしまったりするので、この結果がどのような記事を表してるのかを考慮する必要がありそう。
また横のつながりを深めるためにはすでに他のブログの記事で用いられているタグを参照して、候補に上げる必要性もある。