📊

Hugging Face Spacesで、購買データ分析アプリをつくる(後編)

2024/06/14に公開

目的

前回に引き続き、Streamlitで動く購買データ分析アプリを作りたいと思います。

前回は、UI部分を実装しましたが、実際に分析ロジックを動かす部分をつくっていきます。

ファイルは、Streamlitを動かしているapp.pyにまとめてしまってもいいのですが、コードが長くなりがちなのもあり、create_object.pyというファイルに分けて作っています。
(前回の、「ここまでのまとめ」でも触れましたが)

分析コード

create_object.pyの構造は、非常にシンプルにしています。

次のような「analysis_menu_list」という分析メニューのリストと、次の2つの関数です。
create_sqlは、returnにSQLの文字列を返す関数です。create_sqlには、分析メニューのほかに国、開始日・終了日を渡しています。

create_graphは、plotlyを用いてグラフのfigを返す関数です。こちらには、分析メニューとSQLで出力した結果のPandas Dataframe形式を渡しています。

これらを、app.pyで呼び出して利用しています。

import plotly.graph_objects as go
import plotly.express as px

# 分析メニュー
analysis_menu_list = ["時系列分析","バスケット分析"]

# 分析メニューごとのSQL
def create_sql(analysis_menu, country, start_date, end_date):

    # ここに分析メニューごとのSQLを書きます

    return sql


# 分析メニューごとのグラフ
def create_graph(analysis_menu, df):

    # ここに分析メニューごとのグラフ作成処理を書きます

    return fig

分析メニュー「時系列分析」

分析メニューの作成として、時系列分析を例にとってご説明します。

SQL作成

SQLは次のように作成しています。
・まずは、分析メニュー(analysis_menu)のうち、どれを選んだかを条件分岐で場合分け
・sqlに、country, start_date, end_dateという変数を渡して、SQL文を作成

SQL文は非常にシンプルですが、日付(InvoiceDate)をDATE形式に直して、集計(GROUP BY)・ソート(ORDER BY)するキー項目にしています。

そして、CustomerIDのユニーク数、Quantityの合計値、UnitPrice * Quantityの合計値を算出しています。

if analysis_menu == "時系列分析":
    sql = f"""
    SELECT
    CAST(InvoiceDate AS DATE) AS YearMonthDate,
    COUNT(DISTINCT CustomerID) AS Num_of_Purchaser,
    SUM(Quantity) AS Total_of_Amount,
    SUM(UnitPrice * Quantity) AS SalesTotal
    FROM df
    WHERE CAST(InvoiceDate AS DATE) BETWEEN DATETIME '{start_date}' AND DATETIME '{end_date}'
    AND {country}
    GROUP BY YearMonthDate
    ORDER BY YearMonthDate
    """

このSQL文を、上記のようにreturn値に入れて返すことで、app.py上で実行しています。

ちなみに、app.pyの挙動は前回も書きましたが、次のようになっています。
sqlを返して、duckdbで実行し、Pandas Dataframe形式で返すだけのシンプル構造です。

 # 処理を実行
sql = co.create_sql(analysis_menu, country, start_date, end_date)
df_output = duckdb.query(sql).to_df()

グラフ作成

続いてグラフ作成部分です。
・分析メニュー(analysis_menu)のうち、どれを選んだかを条件分岐で場合分けはSQL作成と同様です
・SQL実行結果を、dfの名称で持ってきてグラフを作成します

if analysis_menu == "時系列分析":
    # 折れ線グラフ
    fig = px.line(df, x='YearMonthDate', y='Total_of_Amount')

ここのグラフ作成については、分析メニューによって、どのグラフで見せるべきかが非常に重要になります。

時系列分析のように、順番と大小があるものであれば、折れ線グラフがいいでしょう。
一方で、他のグラフがいいこともあります。

他のメニュー

今回は、「時系列分析」以外に「バスケット分析」を実装しました。

他のメニューで使うSQLについては、データサイエンスの基礎~購買データ分析編の本をご覧ください。

Amazon Unlimitedであれば、無料で読めますので、ぜひ読んでください。

さあ動かしてみましょう

こちらからアプリを動かすことができます。
以前に動かしてから時間がたっていると(24時間?)、Streamlitサーバの起動からかかるのでやや時間が必要なので、少しお待ちください。

https://huggingface.co/spaces/karasu1982/IDPOS_App

時系列分析では、前回のアウトプットイメージでもお見せしたように出力することができます。

時系列分析

他にも、バスケット分析のメニューを選ぶと、次のような出力になります。

バスケット分析

バスケット分析では、時系列分析とは違って商品同士の併売率を見ていくことになるので、ヒートマップをつくっています。

コード全体

コードの全体像は、Hugging Face SpacesのGit Hubでご確認ください。

https://huggingface.co/spaces/karasu1982/IDPOS_App/tree/main

まとめ

ここまでで、実際にStreamlitを使ったアプリケーション開発についてお話してきました。

以前は、Streamlitはちょっとしたアプリ開発ができるもののような扱いかと思っていたのですが、最近ではデータサイエンティストが、自身の分析をユーザーが使えるように簡単にアプリケーション化するという用途に用いています。

例えば、次のような記事がありましたが、NTTドコモ社のような大会社が社内アプリ用にStreamlit(正確には、Snowflake内のStreamlitを使っているようです)を用いているようです。

https://cloud.watch.impress.co.jp/docs/case/1576426.html

ご自身で分析をしたものを、社内外でアピールしていきたいというケースで、ぜひとも使っていってください。

Discussion