[Docker, Python] Twitterアナリティクスを分析してみた(⑥単回帰分析編)

Dockerで環境構築、jupyterlabおよびPythonを使用して、Twitter機能の一つであるTwitterアナリティクスのデータを分析しています。今回から、統計学を使用して、’Engagement数’などの数値を予測していきたいと思います。

本記事を読むと、

  • Twitterデータから単回帰分析の概要がわかる
  • 分析用のサンプルコード(Python)を使用できる

ので、ぜひ最後までご覧いただけると幸いです。

なお、サンプルコードは最後に記載していますので、サンプルコードだけほしい方は、目次リンクで飛んでいただけると幸いです。

それではやっていましょう!

1. 解析用データの準備

環境構築、解析用Twitterデータの準備が終わってない方は、下記記事いただけると幸いです。

以下の本記事内容は、Docker環境で構築したJupyterlabをベースに作成しています。予めご了承ください。使用環境概要は以下となります。

  • ホストOS: Windows10 Pro
  • Docker image: ubuntu:18.04
  • Anaconda: Anaconda3-2020.07-Linux-x86_64
  • Python: Version 3.8.3 (64bit)

ファイルフォルダー構成は以下です。

.
|-- docker-compose.yml
`-- python_app
    |-- Dockerfile
    `-- jupyter_work
        |-- Twitter_analytics.ipynb
        |-- data
        |   `-- tweet_activity_metrics_UserName_YYYYMMDD_YYYYMMDD_ja.csv
        |-- data_base_analytics.py
        `-- evaluation_analytics.py

Dockerfileは以下のようにして、AnacondaをDockerコンテナ内に用意します。

#Dockerfile
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y \
    sudo \
    wget \
    vim

#Anacondaのインストール
WORKDIR /opt
RUN wget https://repo.continuum.io/archive/Anaconda3-2020.07-Linux-x86_64.sh && \
    sh /opt/Anaconda3-2020.07-Linux-x86_64.sh -b -p /opt/anaconda3 && \
    rm -f Anaconda3-2020.07-Linux-x86_64.sh
ENV PATH /opt/anaconda3/bin:$PATH
WORKDIR /
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--allow-root", "--LabApp.token=''"]

また、docker-compose.ymlは以下のようにしています。

#docker-compose.yml

version: '3'

services:
  app:
    build:
      context: ./python_app
      dockerfile: Dockerfile
    container_name: app
    ports:
        - '5551:8888'
    volumes:
      - '.:/work'
    tty: true
    stdin_open: true

解析用データは以下のコードで取得します。

""" Twitter_analytics.ipynb """

import data_base_analytics as da
import evaluation_analytics as ea


""" main """
"""1.準備編 """
twitter_data_path = da.data_path()
twitter_df = da.data_df(twitter_data_path)
twitter_df = da.data_en(twitter_df)
twitter_df = da.data_time(twitter_df)

""" 5.Tweet分析編 """
string_list = ['読書', 'ブログ', '筋トレ', '統計学', 'datascientist']
ea.evaluation_string(twitter_df, string_list)
""" data_base_analytics.py """
"""1.準備編 """

""" 事前にtwitterデータを'ANSI'にする必要あり """

from pathlib import Path
import pandas as pd

Data_path = './data'
Data_file_name = '*ja.csv'
Encode = 'CP932'

def data_path():
    return Path(Data_path ).glob(Data_file_name)

def data_df(file_path):
    LIST = [pd.read_csv(file, encoding=Encode) for file in file_path]
    df = pd.concat(LIST)
    return df

def data_en(df):
    df = df[["ツイート本文","時間","インプレッション",\
                            "エンゲージメント","エンゲージメント率","リツイート", \
                            "返信","いいね","ユーザープロフィールクリック",\
                            "URLクリック数","ハッシュタグクリック","詳細クリック"]]
    df.columns = ["Tweet", "Time", "Impression", "Engagement", \
                          "Engagement_Ratio", "RT", "Return", "Good", "User_Click", \
                          "URL_Click", "Hash_Click", "Detail_Click"]
    return df

def data_time(df):
    df['Time'] = pd.to_datetime(df['Time'].apply(lambda x: x[:-5]))
    df = df.set_index('Time').sort_index()
    return df
""" evaluation_analytics.py """
""" 5.Tweet分析編 """
def evaluation_string(df, string_list):
    for string in string_list:
        df['{}'.format(string)] = df['Tweet'].apply(lambda x: 1 if '{}'.format(string) in x else 0)
    return df

上記コードを実行して、’Twitter_df’を確認すると以下のようなデータフレームが確認できると思います。

図1 Twitter データフレーム

これでデータ準備は完了です。

2. 単回帰分析の準備(説明変数と目的変数の設定)

