Guess-js という、Google Analytics のデータを元に、ページの先読みを行う、興味深いライブラリがあります。
guess-js/guess: Libraries & tools for enabling Machine Learning driven user-experiences on the webREADME.mdに、以下のような記載があります。

Another approach that could be taken (which is simpler) is attempting to get accurate prediction data from the Google Analytics API. If you ran a report for the Page and Previous Page Path dimension combined with the Pageviews and Exits metrics this should provide enough data to wire up prefetches for most popular pages.

メトリクス ga:pageviews、ga:exits と、 ディメンション ga:pagePath、ga:previousPagePath を取得したレポートの情報で、
ページの先読みに必要な情報は事足りていそうで、実際 guess-js の先読みデータはこのデータが使われています。
このレポートのメトリクス、ディメンションを参考にして、Python でデータを取得して、同じようなデータを作れないか試してみました。
以下、実施したことを記載します。


前提

  • OS

    % sw_vers
    ProductName:  Mac OS X
    ProductVersion: 10.13.6
    BuildVersion: 17G3025
    

  • Python の Version

    % python3 -V
    Python 3.6.5
    

  • 必要なライブラリ
    GoogleAnalytics のデータ取得には、Google2Pandas を使用しています。
    Google2Pandas の使い方は以下記事で説明していますので、よろしければご確認ください。
    Google2Pandas で、Google Analytics のデータを pandas Dataframe に変換する | Monotalk
    また、あまりちゃんと記載をちゃんとしていないですが、API 認証 は サービスアカウントでの認証を行っています。
    以下の記事にサービスアカウントの作成手順が記載されていますので、アカウントがない場合はご確認ください。
    初心者でも分かる!なGoogle Analytics APIの使い

レポートの取得

メトリクス ga:pageviews、ga:exits と、 ディメンション ga:pagePath、ga:previousPagePath を指定し、データを取得します。

データフレームの取得

条件を指定して、データフレームを取得します。

from google2pandas import *
view_id = 'YOUR_VIEW_ID'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '180daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}, 
            {'name' : 'ga:previousPagePath'},
        ],
        'metrics'   : [
            {'expression' : 'ga:pageviews'},
            {'expression' : 'ga:exits'},
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)
df

pagePathpreviousPagePathpageviewsexits
0/(entrance)1009753
1//14156
2//?page=1810
3//?page=261
4//about/288
5//amp/blog/amp-start-の-blog-テーマは内部でどんなcss-を使ってい...11
6//amp/blog/Continuing-technical-blogging-with-V...22
7//amp/blog/django-rest-framework-でserializer-をネ...10
8//amp/blog/github-page-を-gatsby-で構築する/10
9//amp/blog/google-モバイルサイト認定を取得してみました/?__twitter...11
10//blog/AB-test-tool-Web-personalization-tool-RT...20
11//blog/About-statistical-information-of-blog-po...41
12//blog/Add-bat-bot-of-ultimate-bad-bot-blocker-...21
13//blog/amp-roadshow-tokyo-2018-に参加しました/20
14//blog/amp-の-update-cache-要求を-apikeypub-を使用して送っ...11
15//blog/apache-wicketでrestapiを使う/10
16//blog/args4j-で-enumoptionhandler-を使う/10
17//blog/at-comfasterxmljacksondatabindexcunrecog...20
18//blog/author/monotalk/?page=1911
19//blog/Block-multiple-requests-of-Wicket-Ajax/11
20//blog/Calculate-coefficient-of-variation-with-...51
21//blog/Calculate-hypergeometric-distribution-wi...11
22//blog/Calculate-inequality-index-in-python/21
23//blog/Calculate-polynomial-regression-with-pyt...40
24//blog/Calculate-the-F-distribution-with-python/20
25//blog/Calculate-the-interquartile-range-with-p...11
26//blog/Calculate-the-previous-term-growth-rate-...50
27//blog/Calculate-the-probability-of-binomial-di...21
28//blog/Calculate-uniform-distribution-in-Python/21
29//blog/category/google-tag-manager/11
...............
4516/translate_c?depth=1&hl=en&prev=search&rurl=tr.../translate_c?depth=1&hl=en&prev=search&rurl=tr...11
4517/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)11
4518/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)11
4519/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)22
4520/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)11
4521/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)11
4522/translate_c?depth=1&hl=en&prev=search&rurl=tr...(entrance)11
4523/translate_c?depth=1&hl=en&rurl=translate.goog...(entrance)11
4524/translate_c?depth=1&hl=en&rurl=translate.goog...(entrance)11
4525/translate_c?depth=1&hl=en&rurl=translate.goog...(entrance)11
4526/translate_c?depth=1&hl=es&prev=search&rurl=tr...(entrance)10
4527/translate_c?depth=1&hl=es&prev=search&rurl=tr.../translate_c?depth=1&hl=es&prev=search&rurl=tr...11
4528/translate_c?depth=1&hl=es&prev=search&rurl=tr...(entrance)11
4529/translate_c?depth=1&hl=es&prev=search&rurl=tr...(entrance)11
4530/translate_c?depth=1&hl=fr&prev=search&rurl=tr...(entrance)11
4531/translate_c?depth=1&hl=hu&prev=search&rurl=tr...(entrance)11
4532/translate_c?depth=1&hl=ja&ie=UTF8&prev=_t&rur...(entrance)11
4533/translate_c?depth=1&hl=ko&prev=search&rurl=tr...(entrance)11
4534/translate_c?depth=1&hl=ko&prev=search&rurl=tr...(entrance)10
4535/translate_c?depth=1&hl=ko&prev=search&rurl=tr...(entrance)11
4536/translate_c?depth=1&hl=ko&prev=search&rurl=tr...(entrance)11
4537/translate_c?depth=1&hl=ko&rurl=translate.goog.../translate_c?anno=2&depth=1&hl=ko&rurl=transla...11
4538/translate_c?depth=1&hl=pt-BR&prev=search&rurl...(entrance)11
4539/translate_c?depth=1&hl=te&nv=1&prev=search&ru...(entrance)11
4540/translate_c?depth=1&hl=zh-CN&prev=search&rurl...(entrance)11
4541/translate_c?depth=1&hl=zh-CN&prev=search&rurl...(entrance)10
4542/translate_c?depth=1&hl=zh-CN&prev=search&rurl.../translate_c?depth=1&hl=zh-CN&prev=search&rurl...10
4543/translate_c?depth=1&hl=zh-CN&prev=search&rurl...(entrance)11
4544/translate_c?depth=1&hl=zh-CN&rurl=translate.g.../translate_c?anno=2&depth=1&hl=zh-CN&rurl=tran...10
4545/translate_c?depth=1&hl=zh-TW&prev=search&rurl...(entrance)11

4546 rows × 4 columns

基本統計量の算出

データが多すぎてよくわからないので、基本統計量を算出します。

# 型変換
import numpy as np
df['exits'] = df['exits'].astype(np.int64)
df['pageviews'] = df['pageviews'].astype(np.int64)
df.describe()

pageviewsexits
count4546.0000004546.000000
mean29.20523524.223053
std149.843488130.766785
min1.0000000.000000
25%1.0000000.000000
50%1.0000001.000000
75%5.0000004.000000
max4970.0000004403.000000

基本統計量と、各属性値の関係から読み取れること

当たり前の話ですが基本統計量と、属性値から以下のことが読み取れるかと思います。

  • 50%以上の pageview数は1
  • 50%以上の 離脱数は1
  • previousPagePath が (entrance) は、前のページがないことを意味する。 ※ pagePath が流入ページになっている。
  • exits < pageviews となるのは、対象の pagePath から次のページへ移動した人がいるため。

データの加工

次ページの予測という観点で、以下のデータは除外してよいかと思いました。

  • previousPagePath が (entrance)データ
  • pageViewがある閾値に満たないデータ ※先読みをしても恩恵を受けられる人が少ないための足切り

まず、previousPagePath が (entrance)データを除外します。

# previousPagePath が `(entrance)` のデータを除外
df_excluded_entrance = df[df['previousPagePath'] != '(entrance)']
df_excluded_entrance

