見出し画像

【#49】Googleトレンドのデータを日別に取得する方法

おはようございます!
データサイエンスを学んでいる、大学4年生のUKIです。

今日は、『Googleトレンドのデータを日別に取得する方法』というテーマでお話ししたいと思います。今回、Googleトレンドのデータを日別で取得する手順とPythonのコードを紹介したいと思います。同じような境遇の方の参考になれば幸いです。


モチベーション

僕は現在、大学の卒業研究でビットコインをテーマにした研究をしているのですが、そこで「ビットコイン」が検索された数を変数として扱いたいなと思って、Googleトレンドのデータを日別に取得して、それを変数として扱おうと考えました。

課題点

実際に、Googleトレンドのデータを取得しようとしたところ、二つの問題が生じました。

①長期間(9カ月以上)のデータを取得しようとすると、日別では取得できない
②検索数ではなく、指定期間内の最大値を100とした割合が出力される

①9カ月以上を指定すると、日別のデータが取得できない

①に関しては、細かく何日まで日別で取得できるかは確認していませんが、8カ月までは確認できましたが、9カ月以上を指定すると、週別や月別で表示されて、日別のデータを取得することができませんでした。

②検索数ではなく、割合が出力される

そうすると、少し手間はかかりますが、8カ月間のデータを繰り返し取得していけば、日別のデータを取得できるような気もするのですが、実はそう簡単にはいきませんでした。

というのも、それがまさに②の問題点で、検索数を表示されているわけではなく、割合が表示されているので、指定する期間によって、値の大きさが異なるという現象が起きてしまいます。

例えば、今日から直近1週間(5/20-26)を指定した時の最大値(100)と、その前の1週間(5/13-19)を指定した時の最大値(100)は、同じ100だとしても、必ずしも一致しないということです。

アプローチ

先に述べた二つの問題点があるわけですが、少し工夫をすれば、日別のデータを取得することができます。

具体的なアプローチの手順は、こんな感じです。

①8カ月区切りで、欲しい期間のデータを取得する。(前の期間と1日だけ被らせる)
②欲しいデータをすべて結合する。
③被らせた1日の値を元に、補正をかける。

①8カ月区切りで、欲しい期間のデータを取得する

まずは、日別で取得できるギリギリの期間(8カ月)を指定して、日別のデータを取得します。

今回は、2017年1月から2024年1月までのデータが欲しかったので、2017年1月1日から2017年8月31日までの期間を指定しました。

そして、ここから8カ月ごとに指定していくだけなのですが、先ほどの手順で説明したように、後で補正するために前の期間と1日だけ被せる必要があります。

つまり、次の期間は2017年8月31日から2018年4月30日を指定する必要があります。

そして、Googleトレンドのデータをダウンロードすると、常に「multiTimeline.csv」というファイル名で保存されるので、指定した期間が分かるように、次のように名前を変換しました。

  • 20170101_20170831.csv

  • 20170831_20180430.csv

  • 20180430_20181231.csv

  • 20181231_20190831.csv

  • 20190831_20200430.csv

  • 20200430_20201231.csv

  • 20201231_20210831.csv

  • 20210831_20220430.csv

  • 20220430_20221231.csv

  • 20221231_20230831.csv

  • 20230831_20240430.csv

②欲しいデータをすべて結合する

次に、取得したデータをすべて結合します。
Pythonコードと併せて説明していきます。

// ライブラリのインポート
import pandas as pd
import matplotlib.pyplot as plt
import os

// フォルダ内のcsvファイルをすべて取得
folder_path = './' // フォルダパスの指定
csv_files = [file for file in os.listdir(folder_path) if file.endswith('.csv')]
csv_files.sort() // ファイル名を日付順に並べ替え

data = pd.DataFrame() // すべての日別データを格納する空のデータフレームを作成
for file in csv_files:
    file_path = os.path.join(folder_path, file)
    df = pd.read_csv(file_path) // 一つずつファイルを読み込む
    data = pd.concat([data, df]) // 読み込んだファイルをdataに結合

df = data.drop(index='日') // 無駄な行を削除
df.iloc[:, 0] = df.iloc[:, 0].astype(int) // int型に変換

