【究極の要約】自動で投稿の重要ワードを出してくれる機能を作った【WordPress】

最終更新日:

あなたがとあるWebページに訪問したとして、まず最初に見るのは恐らくタイトルでしょう。 そしてその次に更新日時目次イントロダクション(冒頭)等を見るかと思います。

これらの情報は「メタ情報」とも呼ばれ、その記事を簡単に説明できる要素の集まりです。そしてそれがファーストビューに集まっていることで、ユーザーは記事の趣旨をある程度把握できます。

そして今回、このファーストビューに、その記事における重要語のリストのようなものがあったら、より記事の趣旨というか主成分というものを把握してもらえるのではないかと思い、WordPress上で実装することにしました。

重要語とSEO

冒頭で述べた通り、私は完全に利用者目線で考えて、重要語のリストみたいなのがあったら面白いんじゃないと思った限りですが、忘れてはいけないのは「SEO」という概念です。

利用者にとって良いと感じたとしてもそれをGoogleのAIが好むかどうかは別の話であり、特にファーストビューという大切なところに変な情報を入れてしまうとSEOにおける評価が下がってしまう可能性があります。

キーワードは重要ではない

以前まで、Google AI等のロボットに記事の内容を伝えるためのメタ情報の中に、メタキーワードというものがありました。 これはその記事における重要なキーワードを記述する要素で、その内容がSEOにおける評価に直接関わっていたそうです。

しかしGoogle AIは進化し、別に記事の作成者がキーワードを手動で指定しなくても、記事の中のどの単語が重要なのかを解析できるようになり、メタキーワード情報はもはやSEOには関係なくなりました

Googleは記事の作成者に対して、とにかく(検索)利用者が喜ぶ素晴らしい文章・素晴らしい情報を提供してほしいと考えているだけであって、別にSEO対策のプロであることは求めていないかと思います。 だからGoogle AIが進化するごとに、いわゆるSEO対策の中でも「記事を真面目に作る」ことの重要さが増していって、それ以外の技術的な対策に関しては不必要になってきていますね。

キーワードスタッフィング

そしてGoogle AIが進化し、重要語を記事に詰め込みまくる、いわゆる「キーワードスタッフィング」の効力は無くなったというか、むしろ減点対象になってきているようです。

そのため、記事の冒頭にその記事の重要語リストを並べてしまったら減点される可能性すらあるわけですが、別に同じワードを何度も登場させているわけではないので個人的に問題ないかと思います。

実装して検索順位が大きく下がったらその時に対応すればいいですね。

むしろ、記事の冒頭に重要語を集めることでSEO的に評価が上がる可能性もあります。ただ、本文だと勘違いされたら文法を無視した乱れている文章だと勘違いされて評価を下げられかねないので、タグのリストであることをちゃんとHTML的に示したいと思います。

実装してみる

それでは早速、実装していきたいと思います。

重要語の生成

重要語を、重要度が高い順にサイズを大きくしつつ並べていきたいと考えているので、ここでは「TF-IDF」というアルゴリズムを用います。 簡単に説明すると、

TF-IDF

  • その記事に登場する回数が多いほど重要
  • 全記事の中で登場率が低い単語ほど重要

こんな単純なアルゴリズムではあるのですが、現在でも自然言語処理においてバリバリ使われていたりするようですね。

それぞれの記事のTF-IDFリストの生成については以下の記事で紹介しましたので、ぜひご覧ください。

【機械学習】WordPressでより高精度な関連記事を表示させたい【Python】

ここでは記事のTF-IDFリストをその記事の特徴という風にとらえて、TF-IDFリスト(ベクトル)が似ている同士を関連記事と捉えることで、自動的に関連記事を生成するシステムを作りました。

実際に、そこそこ的を得た関連記事を提案してくれています。

そして今回はこのシステムの処理過程で生成するTF-IDFリストをそのまま変形しつつ、利用します。

各記事の重要語リストを生成

上のシステムで生成しているTF-IDFリストは二次元構造であり、一次元目がワード(トークン)で二次元目が記事IDとなっているので、これを変形させて各記事の重要語リストを参照できる形にします。

import json
import math

with open('post_tfidf.json') as f:#投稿のTFIDFリスト
    post_tfidf_dic = json.load(f)

post_tag_dic = {}

for each_word in post_tfidf_dic: #それぞれのトークンについて
    for each_post in post_tfidf_dic[each_word]: #それぞれの投稿について
        if each_post not in post_tag_dic:
            post_tag_dic[each_post] = {}
        post_tag_dic[each_post][each_word] = post_tfidf_dic[each_word][each_post]

for each_post in post_tag_dic: #それぞれの投稿について
    sorted_tag_list = sorted(post_tag_dic[each_post].items(), reverse=True, key=lambda x : x[1])
    sorted_tag_list = sorted_tag_list[0:20] if len(sorted_tag_list) > 20 else sorted_tag_list

    max_tfidf = max([x for _,x in sorted_tag_list])
    scaled_list = {word:tfidf/max_tfidf if tfidf/max_tfidf > 0.1 else 0.1 for word,tfidf in sorted_tag_list}

    post_tag_dic[each_post] = scaled_list

with open('post_tag.json', 'wt') as f:
    json.dump(post_tag_dic, f)

こんな感じでやってみました。TFIDFの値は結構振れ幅があるので、その投稿内で最も高いTFIDF値をもつもののスコアを1として、それを基準に他のワードを重要度が高い順に20個ほど、リストにしています。

こうして、記事IDを入れるだけですぐに重要タグを20個ほど出してくれるJSONデータができました。

重要語を取得してHTMLコードを生成するスクリプト

続いてこのJSONファイルを参照して、現在表示している記事の重要タグを取得し、それをHTMLコードにするJavaScriptの処理を作っていきます。

//タグリストを表示していく
const tagst = JSON.parse(data["tag_list"]);
const base_scale = device=="pc" ? 30 : 25;

if(jQuery("#post_tag_field").length){
    jQuery("#post_tag_field ul").html(
        Object.keys(tagst)
        .sort((a,b) => tagst[b] - tagst[a])
        .map((tag) => `<li><p style="font-size:${base_scale * tagst[tag]}px">${tag}</li>`)
        .join("")
    );
}

こんな感じですね。この記述の上の方で、JSONデータを取得して現在表示しているページの重要タグリストをtagst変数に格納する処理を書いています。

重要度の高い順に並び変えた後にmapメソッドでDOMを作りつつ、それをjQueryで書き込んでいます。あとはCSSを整えて、以下のようになりました。

実際に記事の重要ワードを出力してみた

こんなタイトルの下にでかでかと載せていいのかといった感じですが、とりあえずまぁこれでその記事の内容を肌で感じることができるかなと思います。

でも、「こと」のような常用のワードまで入ってしまっているのでまだ調整が必要そうですね。


関連記事

    人気記事

    じゅんき
    BableTech再整備中です10月頃にまた本格的に始動する見込みです。ちなみに管理人20歳の情報系大学生です。忙しいです(泣)

    記事内用語

    詳細ページ