pagePathpreviousPagePathpageviewsexits
1//14156
2//?page=1810
3//?page=261
4//about/288
5//amp/blog/amp-start-の-blog-テーマは内部でどんなcss-を使ってい...11
6//amp/blog/Continuing-technical-blogging-with-V...22
7//amp/blog/django-rest-framework-でserializer-をネ...10
8//amp/blog/github-page-を-gatsby-で構築する/10
9//amp/blog/google-モバイルサイト認定を取得してみました/?__twitter...11
10//blog/AB-test-tool-Web-personalization-tool-RT...20
11//blog/About-statistical-information-of-blog-po...41
12//blog/Add-bat-bot-of-ultimate-bad-bot-blocker-...21
13//blog/amp-roadshow-tokyo-2018-に参加しました/20
14//blog/amp-の-update-cache-要求を-apikeypub-を使用して送っ...11
15//blog/apache-wicketでrestapiを使う/10
16//blog/args4j-で-enumoptionhandler-を使う/10
17//blog/at-comfasterxmljacksondatabindexcunrecog...20
18//blog/author/monotalk/?page=1911
19//blog/Block-multiple-requests-of-Wicket-Ajax/11
20//blog/Calculate-coefficient-of-variation-with-...51
21//blog/Calculate-hypergeometric-distribution-wi...11
22//blog/Calculate-inequality-index-in-python/21
23//blog/Calculate-polynomial-regression-with-pyt...40
24//blog/Calculate-the-F-distribution-with-python/20
25//blog/Calculate-the-interquartile-range-with-p...11
26//blog/Calculate-the-previous-term-growth-rate-...50
27//blog/Calculate-the-probability-of-binomial-di...21
28//blog/Calculate-uniform-distribution-in-Python/21
29//blog/category/google-tag-manager/11
30//blog/category/java/10
...............
4477/statistics//blog/Draw-a-correlogram-with-statsmodels/20
4478/statistics//blog/Draw-a-stem-leaf-diagram-with-python-ste...10
4479/statistics//blog/Find-Bayesian-confidence-intervals-in-sc...10
4480/statistics//blog/How-to-use-the-sort-method-of-Google-App...11
4481/statistics//blog/mezzanine-blogに/11
4482/statistics//blog/mezzanine-フロクの記事公開日の日付フォーマットを変更する/10
4483/statistics//blog/Perform-independence-test-and-calculatio...10
4484/statistics//blog/Predict-future-impressions-with-Google-S...11
4485/statistics//blog/Python-implements-statistical-test-metho...11
4486/statistics//blog/pythonでポアソン分布の計算をする/41
4487/statistics//blog/sonarqube-nodejs-に依存しないfrontend-lint-環境を...10
4488/statistics//blog/usage-of-django-compress-on-mezzanine/10
4489/statistics//blog/wagtail-markdown-field-を使ってみる/10
4490/statistics//categories/166
4491/statistics//ja/staistics/22
4492/statistics//search/?q=&type=blog.BlogPost10
4493/statistics//statistics/134
4494/translate_c?act=url&depth=1&hl=en&ie=UTF8&pre.../translate_c?act=url&depth=1&hl=en&ie=UTF8&pre...11
4495/translate_c?act=url&depth=1&hl=en&ie=UTF8&pre.../translate_c?act=url&depth=1&hl=en&ie=UTF8&pre...10
4498/translate_c?act=url&depth=1&hl=en&ie=UTF8&pre.../translate_c?act=url&depth=1&hl=en&ie=UTF8&pre...11
4501/translate_c?anno=2&depth=1&hl=en&rurl=transla.../translate_c?depth=1&hl=en&prev=search&rurl=tr...11
4504/translate_c?anno=2&depth=1&hl=ko&nv=1&rurl=tr.../translate_c?anno=2&depth=1&hl=ko&nv=1&rurl=tr...11
4506/translate_c?anno=2&depth=1&hl=ko&rurl=transla.../translate_c?depth=1&hl=ko&prev=search&rurl=tr...11
4508/translate_c?anno=2&depth=1&hl=zh-CN&rurl=tran.../translate_c?depth=1&hl=zh-CN&prev=search&rurl...10
4509/translate_c?anno=2&depth=1&hl=zh-CN&rurl=tran.../translate_c?depth=1&hl=zh-CN&rurl=translate.g...11
4516/translate_c?depth=1&hl=en&prev=search&rurl=tr.../translate_c?depth=1&hl=en&prev=search&rurl=tr...11
4527/translate_c?depth=1&hl=es&prev=search&rurl=tr.../translate_c?depth=1&hl=es&prev=search&rurl=tr...11
4537/translate_c?depth=1&hl=ko&rurl=translate.goog.../translate_c?anno=2&depth=1&hl=ko&rurl=transla...11
4542/translate_c?depth=1&hl=zh-CN&prev=search&rurl.../translate_c?depth=1&hl=zh-CN&prev=search&rurl...10
4544/translate_c?depth=1&hl=zh-CN&rurl=translate.g.../translate_c?anno=2&depth=1&hl=zh-CN&rurl=tran...10

3455 rows × 4 columns

再度、基本統計量を計算します。

df_excluded_entrance.describe()

pageviewsexits
count3455.0000003455.000000
mean6.4726484.223444
std26.57835819.022794
min1.0000000.000000
25%1.0000000.000000
50%1.0000001.000000
75%2.0000001.000000
max674.000000538.000000

続いて、pageViewがある閾値に満たないデータを除外します。
pandas で、previousPagePath で groupby して、previousPagePath ごとの pageview の合計を算出します。

df_groupby_pagepath = df_excluded_entrance.groupby('previousPagePath').sum()
df_groupby_pagepath