ここでは、’Impression’数から’Engagement’数の単回帰分析を実施します。つまり、’Impression’の数字から、’Engagement’数を予測してみる感じと思っていただければOKです。

単回帰分析がよくわからない方は、私もよく参考にさせていただいているかめさん(Twitter:@usdatascientist)のブログを参考にしていただくと良いと思います。

【Pythonで学ぶ】回帰分析を図でわかりやすく解説!条件付き平均と最小2乗法って?【データサイエンス入門:統計編13】

説明変数と目的変数を定めます。なお、他に呼び方があり、一応区別されているようです。

変数xが変数yの平均値を決定するわけですが,この変数xのことを回帰変数(regressor),変数yのことを被回帰変数(regressand)と呼びます.これには他の組み合わせの呼び方もあって,変数xと変数yをそれぞれ独立変数(independent variable)従属変数(dependent variable)と呼んだり,目的変数説明変数と呼んだりします.(実験等で得られたデータは前者,調査等で得られたデータは後者のように呼びますが,実際区別してる人は少ないように思います.)

【Pythonで学ぶ】回帰分析を図でわかりやすく解説!条件付き平均と最小2乗法って?【データサイエンス入門:統計編13】

まずは、下記コードを入力してみてください。

"""  6.単回帰分析編 """
import pandas as pd
import matplotlib.pyplot as plt

x1 = twitter_df['Impression']
y1 = twitter_df['Engagement']

x1.shape, y1.shape

説明変数x1と目的変数y1のデータ形状は1次元です。このあと用いるsklearnの単回帰分析は、x1のデータ形状が2次元である必要があるため、以下のコードで次元数を変更します。

""" sklearnに入れるデータ形状は2次元に必要がある """
x1_reshape = x1.values.reshape(-1,1)
x1_reshape.shape

3. 単回帰分析のモデル構築

さて、データ準備も完了したので、早速単回帰分析していきましょう。

以下のコードを入力してください。skleranから、単回帰分析のライブラリ’LinearRegression’をインポートします。そして、モデルをフィットさせ、決定係数r2を算出していきます。

from sklearn.linear_model import LinearRegression

reg = LinearRegression()
""" データ入力後、分析モデルにフィット """
reg.fit(x1_reshape,y1)
r2 = reg.score(x1_reshape,y1).round(3)

実行すると、決定係数が算出されます。なお、決定係数が不明な方は、かめさん(Twitter:@usdatascientist)ブログで決定係数R2の詳しい説明が記載されているので、ご参考にされると良いかと思います。

定係数は,説明変数xがどれだけ目的変数yを説明しているのかを表す指標

【Pythonで学ぶ】決定係数R2を超わかりやすく解説【データサイエンス入門:統計編16】

単回帰分析は直線近似なので、その直線の係数(傾き)と切片を求めます。

a1 = reg.coef_.round(3)
b1 = reg.intercept_.round(3)

reg_summary = pd.DataFrame(data = ['Impression'], columns=['Features'])
reg_summary ['Coefficients'] = a1
reg_summary ['Intercept'] = b1
reg_summary ['Score_r2'] = r2
reg_summary

これで、単回帰分析による’Impression’数から’Engagement’数を予測する直線が作成できました。

次にこの直線式を用いて、’Impression’数から’Engagement’数を予測してみましょう。

4. 単回帰分析による予測値算出

では、’Impression’数から’Engagement’数を予測してみましょう。以下のコードを入力して、予測する’Impression’数のデータフレームを作成します。

new_tweet = pd.DataFrame(data=[1000,10000],columns=['Impression'])

今回は、’Impression’数の値が’1000’もしくは’10000’の場合、’Engagement’数はどの程度になるかを予測していきます。

予測用データを作成したら、’LinearRegression’の’predict’関数を用いて、’Engagment’数を予測します。

predict = reg.predict(new_tweet)
new_tweet['Engagement'] = predict
new_tweet

上記コードで、’Impression’数の値が’1000’もしくは’10000’の場合、’Engagement’数の予測値が出力されていると思います。

最後にTwitterデータと単回帰分析による直線式を可視化していきましょう。

5. 単回帰分析の可視化

Twitterデータの可視化には散布図、単回帰分析による直線式はplotで表示します。以下のコードを入力してみてください。

""" 変数を使った回帰式 """
y_hat = a1 * x1_reshape + b1

fig, axes = plt.subplots(figsize=(8, 5))
""" Twitterデータの散布図 """
plt.scatter(x1,y1)
""" 回帰直線の表示 """
plt.plot(x1, y_hat, c='orange', label ='regression line')
axes.set_xlabel('Impression', fontsize = 15)
axes.set_ylabel('Engagement', fontsize = 15)
fig.tight_layout()
plt.text(1000, 450,"y = {0}x + {1}".format(a1 ,b1), fontsize=15)
plt.text(1000, 400,"coefficient of determination: {0}".format(r2),fontsize=15)
plt.xlim([0, 12000])
plt.ylim([0, 500])
plt.plot()

