一日一膳(当社比)

RとJavaと時々数学

【R】Search Consoleレポートからクリック率を高めるキーワードを推定する

1. 検索キーワードとクリック率

Search Consoleで取得できる検索パフォーマンスレポートでは, Search Consoleを導入済みウェブサイトがどのような検索キーワードからアクセスされているかを確認できます.

このデータを元に「どんなキーワードで自分のウェブサイトがクリックされやすいか?」を意識して サイト内容を見直すことで, 検索エンジンからのアクセス数を改善することができます.

本記事では検索パフォーマンスレポートのデータを基に, 検索に使われる高クリック率なキーワードの分析をRを使って試してみます.

f:id:kimigayoseishou:20200610132907p:plain

2. モデル化

2.1 ロジスティック回帰

検索クエリは, 複数キーワードの組み合わせ(例えば, 「おいしいカレー / 作り方」)からなります. キーワードごとのクリック率の傾向を見るためには検索クエリをキーワード単位で分解する必要があります.
そこでまず, 検索クエリ内に現れるキーワードを予めリストアップしておき, w1, \ldots, w_Lとします. 次に検索クエリQに対して,

q_j = \begin{cases} 1 ,  \quad ({\rm キーワード}w_j{\rm が}Q{\rm に含まれる}) \\ 0 , \quad ({\rm  上記以外})\end{cases}

とすることで, 検索クエリをキーワードの有無を各成分にもつベクトルq = (q_j) \in {0,1}^Lに変換できます.

検索クエリQで検索を行ったユーザーが自分のサイトにアクセスした場合1, そうでない場合0とするbinaryな確率変数をYとします.

検索クエリと自分のサイトのクリック率の関係を探るためモデルを導入します. 今回は最も単純なモデルとして, Yを目的変数, クエリQのベクトル化qを説明変数としたロジスティック回帰(logistic regression) :

\begin{align} Y | Q \sim {\sf Binomial}(\pi), \quad \pi = \frac{\exp(\beta_0 + \beta ^\top q)}{1 + \exp(\beta_0 + \beta ^\top q)} \end{align}

を採用します, ただし\beta_0 \in {\mathbb R}, \beta = (\beta_1, \ldots, \beta_L) \in {\mathbb R}^Lはパラメータです.

\pi = p(Y = 1 |Q)はクリック率に対応するため, \beta_jが大きいキーワードw_jほど, 高クリック率になりやすいキーワードだと考えられます.

2.2 正則化

N個の検索クエリ\underline{Q} = (Q_1, \ldots, Q_N)と実際にクリックされたかどうかの結果\underline{y} = (y_1, \ldots, y_N) \in {0, 1} ^ Nを観測値としてロジスティック回帰モデルのパラメータの推定を行いたい.

最尤推定では対数尤度l(\beta_0, \ \beta) = \log p(\underline{y}|\underline{Q})の最大化によりパラメータ推定を行いますが, 今回の観測データのように検索キーワードを説明変数とするモデルでは, 説明変数が多くなり過学習に陥ってしまう恐れがあります.

このような場合, 適当な罰則項を考慮した最適化問題

\begin{align} \underset{(\beta_0, \ \beta) \in {\mathbb R}^{L+1}}{{\sf argmin}}\ - \frac{1}{N} l(\beta_0, \ \beta) + \lambda ({\text 罰則項}) \end{align}

によるパラメータ推定を行うことで過学習を回避できることがあります(正則化). 代表的な罰則項としては次のようなものがあります


3. glmnetを利用したLasso推定

以下, Ridge/Lasso(及びその線型和であるElastic Net)正則化回帰モデルを扱うRパッケージ glmnetパッケージを利用して, 検索パフォーマンスレポートのデータの分析を行います.

使用するデータは当ブログの過去3ヶ月のデータですが, Search Consoleを利用している方は 自サイトのデータで分析するのもいいかもしれません.

3.1. データの確認

# require(tidyverse)
# データ読み込み
search_console_dat <- readxl::read_excel('自分のブログ_Performance-on-Search-2020-06-06.xlsx')

search_console_dat %>%
    mutate(検索キーワード = reorder(検索キーワード, CTR)) %>%
    top_n(10, CTR) %>%
    ggplot(aes(x = as.factor(検索キーワード), y = CTR)) +
    geom_bar(stat = "identity") +
    xlab("検索クエリ") +
    ylab("クリック率") +
    coord_flip() + 
    ggtitle("クリック率上位10件の検索クエリ")

3.2. 前処理

次に前処理として, 検索クエリをキーワード単位でベクトル化します.

# 検索クエリ内に現れるキーワードをリスト化
words_in_query <- search_console_dat$検索キーワード %>%
    strsplit(" ") %>%
    unlist() %>%
    unique()

wordlist_in_query <- search_console_dat$検索キーワード %>%
    lapply(function(str) as.numeric(str_detect(str, words_in_query)))

# を列とし, 各検索キーワードを行とする行列
# 各行の検索キーワードがある列に対応する単語を含む場合1, そうでなければ0
word_in_query <- rlang::exec(rbind, !!!wordlist_in_query) 
colnames(word_in_query) <- words_in_query

count_word_in_query <- as_tibble(word_in_query) %>%
    add_column(Imp = search_console_dat$表示回数, .before = 1) %>%
    add_column(click = search_console_dat$クリック数, .before = 1)

3.3 パラメータ推定

それでは実際にパラメータ推定を行います. 今回はLasso推定を実際に試してみます. Lasso回帰を行うには, glmnet::glmnet関数, もしくはglmnet::cv.glmnet関数を利用します. 特に, glmnet::cv.glmnet関数では罰則項の大きさを指定するパラメータまで交差検証により 自動で推定が行われます.

# see https://cran.r-project.org/web/packages/glmnet/vignettes/glmnet.pdf
require(glmnet)
imp <- search_console_dat$表示回数
click <- search_console_dat$クリック数

# 交差検証により自動でlambdaを調整してくれる
fit_lasso.cv <- cv.glmnet(x = as.matrix(count_word_in_query[,-c(1:2)]), 
                          y = cbind(imp-click, click), 
                          nfolds = 4, family = "binomial", alpha=1)

glmnet::cv.glmnetの引数の意味は以下の通りです

  • x:説明変数(matrixで指定する)

  • y:目的変数

  • nfolds:交差検証の分割数

  • family:回帰モデルの指定("gaussian", "binomial", "poisson", "multinomial", "cox", "mgaussian"のいずれかが指定できる)

  • alpha:罰則項の形を決定する. 具体的な形は\alpha ||\beta||_1 + (1-\alpha)||\beta||^2_2 / 2となる.

3.4 推定結果の確認

最後に推定結果の確認を行います.

plot(fit_lasso.cv)

coef(fit_lasso.cv, s="lambda.min") %>% 
    broom::tidy() %>%
    mutate(row = reorder(row, value)) %>%
    ggplot(aes(x = as.factor(row), y = value)) +
    geom_bar(stat = "identity") +
    xlab("検索キーワード") +
    ylab("回帰係数の推定値") +
    coord_flip() 

注目すべきキーワードとして「mac」や「catalina」といったPCのOSに関するキーワードが 回帰係数が大きく, 高クリック率に寄与するという点が挙げられます.

このブログのようなプログラミングに関する内容のサイトでは, OSキーワードを記事に含めることで競合サイトが減り, 結果クリック率が上がるのかもしれません.

f:id:kimigayoseishou:20200610133119p:plain
Lasso推定による回帰係数の推定結果