pageviewsexits
previousPagePath
/641254
/?page= 220
/?page= 310
/?page= 411
/?page=151
/?page=1010
/?page=1120
/?page=1210
/?page=1330
/?page=1410
/?page=1521
/?page=1610
/?page=1710
/?page=1810
/?page=25312
/?page=3175
/?page=4114
/?page=5113
/?page=641
/?page=740
/?page=821
/?page=920
/about/9134
/amp/blog/10
/amp/blog/404_errorpage_configration_on_wicket_dropwizard/11
/amp/blog/AB-test-tool-Web-personalization-tool-RTP-Website-Optimization/21
/amp/blog/About-formulas-in-Google-Spreadsheet-for-calculating-basic-statistics/65
/amp/blog/About-searching-and-completing-a-string-in-Google-Spread-Sheet/11
/amp/blog/About-statistical-information-of-blog-posts-recorded-as-custom-dimensions-and-events/71
/amp/blog/Calculate-coefficient-of-variation-with-python-scipy-and-numpy/63
.........
/search/?q=標準得点+変動係数&type=10
/search/?q=正規分布&type=11
/search/?q=目次&type=11
/search/?q=移動平均&type=20
/search/?q=統計情報&type=10
/search/?q=統計量&type=10
/search/?q=継承&type=20
/search/?q=著者&type=10
/search/?q=項分布&type=20
/search?q=cache:6Hj2PNT7p_IJ:https://www.monotalk.xyz/blog/elasticsearch-の-kuromoji-plugin-が削除されてindexclosedexceptionが発生する/+&cd=1&hl=ja&ct=clnk&gl=jp11
/search?q=cache:AtYTm8CqpCIJ:https://www.monotalk.xyz/blog/cent-os-69-に-memcached-をインストールログの設定まで実施する/+&cd=1&hl=ja&ct=clnk&gl=jp11
/search?q=cache:R029jladBYkJ:https://www.monotalk.xyz/blog/beautifulsoup-て-style-タクscript-タクstyle-属性を除去する/+&cd=8&hl=ja&ct=clnk&gl=jp11
/search?q=cache:bdtGTPNBilkJ:https://www.monotalk.xyz/blog/bootstraps-javascript-requires-jquery-version-191-エラーについて/+&cd=1&hl=ja&ct=clnk&gl=jp41
/search?q=cache:https://www.monotalk.xyz/blog/pythonで相関係数の計算をする/&rlz=1C1GCEU_jaJP821JP821&oq=cache:https://www.monotalk.xyz/blog/pythonで相関係数の計算をする/&aqs=chrome..69i57j69i58.959j0j4&sourceid=chrome&ie=UTF-811
/search?q=cache:lH1xzlsJJLQJ:https://www.monotalk.xyz/blog/content-security-policy-適用後の経過を観察する-2017年11月/+&cd=7&hl=ja&ct=clnk&gl=jp&client=firefox-b11
/search?q=cache:tiQbVsjpKwsJ:https://www.monotalk.xyz/blog/django-runserver-実行時にログを全部出しする/+&cd=3&hl=ja&ct=clnk&gl=jp11
/staistics/22
/statistics/6610
/translate_c?act=url&depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&sl=auto&sp=nmt4&tl=en&u=https://www.monotalk.xyz/&xid=17259,15700023,15700124,15700149,15700168,15700186,15700191,15700201,15700208&usg=ALkJrhjtOYOh8APBIMaYgzAUfYz7hDqWHA11
/translate_c?act=url&depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&sl=auto&sp=nmt4&tl=en&u=https://www.monotalk.xyz/blog/Draw-a-boxplot-with-data from-Google-Search-Console/&xid=17259,15700023,15700124,15700149,15700168,15700186,15700191,15700201,15700208&usg=ALkJrhj0yJX0Khr0Rv31gEvlN8iAql4H-w10
/translate_c?act=url&depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&sl=auto&sp=nmt4&tl=fr&u=https://www.monotalk.xyz/blog/Error-A-partial-update-is-not-possible-for-a-component-that-has-renderBodyOnly-enabled-on-Wicket/&xid=17259,15700023,15700043,15700124,15700149,15700168,15700173,15700186,15700190,15700201&usg=ALkJrhi-6s44aa2jCIG84k0JJU58sEABOA11
/translate_c?anno=2&depth=1&hl=ko&nv=1&rurl=translate.google.co.kr&sl=ja&sp=nmt4&tl=ko&u=https://www.monotalk.xyz/blog/sitespeedio-の-coach-を使って-webページのパフォーマンスを評価する/&xid=25657,15700022,15700122,15700124,15700149,15700168,15700186,15700190,15700201,15700208&usg=ALkJrhhUks2_n920PQOioH83LWYNTzJmuQ11
/translate_c?anno=2&depth=1&hl=ko&rurl=translate.google.co.kr&sl=ja&sp=nmt4&tl=ko&u=https://www.monotalk.xyz/blog/sitespeedio-の-coach-を使って-webページのパフォーマンスを評価する/&xid=17259,15700002,15700023,15700124,15700149,15700168,15700186,15700190,15700201,15700208&usg=ALkJrhgMhHmycL10zo9Z4Wmm-gap-B80jQ11
/translate_c?anno=2&depth=1&hl=zh-CN&rurl=translate.google.com.hk&sl=ja&sp=nmt4&tl=zh-CN&u=https://www.monotalk.xyz/blog/google-analytics-v4-api-java-pageview-per-url/&xid=17259,15700023,15700124,15700149,15700186,15700190,15700201&usg=ALkJrhh31NVtSiKXSwz4dLCXo80kP3JyMA10
/translate_c?depth=1&hl=en&prev=search&rurl=translate.google.co.jp&sl=ja&sp=nmt4&u=https://www.monotalk.xyz/blog/google-app-script-の-urlfetchapp-の-例外ハンドリングについて/&xid=17259,1500004,15700019,15700124,15700149,15700186,15700190,15700201,15700214&usg=ALkJrhjyOtARNK8ZqludO98LMoYLY0SEGg11
/translate_c?depth=1&hl=en&prev=search&rurl=translate.google.co.jp&sl=ja&sp=nmt4&u=https://www.monotalk.xyz/blog/検索キーワードの共起ネットワーク図を-cytoscape-で描画する/&xid=17259,15700023,15700124,15700149,15700186,15700190,15700201,15700214&usg=ALkJrhjmF9M06IEYQoCF3xAvbcUOJvGwbw11
/translate_c?depth=1&hl=es&prev=search&rurl=translate.google.com.mx&sl=ja&sp=nmt4&u=https://www.monotalk.xyz/blog/uses-a-non-entity-orgeclipsepersistenceexceptionsvalidationexception/&xid=17259,15700022,15700124,15700149,15700186,15700190,15700201,15700214&usg=ALkJrhhKlkTy_PBGLPcBDW0qrLjG4VV_bg11
/translate_c?depth=1&hl=ko&prev=search&rurl=translate.google.co.kr&sl=ja&sp=nmt4&u=https://www.monotalk.xyz/blog/sitespeedio-の-coach-を使って-webページのパフォーマンスを評価する/&xid=17259,15700019,15700124,15700149,15700168,15700186,15700191,15700201,15700208&usg=ALkJrhhjVd65VmIk-4SEPx_4rg1QM0zYyA11
/translate_c?depth=1&hl=zh-CN&prev=search&rurl=translate.google.com.hk&sl=ja&sp=nmt4&u=https://www.monotalk.xyz/blog/google-analytics-v4-api-java-pageview-per-url/&xid=17259,15700023,15700124,15700149,15700186,15700190,15700201&usg=ALkJrhgCFfDlxZvmrkmM26kKrdPhJ2ertQ20
/translate_c?depth=1&hl=zh-CN&rurl=translate.google.com.hk&sl=ja&sp=nmt4&tl=zh-CN&u=https://www.monotalk.xyz/blog/google-analytics-v4-api-java-pageview-per-url/&xid=17259,15700023,15700124,15700149,15700186,15700190,15700201&usg=ALkJrhgiPDNYKGwelQJoT8KHqsIkYRUY_w11

929 rows × 2 columns

基本統計量を算出します。

df_groupby_pagepath.describe()

pageviewsexits
count929.000000929.000000
mean24.07212115.707212
std62.86651341.896814
min1.0000000.000000
25%1.0000001.000000
50%5.0000002.000000
75%19.00000012.000000
max707.000000559.000000

ヒストグラムを描画してみます。

%matplotlib inline
ax = df_groupby_pagepath.plot(y='exits', bins=50, alpha=0.5, figsize=(16,4), kind='hist')
df_groupby_pagepath.plot( y='pageviews', bins=50, alpha=0.5, figsize=(16,4), kind='hist',ax=ax)

<matplotlib.axes._subplots.AxesSubplot at 0x112ca7048>

png

ほとんどのページが、15-20 PageView 以下 であることがわかります。
累積度数もプロットしたグラフを描いてみます。

import pandas as pd
df_pareto = pd.DataFrame(df_groupby_pagepath.groupby("pageviews").size())
df_pareto = df_pareto.sort_values(by="pageviews", ascending=True)
df_pareto.columns = ['count']
df_pareto["cumsum_pageview"] = np.cumsum(df_pareto["count"] * df_pareto.index)
df_pareto["cumsum_pageview_percent"] = df_pareto["cumsum_pageview"] / sum(df_pareto.index * df_pareto['count']) * 100
df_pareto["cumsum_count"] = np.cumsum(df_pareto["count"])
df_pareto["cumsum_count_percent"] = df_pareto["cumsum_count"] / sum(df_pareto['count']) * 100
df_pareto

countcumsum_pageviewcumsum_pageview_percentcumsum_countcumsum_count_percent
pageviews
12582581.15369125827.771798
21104782.13745936839.612487
3516312.82162541945.102260
4427993.57286646149.623251
5319544.26597549252.960172
62811225.01721652055.974166
73113395.98756955159.311087
81214356.41684956360.602799
92216337.30224058562.970936
101417737.92827459964.477933
112019938.91204261966.630786
121321499.60962363268.030140
1311229210.24907264369.214209
1410243210.87510665370.290635
1514264211.81415766771.797632
169278612.45807867672.766416
1712299013.37029968874.058127
186309813.85324069474.703983
1910328814.70285770475.780409
2011350815.68662571576.964478
215361316.15615172077.502691
2211385517.23829573178.686760
233392417.54684173479.009688
244402017.97612173879.440258
256417018.64687274480.086114
261419618.76313674580.193757
273427719.12534174880.516685
285441719.75137575381.054898
294453320.27008975781.485468
305468320.94084076282.023681
..................
13921359260.77896589996.770721
14711373961.43630190096.878364
15021403962.77780390297.093649
15311419263.46196890397.201292
15411434664.15060690497.308934
16011450664.86607390597.416577
16411467065.59942890697.524220
16611483666.34172590797.631862
16911500567.09743890897.739505
17211517767.86656590997.847147
17511535268.64910891097.954790
18611553869.48083991198.062433
18911572770.32598591298.170075
19711592471.20690491398.277718
19911612372.09676791498.385361
20411632773.00898891598.493003
20811653573.93909691698.600646
22111675674.92733591798.708288
25811701476.08102791898.815931
28911730377.37334091998.923574
32811763178.84004892099.031216
34611797780.38724792199.138859
37411835182.05965292299.246502
45711880884.10320692399.354144
49111929986.29879792499.461787
51311981288.59276592599.569429
53312034590.97616692699.677072
64112098693.84250892799.784715
67012165696.83852892899.892357
707122363100.000000929100.000000