実行すると、以下のようなTwitterデータの散布図と単回帰直線が表示されます。

図2 Twitterデータの散布図と単回帰直線

(当たり前ですが)’Impression’数が多いと、’Engagement’数が増加する傾向が見て取れますね。

6. サンプルコードとまとめ

以上の内容のサンプルコードをまとめたものは以下となります。

ファイルフォルダー構成は以下です。

.
|-- Twitter_analytics.ipynb
|-- data
|   `-- tweet_activity_metrics_BaranGizagiza_YYYYMMDD_YYYYMMDD_ja.csv
|-- data_base_analytics.py
`-- evaluation_analytics.py

各ファイルは以下となります。

""" Twitter_analytics.ipynb """

import data_base_analytics as da
import evaluation_analytics as ea
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

def main():
    """ main """
    """1.準備編 """
    twitter_data_path = da.data_path()
    twitter_df = da.data_df(twitter_data_path)
    twitter_df = da.data_en(twitter_df)
    twitter_df = da.data_time(twitter_df)

    """ 5.Tweet分析編 """
    string_list = ['読書', 'ブログ', '筋トレ', '統計学', 'datascientist']
    ea.evaluation_string(twitter_df, string_list)

    """  6.単回帰分析編 """
    x1, y1 = twitter_df['Impression'], twitter_df['Engagement']

    a1 = reg.coef_
    b1 = reg.intercept_

    new_tweet = pd.DataFrame(data=[1000,10000],columns=['Impression'])
    predict = reg.predict(new_tweet)
    new_tweet['Engagement'] = predict

    y_hat = a1 * x1_reshape + b1

    fig, axes = plt.subplots(figsize=(10, 5))
    plt.scatter(x1,y1)
    plt.plot(x1, y_hat, c='orange', label ='regression line')
    axes.set_xlabel('Impression', fontsize = 15)
    axes.set_ylabel('Engagement', fontsize = 15)
    fig.tight_layout()
    plt.plot()
""" data_base_analytics.py """
"""1.準備編 """

from pathlib import Path
import pandas as pd

Data_path = './data'
Data_file_name = '*ja.csv'
Encode = 'CP932'

def data_path():
    return Path(Data_path ).glob(Data_file_name)

def data_df(file_path):
    LIST = [pd.read_csv(file, encoding=Encode) for file in file_path]
    df = pd.concat(LIST)
    return df

def data_en(df):
    df = df[["ツイート本文","時間","インプレッション",\
             "エンゲージメント","エンゲージメント率","リツイート", \
             "返信","いいね","ユーザープロフィールクリック",\
             "URLクリック数","ハッシュタグクリック","詳細クリック"]]
    df.columns = ["Tweet", "Time", "Impression", "Engagement", \
                  "Engagement_Ratio", "RT", "Return", "Good", "User_Click", \
                  "URL_Click", "Hash_Click", "Detail_Click"]
    return df

def data_time(df):
    df['Time'] = pd.to_datetime(df['Time'].apply(lambda x: x[:-5]))
    df = df.set_index('Time').sort_index()
    return df
""" evaluation_analytics.py """
""" 5.Tweet分析編 """

import matplotlib.pyplot as plt
import seaborn as sns

def evaluation_string(df, string_list):
    for string in string_list:
        df['{}'.format(string)] = df['Tweet'].apply(lambda x: 1 if '{}'.format(string) in x else 0)
    return df

以上のファイルを用意して、jupyterlab上でmain()を呼び出せば、Twitterデータの散布図と単回帰直線を表示できると思います。

私も詰まったところが、pythonファイルを更新すると、モジュールを読み込む際は、「カーネルを再起動するか、import libを使う」必要があります。詳しくは以下のサイトに記載されているので、ご参考いただけると幸いです。

【Python】Jupyter notebookを使うときに守るべきPythonの作法2選

今回は単回帰分析でしたが、次回以降で重回帰分析による詳細解析を予定しています。

また、今後の記載内容としては

  • 統計学とTwitterデータ(ロジスティック、クラスタリング etc.)

などを予定しています。乞うご期待ください。それでは、よいPythonライフを!!

本記事に関連する過去の投稿は以下です。ご覧いただけると幸いです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT US

Baran-gizagiza
経歴:浪人→理系大学院卒業→大手製造業に就職(技術職)→アメリカ赴任中 仕事は、研究・設計など上流工程の仕事に携わっています。企業勤務を継続しながら、新しいことにチャレンジしたいと思い、ブログを下記はじめました。 このブログでは、趣味である 筋トレ(健康、ダイエット) AIとデータ(高校数学、プログラミング) 読書(主に自己啓発系) を中心に、人生経験やおすすめ情報の発信しています。