今回、取得したcsvファイルを直下のフォルダに格納していたので、フォルダパスに「'./'」を指定していますが、実際に手を動かす場合は、ご自身のフォルダパスを指定してください。
※この時点では、被らせている日があるので、取得したい日数(2443日)より行数が多くなっています。

また、現時点のデータを用いて折れ線グラフを作ってみると、こんな形になりました。

plt.plot(df['カテゴリ: すべてのカテゴリ'])

課題点の②で述べたように、100がいくつも存在していて、実際の検索数を反映していない状態になっていることが分かります。

③被らせた1日の値を元に、補正をかける

次に、データを取得する時に被らせた1日の値を元に、補正をかけます。

まずはその前に、被らせた1日がどこにあるかを特定します。

indices = [] // 被っている日のインデックスを格納する空のリストを作成
 
for i in range(1, len(df)): // 前の行と比較するために1から始める
    if df.index[i] == df.index[i-1]:
        indices.append(i)

indices.append(len(df)) // 最後に最終日のインデックスをリストに追加

次に、実際に被った1日の値を元に補正をかけていきます。

Pythonのコードに移る前に、補正のアルゴリズムを説明しておきます。

1つ目の期間の最終日と2つ目の期間の初日は同じ日付を表しているわけですが、異なる値を示していることがあります。
この違いを利用して、他の値を補正していきます。

例えば、1つ目の期間の最終日の値が30、2つ目の期間の初日の値が40だとすると、それぞれの期間の最大値は1つ目の方が大きいことが分かります。

つまり、2つ目の期間の値を1つ目の期間の値に寄せて補正する必要があります。

そこで、2つ目の期間の初日の値(40)を1つ目の期間の最終日の値(30)に補正しようとすると、40を3/4倍すればいいです。

ということで、2つ目の期間の値をすべて3/4倍してあげることで、すべてを1つ目の期間の値に寄せて補正することができます。

このように、まずどっちの期間の値の方が大きいかを判定して、その後に係数(今回の3/4倍のこと)を算出し、適切な方に補正する。

all_data = [] // 補正した値を格納する空のリストを作成

// 最初の期間の値をall_dataに追加
for i in df.iloc[:243, 0].tolist():
    all_data.append(float(i))

// 補正の処理
for i in range(len(indices)-1):
    // 各期間ごとの値を取得
    data = df.iloc[indices[i]:indices[i+1], 0]

    if all_data[-1] < df.iloc[indices[i], 0]:
        rate = all_data[-1] / df.iloc[indices[i], 0]
        arrange_data = data * rate
        for j in arrange_data.tolist():
            all_data.append(float(j))

    elif all_data[-1] > df.iloc[indices[i], 0]:
        rate = df.iloc[indices[i], 0] / all_data[-1]
        all_data = [x * rate for x in all_data]
        for j in data.tolist():
            all_data.append(float(j))

    else:
        for j in data.tolist():
            all_data.append(float(j))

これで、値の補正は完了しましたが、最後に被っている日がまだ残っているので、削除する必要があります。

df['補正済'] = all_data // 補正済のデータを元のデータフレームに追加

// 被っている日かどうかのフラグを追加
df['フラグ'] = 0 
for i in indices[:-1]:
    df['フラグ'][i] = 1

// 被っている日の行を削除
all_df = pd.DataFrame(df['補正済'][df['フラグ'] == 0])

最後に、完成した値を折れ線グラフで確認してみましょう。

plt.plot(all_df.index, all_df['補正済'])
plt.xticks(all_df.index[::365], rotation=45)

先ほどのグラフと比較すると、明らかに100の数が減ったことが分かると思います。

これで、Googleトレンドの長期間(9カ月以上)のデータを日別で取得することができました。

まとめ

最後まで読んでいただき、ありがとうございました。
今日は、『Googleトレンドのデータを日別に取得する方法』というテーマでお話しさせていただきました。

今後も日々の活動や学び、考えていることなどを発信していくので、よろしくお願い致します。

また、X(旧:Twitter)でも発信しているので、フォローお願いします!

匿名で質問募集中です!
聞いてみたいことなど、お気軽にメッセージください!

この記事が気に入ったらサポートをしてみませんか?