126 rows × 5 columns

import matplotlib.pyplot as plt
fig, ax1 = plt.subplots(figsize=(15,8))
data_num = len(df_pareto)

ax1.bar(range(data_num), df_pareto["count"])
ax1.set_xticks(range(data_num))
ax1.set_xticklabels(df_pareto.index.tolist())
ax1.set_xlabel("label")
ax1.set_ylabel("counts")

ax2 = ax1.twinx()
ax2.plot(range(data_num), df_pareto["cumsum_count_percent"], c="k", marker="o")
ax2.set_ylim([0, 100])
ax2.grid(True, which='both', axis='y')
ax3 = ax1.twinx()
ax3.plot(range(data_num), df_pareto["cumsum_pageview_percent"], c="k", marker="x")
ax3.set_ylim([0, 100])
ax3.grid(True, which='both', axis='y')
ax1.set_title("Cumulativefrequency Graph")
plt.show()

png

全体の20%のページのPageViewが80% を占めていそうな雰囲気です。
PageView の閾値は80%点を指定します。


データ取得、加工までのスクリプトをまとめる

以下、データ取得、加工まで行うスクリプトをまとめます。

# ----------------
#  データ取得
# --------
from google2pandas import *
view_id = 'YOUR_VIEW_ID'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '180daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}, 
            {'name' : 'ga:previousPagePath'},
        ],
        'metrics'   : [
            {'expression' : 'ga:pageviews'},
            {'expression' : 'ga:exits'},
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)

# ----------------
#  # 型変換
# --------
import numpy as np
df['exits'] = df['exits'].astype(np.int64)
df['pageviews'] = df['pageviews'].astype(np.int64)

# ----------------
#  データの加工
# --------

## データ抽出
# previousPagePath が `(entrance)` のデータを除外
df_excluded_entrance = df[df['previousPagePath'] != '(entrance)']
# previousPagePath ごとの合計を算出
df_groupby_pagepath = df_excluded_entrance.groupby('previousPagePath').sum()
# 上位20%のデータのみ抽出する
import pandas as pd
df_cutback = df_groupby_pagepath[df_groupby_pagepath['pageviews'] > df_groupby_pagepath.quantile(0.80)["pageviews"]]
df_edited = df_excluded_entrance[df_excluded_entrance['previousPagePath'].isin(df_cutback.index.tolist())]

## 元データに対して処理を行い、最終的なアウトプットへ加工する
page_grouped = df_edited.groupby(["previousPagePath","pagePath"]).sum()
del page_grouped["exits"]
page_grouped['pageview_percent'] = page_grouped.groupby(level=0).apply(lambda x: 100 * x / float(x.sum()))['pageviews']
page_grouped = page_grouped.reset_index()
page_grouped = page_grouped[(page_grouped['pageview_percent']  >= 10) & ~(page_grouped['previousPagePath'] == page_grouped['pagePath'])]

# pandas での編集結果を辞書にする    
record_dicts = page_grouped.to_dict(orient="records")
result_dict = {}
for record_dict in record_dicts:
    dict_list = result_dict.get(record_dict.get("previousPagePath"), [])
    dict_list.append(record_dict)
    result_dict.update({record_dict.get("previousPagePath") : dict_list})

result_dict

WARNING:googleapiclient.discovery_cache:file_cache is unavailable when using oauth2client >= 4.0.0
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery_cache/__init__.py", line 36, in autodetect
    from google.appengine.api import memcache
ModuleNotFoundError: No module named 'google.appengine'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery_cache/file_cache.py", line 33, in <module>
    from oauth2client.contrib.locked_file import LockedFile
ModuleNotFoundError: No module named 'oauth2client.contrib.locked_file'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery_cache/file_cache.py", line 37, in <module>
    from oauth2client.locked_file import LockedFile
ModuleNotFoundError: No module named 'oauth2client.locked_file'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery_cache/__init__.py", line 41, in autodetect
    from . import file_cache
  File "/usr/local/lib/python3.6/site-packages/googleapiclient/discovery_cache/file_cache.py", line 41, in <module>
    'file_cache is unavailable when using oauth2client >= 4.0.0')
ImportError: file_cache is unavailable when using oauth2client >= 4.0.0





{'/?page=2': [{'pagePath': '/',
   'pageview_percent': 11.320754716981131,
   'pageviews': 6,
   'previousPagePath': '/?page=2'},
  {'pagePath': '/?page=3',
   'pageview_percent': 43.39622641509434,
   'pageviews': 23,
   'previousPagePath': '/?page=2'}],
 '/about/': [{'pagePath': '/',
   'pageview_percent': 30.76923076923077,
   'pageviews': 28,
   'previousPagePath': '/about/'},
  {'pagePath': '/categories/',
   'pageview_percent': 19.78021978021978,
   'pageviews': 18,
   'previousPagePath': '/about/'},
  {'pagePath': '/statistics/',
   'pageview_percent': 10.989010989010989,
   'pageviews': 10,
   'previousPagePath': '/about/'}],
 '/amp/blog/google-analytics-のテータを-python-て-アソシエーション分析-する/': [{'pagePath': '/blog/mezzanine-の-blog-に-関連記事-のレコメンド表示を組み込んでみる/',
   'pageview_percent': 15.625,
   'pageviews': 5,
   'previousPagePath': '/amp/blog/google-analytics-のテータを-python-て-アソシエーション分析-する/'}],
 '/blog/Block-multiple-requests-of-Wicket-Ajax/': [{'pagePath': '/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/',
   'pageview_percent': 10.0,
   'pageviews': 4,
   'previousPagePath': '/blog/Block-multiple-requests-of-Wicket-Ajax/'},
  {'pagePath': '/blog/search-resutls-wicket-forms/',
   'pageview_percent': 12.5,
   'pageviews': 5,
   'previousPagePath': '/blog/Block-multiple-requests-of-Wicket-Ajax/'},
  {'pagePath': '/blog/wicket-ajax処理-を並列に動作させる/',
   'pageview_percent': 12.5,
   'pageviews': 5,
   'previousPagePath': '/blog/Block-multiple-requests-of-Wicket-Ajax/'}],
 '/blog/Calculate-coefficient-of-variation-with-python-scipy-and-numpy/': [{'pagePath': '/',
   'pageview_percent': 14.705882352941176,
   'pageviews': 5,
   'previousPagePath': '/blog/Calculate-coefficient-of-variation-with-python-scipy-and-numpy/'}],
 '/blog/Calculate-the-probability-of-binomial-distribution-with-python/': [{'pagePath': '/blog/pythonでポアソン分布の計算をする/',
   'pageview_percent': 12.612612612612613,
   'pageviews': 14,
   'previousPagePath': '/blog/Calculate-the-probability-of-binomial-distribution-with-python/'}],
 '/blog/Continuing-technical-blogging-with-VPS-for-3-years-what-got-lost-what-is-going-on-now/': [{'pagePath': '/',
   'pageview_percent': 33.333333333333336,
   'pageviews': 18,
   'previousPagePath': '/blog/Continuing-technical-blogging-with-VPS-for-3-years-what-got-lost-what-is-going-on-now/'}],
 '/blog/Default-FindBugs-Rules-In-Github-Repositories/': [{'pagePath': '/blog/Default-PMD-Rules-In-Github-Repositories/',
   'pageview_percent': 21.311475409836067,
   'pageviews': 13,
   'previousPagePath': '/blog/Default-FindBugs-Rules-In-Github-Repositories/'}],
 '/blog/Default-PMD-Rules-In-Github-Repositories/': [{'pagePath': '/blog/pmd-rulesetの一覧java/',
   'pageview_percent': 49.6124031007752,
   'pageviews': 64,
   'previousPagePath': '/blog/Default-PMD-Rules-In-Github-Repositories/'}],
 '/blog/Draw-a-correlogram-with-statsmodels/': [{'pagePath': '/',
   'pageview_percent': 14.285714285714286,
   'pageviews': 4,
   'previousPagePath': '/blog/Draw-a-correlogram-with-statsmodels/'}],
 '/blog/Get-Google-trend-data-with-pytrends/': [{'pagePath': '/blog/Merge-Google-Trend-results-with-pytrends/',
   'pageview_percent': 18.83116883116883,
   'pageviews': 29,
   'previousPagePath': '/blog/Get-Google-trend-data-with-pytrends/'}],
 "/blog/Implement-Paging-with-Elasticsearch-Java-Client's-SearchTemplateRequestBuilder/": [{'pagePath': '/blog/macos-el-capitan-に-elasticsearch-を-インストールしてjava-クライアントから検索してみる/',
   'pageview_percent': 12.76595744680851,
   'pageviews': 6,
   'previousPagePath': "/blog/Implement-Paging-with-Elasticsearch-Java-Client's-SearchTemplateRequestBuilder/"}],
 '/blog/Python-implements-statistical-test-method-that-can-be-used-for-AB-test/': [{'pagePath': '/',
   'pageview_percent': 12.244897959183673,
   'pageviews': 6,
   'previousPagePath': '/blog/Python-implements-statistical-test-method-that-can-be-used-for-AB-test/'}],
 '/blog/TEMPLATE_DEBUG-on-Djnago1.8/': [{'pagePath': '/blog/django-18からsettingspyのtemplatesが非推奨になって警告が出力される/',
   'pageview_percent': 18.51851851851852,
   'pageviews': 5,
   'previousPagePath': '/blog/TEMPLATE_DEBUG-on-Djnago1.8/'},
  {'pagePath': '/blog/django-runserver-実行時にログを全部出しする/',
   'pageview_percent': 18.51851851851852,
   'pageviews': 5,
   'previousPagePath': '/blog/TEMPLATE_DEBUG-on-Djnago1.8/'}],
 '/blog/The-data-of-the-site-operated-for-18-years-has-disappeared/': [{'pagePath': '/',
   'pageview_percent': 36.111111111111114,
   'pageviews': 13,
   'previousPagePath': '/blog/The-data-of-the-site-operated-for-18-years-has-disappeared/'},
  {'pagePath': '/blog/category/雑記/',
   'pageview_percent': 11.11111111111111,
   'pageviews': 4,
   'previousPagePath': '/blog/The-data-of-the-site-operated-for-18-years-has-disappeared/'}],
 '/blog/Try-Japanese-translation-of-rule-of-SonarQube/': [{'pagePath': '/blog/install-SonarQube-on-El-Capitan/',
   'pageview_percent': 68.29268292682927,
   'pageviews': 112,
   'previousPagePath': '/blog/Try-Japanese-translation-of-rule-of-SonarQube/'}],
 '/blog/Try-static-analysis-of-Python-using-SonarPython/': [{'pagePath': '/blog/install-SonarQube-on-El-Capitan/',
   'pageview_percent': 15.909090909090908,
   'pageviews': 14,
   'previousPagePath': '/blog/Try-static-analysis-of-Python-using-SonarPython/'}],
 '/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/': [{'pagePath': '/blog/Block-multiple-requests-of-Wicket-Ajax/',
   'pageview_percent': 15.151515151515152,
   'pageviews': 5,
   'previousPagePath': '/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/'},
  {'pagePath': '/blog/search-resutls-wicket-forms/',
   'pageview_percent': 24.242424242424242,
   'pageviews': 8,
   'previousPagePath': '/blog/Wicket-AjaxButton-Controls-behavior-when-an-error-occurs-onSubmit-method/'}],
 '/blog/With-python-statsmodel-calculate-the-verification-power-and-the-Sample-Size/': [{'pagePath': '/blog/Perform-python-analysis-of-variance/',
   'pageview_percent': 10.344827586206897,
   'pageviews': 6,
   'previousPagePath': '/blog/With-python-statsmodel-calculate-the-verification-power-and-the-Sample-Size/'}],
 '/blog/apache-wicketでrestapiを使う/': [{'pagePath': '/blog/rest-api-on-wicket7.3.0/',
   'pageview_percent': 55.172413793103445,
   'pageviews': 16,
   'previousPagePath': '/blog/apache-wicketでrestapiを使う/'}],
 '/blog/args4j-で-enumoptionhandler-を使う/': [{'pagePath': '/blog/args4j-条件付きチェックを実装する/',
   'pageview_percent': 34.04255319148936,
   'pageviews': 16,
   'previousPagePath': '/blog/args4j-で-enumoptionhandler-を使う/'},
  {'pagePath': '/blog/spring-boot-での-サブコマンドsubcommandsの実装案/',
   'pageview_percent': 25.53191489361702,
   'pageviews': 12,
   'previousPagePath': '/blog/args4j-で-enumoptionhandler-を使う/'}],
 '/blog/args4j-条件付きチェックを実装する/': [{'pagePath': '/blog/args4j-で-enumoptionhandler-を使う/',
   'pageview_percent': 51.851851851851855,
   'pageviews': 14,
   'previousPagePath': '/blog/args4j-条件付きチェックを実装する/'},
  {'pagePath': '/blog/spring-boot-での-サブコマンドsubcommandsの実装案/',
   'pageview_percent': 14.814814814814815,
   'pageviews': 4,
   'previousPagePath': '/blog/args4j-条件付きチェックを実装する/'}],
 '/blog/beatifulsoup4-で余分なhtmlタグbodyタグを除去する/': [{'pagePath': '/blog/beautifulsoup-て-style-タクscript-タクstyle-属性を除去する/',
   'pageview_percent': 67.6056338028169,
   'pageviews': 48,
   'previousPagePath': '/blog/beatifulsoup4-で余分なhtmlタグbodyタグを除去する/'}],
 '/blog/beautifulsoup-て-style-タクscript-タクstyle-属性を除去する/': [{'pagePath': '/blog/beatifulsoup4-で余分なhtmlタグbodyタグを除去する/',
   'pageview_percent': 21.333333333333332,
   'pageviews': 32,
   'previousPagePath': '/blog/beautifulsoup-て-style-タクscript-タクstyle-属性を除去する/'}],
 '/blog/category/mezzanine/': [{'pagePath': '/blog/category/mezzanine/?page=2',
   'pageview_percent': 15.625,
   'pageviews': 5,
   'previousPagePath': '/blog/category/mezzanine/'},
  {'pagePath': '/blog/django-で-amp-ページ-と-通常ページを振り分ける/',
   'pageview_percent': 15.625,
   'pageviews': 5,
   'previousPagePath': '/blog/category/mezzanine/'},
  {'pagePath': '/blog/djangomezzanine-templateにcritical-css-組み込む思索と施作-1/',
   'pageview_percent': 12.5,
   'pageviews': 4,
   'previousPagePath': '/blog/category/mezzanine/'},
  {'pagePath': '/blog/updated-from-mezzanine-4.2.3-to-4.3.0/',
   'pageview_percent': 12.5,
   'pageviews': 4,
   'previousPagePath': '/blog/category/mezzanine/'}],
 '/blog/category/雑記/': [{'pagePath': '/',
   'pageview_percent': 36.0,
   'pageviews': 18,
   'previousPagePath': '/blog/category/雑記/'},
  {'pagePath': '/blog/Continuing-technical-blogging-with-VPS-for-3-years-what-got-lost-what-is-going-on-now/',
   'pageview_percent': 10.0,
   'pageviews': 5,
   'previousPagePath': '/blog/category/雑記/'}],
 '/blog/cent-os-69-に-memcached-をインストールログの設定まで実施する/': [{'pagePath': '/blog/cent-os-74-に-memcached-をインストールログの設定まで実施する/',
   'pageview_percent': 58.96551724137931,
   'pageviews': 171,
   'previousPagePath': '/blog/cent-os-69-に-memcached-をインストールログの設定まで実施する/'}],
 '/blog/cent-os-69-上で稼働する-django-に-memcached-の-cache-設定をしてみる/': [{'pagePath': '/blog/cent-os-69-に-memcached-をインストールログの設定まで実施する/',
   'pageview_percent': 21.428571428571427,
   'pageviews': 6,
   'previousPagePath': '/blog/cent-os-69-上で稼働する-django-に-memcached-の-cache-設定をしてみる/'},
  {'pagePath': '/blog/centos-69-で稼働しているdjango-で-pylibmc-を使おうとして結構大変だった話/',
   'pageview_percent': 17.857142857142858,
   'pageviews': 5,
   'previousPagePath': '/blog/cent-os-69-上で稼働する-django-に-memcached-の-cache-設定をしてみる/'}],
 '/blog/cent-os-74-に-memcached-をインストールログの設定まで実施する/': [{'pagePath': '/blog/cent-os-69-に-memcached-をインストールログの設定まで実施する/',
   'pageview_percent': 63.13131313131313,
   'pageviews': 125,
   'previousPagePath': '/blog/cent-os-74-に-memcached-をインストールログの設定まで実施する/'}],
 '/blog/content-security-policy-適用後の経過を観察する-2017年11月/': [{'pagePath': '/blog/content-security-policy-csp-の-report-を-10-日くらい集計してポリシーを見直すの途中/',
   'pageview_percent': 17.24137931034483,
   'pageviews': 5,
   'previousPagePath': '/blog/content-security-policy-適用後の経過を観察する-2017年11月/'},
  {'pagePath': '/blog/content-security-policy-適用後の経過を観察する-2018年04月/',
   'pageview_percent': 24.137931034482758,
   'pageviews': 7,
   'previousPagePath': '/blog/content-security-policy-適用後の経過を観察する-2017年11月/'}],
 '/blog/control-error-message-by-component-on-wicket/': [{'pagePath': '/blog/search-resutls-wicket-forms/',
   'pageview_percent': 48.888888888888886,
   'pageviews': 44,
   'previousPagePath': '/blog/control-error-message-by-component-on-wicket/'}],
 '/blog/django-18からsettingspyのtemplatesが非推奨になって警告が出力される/': [{'pagePath': '/blog/TEMPLATE_DEBUG-on-Djnago1.8/',
   'pageview_percent': 20.0,
   'pageviews': 6,
   'previousPagePath': '/blog/django-18からsettingspyのtemplatesが非推奨になって警告が出力される/'},
  {'pagePath': '/blog/django-djangotemplateloaderscachedloader-について/',
   'pageview_percent': 13.333333333333334,
   'pageviews': 4,
   'previousPagePath': '/blog/django-18からsettingspyのtemplatesが非推奨になって警告が出力される/'}],
 '/blog/django-request-on-mezzanine/': [{'pagePath': '/blog/django-runserver-実行時にログを全部出しする/',
   'pageview_percent': 28.26086956521739,
   'pageviews': 13,
   'previousPagePath': '/blog/django-request-on-mezzanine/'}],
 '/blog/django-runserver-実行時にログを全部出しする/': [{'pagePath': '/blog/djangoのsettingspy内でloghandler-streamhandlerのログ出力先を指定する/',
   'pageview_percent': 23.280423280423282,
   'pageviews': 44,
   'previousPagePath': '/blog/django-runserver-実行時にログを全部出しする/'}],
 '/blog/elasticsearch-の-kuromoji-plugin-が削除されてindexclosedexceptionが発生する/': [{'pagePath': '/blog/macos-el-capitan-に-elasticsearch-を-インストールしてjava-クライアントから検索してみる/',
   'pageview_percent': 10.526315789473685,
   'pageviews': 4,
   'previousPagePath': '/blog/elasticsearch-の-kuromoji-plugin-が削除されてindexclosedexceptionが発生する/'}],
 '/blog/error-handling-on-wicket/': [{'pagePath': '/blog/delete-version-number-from-url-on-wicket/',
   'pageview_percent': 14.285714285714286,
   'pageviews': 5,
   'previousPagePath': '/blog/error-handling-on-wicket/'}],
 '/blog/google-analytics-の-時系列テータを-bokeh-て可視化する/': [{'pagePath': '/blog/bokeh-と-plotlyでヒストグラム-を描く/',
   'pageview_percent': 15.789473684210526,
   'pageviews': 6,
   'previousPagePath': '/blog/google-analytics-の-時系列テータを-bokeh-て可視化する/'},
  {'pagePath': '/blog/google-analytics-のテータを-python-てコレスホンテンス分析する/',
   'pageview_percent': 10.526315789473685,
   'pageviews': 4,
   'previousPagePath': '/blog/google-analytics-の-時系列テータを-bokeh-て可視化する/'}],
 '/blog/google-analytics-アフィニティ-カテゴリの英語の対訳を-bing-translate-api-で作成する/': [{'pagePath': '/blog/google-analytics-アフィニティカテゴリの日本語翻訳を返すpython-ファンクションを作成する/',
   'pageview_percent': 22.580645161290324,
   'pageviews': 7,
   'previousPagePath': '/blog/google-analytics-アフィニティ-カテゴリの英語の対訳を-bing-translate-api-で作成する/'}],
 '/blog/google-analytics-アフィニティカテゴリの日本語翻訳を返すpython-ファンクションを作成する/': [{'pagePath': '/blog/google-analytics-アフィニティ-カテゴリの英語の対訳を-bing-translate-api-で作成する/',
   'pageview_percent': 30.76923076923077,
   'pageviews': 28,
   'previousPagePath': '/blog/google-analytics-アフィニティカテゴリの日本語翻訳を返すpython-ファンクションを作成する/'}],
 '/blog/google-app-script-の-urlfetchapp-の-例外ハンドリングについて/': [{'pagePath': '/blog/google-apps-script-urlfetchapp-で-http-header-を設定する/',
   'pageview_percent': 15.071283095723015,
   'pageviews': 74,
   'previousPagePath': '/blog/google-app-script-の-urlfetchapp-の-例外ハンドリングについて/'}],
 '/blog/google-apps-script-urlfetchapp-で-http-header-を設定する/': [{'pagePath': '/blog/google-app-script-の-urlfetchapp-の-例外ハンドリングについて/',
   'pageview_percent': 37.735849056603776,
   'pageviews': 60,
   'previousPagePath': '/blog/google-apps-script-urlfetchapp-で-http-header-を設定する/'}],
 '/blog/google-data-studio-でヒストグラムを描画する/': [{'pagePath': '/',
   'pageview_percent': 10.0,
   'pageviews': 4,
   'previousPagePath': '/blog/google-data-studio-でヒストグラムを描画する/'}],
 '/blog/google-search-console-の-キーワードの共起ネットワーク図を-python-で描画する/': [{'pagePath': '/blog/検索キーワードの共起ネットワーク図を-cytoscape-で描画する/',
   'pageview_percent': 27.766990291262136,
   'pageviews': 143,
   'previousPagePath': '/blog/google-search-console-の-キーワードの共起ネットワーク図を-python-で描画する/'}],
 '/blog/google-search-console-の-キーワードを-python-sklearn-linearsvc-でクラス分類してカテゴリ分けする/': [{'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/',
   'pageview_percent': 16.27906976744186,
   'pageviews': 7,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-linearsvc-でクラス分類してカテゴリ分けする/'},
  {'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/',
   'pageview_percent': 27.906976744186046,
   'pageviews': 12,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-linearsvc-でクラス分類してカテゴリ分けする/'}],
 '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/': [{'pagePath': '/blog/google-search-console-の-キーワードの共起ネットワーク図を-python-で描画する/',
   'pageview_percent': 15.873015873015873,
   'pageviews': 10,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/'},
  {'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-linearsvc-でクラス分類してカテゴリ分けする/',
   'pageview_percent': 15.873015873015873,
   'pageviews': 10,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/'},
  {'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/',
   'pageview_percent': 22.22222222222222,
   'pageviews': 14,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/'}],
 '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/': [{'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-linearsvc-でクラス分類してカテゴリ分けする/',
   'pageview_percent': 12.32876712328767,
   'pageviews': 18,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/'},
  {'pagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-randomforestclassifier-でクラス分類してカテゴリ分けする/',
   'pageview_percent': 13.013698630136986,
   'pageviews': 19,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/'},
  {'pagePath': '/blog/google-search-console-の-キーワードを-python-でクラスタリングする/',
   'pageview_percent': 11.643835616438356,
   'pageviews': 17,
   'previousPagePath': '/blog/google-search-console-の-キーワードを-python-sklearn-の-ナイーブベイズ分類-で-カテゴリ分けする/'}],
 '/blog/google-tag-manager-の-カスタムjavascript内-で-this-のようなものを使う/': [{'pagePath': '/blog/gtmgoogle-tag-manager-て-ユーサのカテコリことのハナー配信メッセーシ配信-を行う/',
   'pageview_percent': 12.5,
   'pageviews': 4,
   'previousPagePath': '/blog/google-tag-manager-の-カスタムjavascript内-で-this-のようなものを使う/'}],
 '/blog/google-モバイルサイト認定を取得してみました/': [{'pagePath': '/blog/mezzanine-amp-対応のテーマを作成してみました/',
   'pageview_percent': 19.444444444444443,
   'pageviews': 7,
   'previousPagePath': '/blog/google-モバイルサイト認定を取得してみました/'},
  {'pagePath': '/blog/usage-of-django-compress-on-mezzanine/',
   'pageview_percent': 13.88888888888889,
   'pageviews': 5,
   'previousPagePath': '/blog/google-モバイルサイト認定を取得してみました/'},
  {'pagePath': '/blog/プログラマがgaiq-を取得した話/',
   'pageview_percent': 13.88888888888889,
   'pageviews': 5,
   'previousPagePath': '/blog/google-モバイルサイト認定を取得してみました/'}],
 '/blog/google-モバイルフレンドリーテストで出力された警告に対処する/': [{'pagePath': '/blog/google-モバイルフレンドリーテスト-をpythonを使って実施して駄目な部分を対応する/',
   'pageview_percent': 12.5,
   'pageviews': 5,
   'previousPagePath': '/blog/google-モバイルフレンドリーテストで出力された警告に対処する/'}],
 '/blog/gtm-を使ってmixpanel-のタグを設定する/': [{'pagePath': '/blog/onesignal-google-analyticsmixpanel-に-event-を送付する/',
   'pageview_percent': 11.363636363636363,
   'pageviews': 5,
   'previousPagePath': '/blog/gtm-を使ってmixpanel-のタグを設定する/'}],
 '/blog/htmlcompressor-maven-plugin-を使ってhtml-を圧縮する/': [{'pagePath': '/blog/jar-ファイル作成時にminify-maven-plugin-を使ってcssjavascript-を圧縮結合する/',
   'pageview_percent': 47.36842105263158,
   'pageviews': 18,
   'previousPagePath': '/blog/htmlcompressor-maven-plugin-を使ってhtml-を圧縮する/'}],
 '/blog/install-SonarQube-on-El-Capitan/': [{'pagePath': '/blog/Try-Japanese-translation-of-rule-of-SonarQube/',
   'pageview_percent': 32.18390804597701,
   'pageviews': 56,
   'previousPagePath': '/blog/install-SonarQube-on-El-Capitan/'}],
 '/blog/invisible-markup-on-wicket/': [{'pagePath': '/blog/wicket-条件でhtml等のリソースファイルの切り替えをする/',
   'pageview_percent': 11.764705882352942,
   'pageviews': 6,
   'previousPagePath': '/blog/invisible-markup-on-wicket/'}],
 '/blog/jar-ファイル作成時にminify-maven-plugin-を使ってcssjavascript-を圧縮結合する/': [{'pagePath': '/blog/htmlcompressor-maven-plugin-を使ってhtml-を圧縮する/',
   'pageview_percent': 24.59016393442623,
   'pageviews': 30,
   'previousPagePath': '/blog/jar-ファイル作成時にminify-maven-plugin-を使ってcssjavascript-を圧縮結合する/'}],
 '/blog/java-easybatchを使ってみる1/': [{'pagePath': '/blog/java-easybatchを使ってみる2/',
   'pageview_percent': 61.1764705882353,
   'pageviews': 52,
   'previousPagePath': '/blog/java-easybatchを使ってみる1/'}],
 '/blog/jpa-query-selecting-only-specific-columns/': [{'pagePath': '/blog/Several-queries-implemented-with-QueryDsl/',
   'pageview_percent': 10.169491525423728,
   'pageviews': 6,
   'previousPagePath': '/blog/jpa-query-selecting-only-specific-columns/'}],
 '/blog/mezzanine-の-blog-に-関連記事-のレコメンド表示を組み込んでみる/': [{'pagePath': '/amp/blog/google-analytics-のテータを-python-て-アソシエーション分析-する/',
   'pageview_percent': 13.793103448275861,
   'pageviews': 4,
   'previousPagePath': '/blog/mezzanine-の-blog-に-関連記事-のレコメンド表示を組み込んでみる/'},
  {'pagePath': '/blog/mezzanine-の-blog-に-関連記事-のレコメンド表示をカスタマイズする/',
   'pageview_percent': 13.793103448275861,
   'pageviews': 4,
   'previousPagePath': '/blog/mezzanine-の-blog-に-関連記事-のレコメンド表示を組み込んでみる/'}],
 '/blog/mezzanine-フロクの記事公開日の日付フォーマットを変更する/': [{'pagePath': '/blog/ssl configuration-on-mezzanine/',
   'pageview_percent': 13.793103448275861,
   'pageviews': 4,
   'previousPagePath': '/blog/mezzanine-フロクの記事公開日の日付フォーマットを変更する/'}],
 '/blog/my-first-scaling/': [{'pagePath': '/blog/category/雑記/',
   'pageview_percent': 10.256410256410257,
   'pageviews': 4,
   'previousPagePath': '/blog/my-first-scaling/'}],
 '/blog/nonencoded-querystring-on-python-requests/': [{'pagePath': '/blog/python-requests-post-リクエスト送信時にheader-を設定する/',
   'pageview_percent': 20.72072072072072,
   'pageviews': 23,
   'previousPagePath': '/blog/nonencoded-querystring-on-python-requests/'}],
 '/blog/onesignal-の-serviceworker-と-既存の-serviceworker-と-共存させる/': [{'pagePath': '/blog/onesignal-を使った-webpush-通知の実装について/',
   'pageview_percent': 25.333333333333332,
   'pageviews': 19,
   'previousPagePath': '/blog/onesignal-の-serviceworker-と-既存の-serviceworker-と-共存させる/'},
  {'pagePath': '/blog/serviceworker-の-webpush-について/',
   'pageview_percent': 17.333333333333332,
   'pageviews': 13,
   'previousPagePath': '/blog/onesignal-の-serviceworker-と-既存の-serviceworker-と-共存させる/'}],
 '/blog/onesignal-を使った-webpush-通知の実装について/': [{'pagePath': '/blog/onesignal-の-serviceworker-と-既存の-serviceworker-と-共存させる/',
   'pageview_percent': 27.419354838709676,
   'pageviews': 17,
   'previousPagePath': '/blog/onesignal-を使った-webpush-通知の実装について/'},
  {'pagePath': '/blog/serviceworker-の-webpush-について/',
   'pageview_percent': 11.290322580645162,
   'pageviews': 7,
   'previousPagePath': '/blog/onesignal-を使った-webpush-通知の実装について/'}],
 '/blog/page-speed-insight-v4-api-で-ページ統計情報を取得する/': [{'pagePath': '/blog/page-speed-insights-の-score-を-定期的に計測してdatastudio-てクラフ化する/',
   'pageview_percent': 33.333333333333336,
   'pageviews': 17,
   'previousPagePath': '/blog/page-speed-insight-v4-api-で-ページ統計情報を取得する/'}],
 '/blog/page-speed-insights-の-score-を-定期的に計測してdatastudio-てクラフ化する/': [{'pagePath': '/blog/page-speed-insight-v4-api-で-ページ統計情報を取得する/',
   'pageview_percent': 37.5,
   'pageviews': 18,
   'previousPagePath': '/blog/page-speed-insights-の-score-を-定期的に計測してdatastudio-てクラフ化する/'}],
 '/blog/pmd-rulesetの一覧java/': [{'pagePath': '/blog/Default-PMD-Rules-In-Github-Repositories/',
   'pageview_percent': 52.76381909547739,
   'pageviews': 105,
   'previousPagePath': '/blog/pmd-rulesetの一覧java/'}],
 '/blog/postgres-sql-fatal-role-xxxxxx-is-not-permitted-to-log-in-が発生する/': [{'pagePath': '/blog/postgresql-connection-to-database-failed-fe_sendauth-no-password-supplied/',
   'pageview_percent': 12.195121951219512,
   'pageviews': 5,
   'previousPagePath': '/blog/postgres-sql-fatal-role-xxxxxx-is-not-permitted-to-log-in-が発生する/'}],
 '/blog/python-folinum-を使い都道府県の夫婦年齢差をプロットする/': [{'pagePath': '/blog/python-folium-で都内の公園にまつわる情報を地図上に描画する/',
   'pageview_percent': 28.514851485148515,
   'pageviews': 144,
   'previousPagePath': '/blog/python-folinum-を使い都道府県の夫婦年齢差をプロットする/'},
  {'pagePath': '/blog/python-folium-指定できる-地図の-タイル-について/',
   'pageview_percent': 19.00990099009901,
   'pageviews': 96,
   'previousPagePath': '/blog/python-folinum-を使い都道府県の夫婦年齢差をプロットする/'}],
 '/blog/python-folium-で都内の公園にまつわる情報を地図上に描画する/': [{'pagePath': '/blog/python-folinum-を使い都道府県の夫婦年齢差をプロットする/',
   'pageview_percent': 22.804054054054053,
   'pageviews': 135,
   'previousPagePath': '/blog/python-folium-で都内の公園にまつわる情報を地図上に描画する/'},
  {'pagePath': '/blog/python-folium-指定できる-地図の-タイル-について/',
   'pageview_percent': 19.425675675675677,
   'pageviews': 115,
   'previousPagePath': '/blog/python-folium-で都内の公園にまつわる情報を地図上に描画する/'}],
 '/blog/python-foliumのコロプレス図で選択可能なfill_color-について/': [{'pagePath': '/blog/python-folinum-を使い都道府県の夫婦年齢差をプロットする/',
   'pageview_percent': 28.985507246376812,
   'pageviews': 40,
   'previousPagePath': '/blog/python-foliumのコロプレス図で選択可能なfill_color-について/'},
  {'pagePath': '/blog/python-folium-で都内の公園にまつわる情報を地図上に描画する/',
   'pageview_percent': 17.391304347826086,
   'pageviews': 24,
   'previousPagePath': '/blog/python-foliumのコロプレス図で選択可能なfill_color-について/'},
  {'pagePath': '/blog/python-folium-指定できる-地図の-タイル-について/',
   'pageview_percent': 14.492753623188406,
   'pageviews': 20,
   'previousPagePath': '/blog/python-foliumのコロプレス図で選択可能なfill_color-について/'}],
 '/blog/python-て-ga-のテータをユーサーあたりのpageviewてセクメント分けする/': [{'pagePath': '/blog/google-analytics-のテータを-python-てコレスホンテンス分析する/',
   'pageview_percent': 14.285714285714286,
   'pageviews': 4,
   'previousPagePath': '/blog/python-て-ga-のテータをユーサーあたりのpageviewてセクメント分けする/'}],
 '/blog/python3-ではbeautifulsoup3-を-pip-install-できない/': [{'pagePath': '/blog/python-pip-install-でunicodedecodeerror-が発生/',
   'pageview_percent': 17.857142857142858,
   'pageviews': 5,
   'previousPagePath': '/blog/python3-ではbeautifulsoup3-を-pip-install-できない/'}],
 '/blog/pythonでポアソン分布の計算をする/': [{'pagePath': '/blog/Calculate-the-probability-of-binomial-distribution-with-python/',
   'pageview_percent': 10.526315789473685,
   'pageviews': 10,
   'previousPagePath': '/blog/pythonでポアソン分布の計算をする/'}],
 '/blog/search-resutls-wicket-forms/': [{'pagePath': '/blog/control-error-message-by-component-on-wicket/',
   'pageview_percent': 25.203252032520325,
   'pageviews': 31,
   'previousPagePath': '/blog/search-resutls-wicket-forms/'}],
 '/blog/serviceworker-を-ssr-中心の-blog-に組み込む際に調べたこと感想等/': [{'pagePath': '/blog/serviceworker-の-webpush-について/',
   'pageview_percent': 14.285714285714286,
   'pageviews': 5,
   'previousPagePath': '/blog/serviceworker-を-ssr-中心の-blog-に組み込む際に調べたこと感想等/'}],
 '/blog/sonarqube-java-client-介して-web-api-を-実行する/': [{'pagePath': '/blog/sonarqube-web-api-を-python-から実行する/',
   'pageview_percent': 26.19047619047619,
   'pageviews': 11,
   'previousPagePath': '/blog/sonarqube-java-client-介して-web-api-を-実行する/'}],
 '/blog/sonarqube-owasp-dependency-check-plugin-を-インストールして使ってみる/': [{'pagePath': '/blog/category/sonarqube/',
   'pageview_percent': 12.244897959183673,
   'pageviews': 6,
   'previousPagePath': '/blog/sonarqube-owasp-dependency-check-plugin-を-インストールして使ってみる/'}],
 '/blog/sonarqube-web-api-を-python-から実行する/': [{'pagePath': '/blog/Try-static-analysis-of-Python-using-SonarPython/',
   'pageview_percent': 24.65753424657534,
   'pageviews': 18,
   'previousPagePath': '/blog/sonarqube-web-api-を-python-から実行する/'},
  {'pagePath': '/blog/sonarqube-java-client-介して-web-api-を-実行する/',
   'pageview_percent': 31.506849315068493,
   'pageviews': 23,
   'previousPagePath': '/blog/sonarqube-web-api-を-python-から実行する/'}],
 '/blog/spring-boot-での-サブコマンドsubcommandsの実装案/': [{'pagePath': '/blog/args4j-で-enumoptionhandler-を使う/',
   'pageview_percent': 11.764705882352942,
   'pageviews': 6,
   'previousPagePath': '/blog/spring-boot-での-サブコマンドsubcommandsの実装案/'},
  {'pagePath': '/blog/args4j-条件付きチェックを実装する/',
   'pageview_percent': 15.686274509803921,
   'pageviews': 8,
   'previousPagePath': '/blog/spring-boot-での-サブコマンドsubcommandsの実装案/'}],
 '/blog/wicket-条件でhtml等のリソースファイルの切り替えをする/': [{'pagePath': '/blog/How-to-redirect-to-external-site-on-Wicket/',
   'pageview_percent': 11.11111111111111,
   'pageviews': 4,
   'previousPagePath': '/blog/wicket-条件でhtml等のリソースファイルの切り替えをする/'},
  {'pagePath': '/blog/create-stateless-page-on-wicket/',
   'pageview_percent': 11.11111111111111,
   'pageviews': 4,
   'previousPagePath': '/blog/wicket-条件でhtml等のリソースファイルの切り替えをする/'},
  {'pagePath': '/blog/wicketでページ内遷移を実装する/',
   'pageview_percent': 11.11111111111111,
   'pageviews': 4,
   'previousPagePath': '/blog/wicket-条件でhtml等のリソースファイルの切り替えをする/'}],
 '/blog/wicketでbodyタグのcssを切り替える/': [{'pagePath': '/blog/invisible-markup-on-wicket/',
   'pageview_percent': 18.6046511627907,
   'pageviews': 8,
   'previousPagePath': '/blog/wicketでbodyタグのcssを切り替える/'},
  {'pagePath': '/blog/wicket-152-でcss-javascript-の-reference-出力をコントロールする/',
   'pageview_percent': 23.25581395348837,
   'pageviews': 10,
   'previousPagePath': '/blog/wicketでbodyタグのcssを切り替える/'}],
 '/blog/データマイニングツール-orange-でgoogle-search-console-の-キーワードを-wordcloud-にする/': [{'pagePath': '/blog/google-analytics-のテータを-python-て-アソシエーション分析-する/',
   'pageview_percent': 11.11111111111111,
   'pageviews': 13,
   'previousPagePath': '/blog/データマイニングツール-orange-でgoogle-search-console-の-キーワードを-wordcloud-にする/'}],
 '/blog/検索キーワードの共起ネットワーク図を-cytoscape-で描画する/': [{'pagePath': '/blog/google-search-console-の-キーワードの共起ネットワーク図を-python-で描画する/',
   'pageview_percent': 53.50877192982456,
   'pageviews': 61,
   'previousPagePath': '/blog/検索キーワードの共起ネットワーク図を-cytoscape-で描画する/'}],
 '/categories/': [{'pagePath': '/about/',
   'pageview_percent': 12.658227848101266,
   'pageviews': 10,
   'previousPagePath': '/categories/'},
  {'pagePath': '/statistics/',
   'pageview_percent': 20.253164556962027,
   'pageviews': 16,
   'previousPagePath': '/categories/'}],
 '/statistics/': [{'pagePath': '/',
   'pageview_percent': 18.181818181818183,
   'pageviews': 12,
   'previousPagePath': '/statistics/'},
  {'pagePath': '/categories/',
   'pageview_percent': 16.666666666666668,
   'pageviews': 11,
   'previousPagePath': '/statistics/'}]}

参考

以下、参考にしました。

この記事で作成したデータは、AMP ページで先読み対象ページの判断するための入力として使おうかと考えております。
以上です。

コメント