[ChatGPT Hack] Code Interpreter で、訪日外客者数 Excel ファイルのデータ加工 (データクレンジング・前処理)をやってみた

# 背景

Code Interpreter の**可能性**は本当に凄まじいものがあります。

この Blog Post では、データ加工について取り上げます。データを扱う上で最も退屈かつ最もコンピューターリソースを必要とすることもある、データの加工。特にクレンジングや前処理と言われている部分にチャレンジをします。

前に別の Blog で加工済みのデータの分析の初歩にチャレンジしてみました。
こちらですね。

https://qiita.com/dahatake/items/0a408a373dd677f16e7c

構造化されたデータからの:
- グラフ作成
- 気づきの文章作成! これ予想外にいい

さらに
- PowerPoint のプレゼン作成

を行ってみました。

今回のものが、その補完になります。しかも、超絶強力な...

:::note alert 

注意点
- ぶっちゃけ、近くにデータ分析をした経験のある人がいないと、辛いです。ChatGPT や Code Interpreter は**迷走**をすることがあります。**データ加工はそれに遭遇しやすい**です。
- データ加工で何をどうする必要があるのか? その指示を具体的に Prompt の中で記載してください。

迷走例 #1: https://chat.openai.com/share/3ed08a7e-fa74-4e2a-a312-03f93ca91042
迷走例 #2: https://chat.openai.com/share/e1d79dc0-7078-459b-897d-de2eeb04be11

- **機密情報**を扱うのは、現状は避けたほうがいいです。OpenAI の方で明言されていません。探せていません。
- **巨大なデータ**を扱うのも無理です。現状 (2023年8月2日現在) は Code Interpreter は 10GBのストレージ。一度のファイルのアップロードは 512MBまで。コードの実行時間は120秒まで、となっています。

:::

:::note
Tips

**巨大なデータ**に応用したい、という方は多いです😊
ここで Code Interpreter を使って作成した **Python のコードを PySpark に改造**して。**Spark の Cluster** で動かす道があります😊
以下、おススメの Spark 環境です。

Azure DataBricks:
https://learn.microsoft.com/ja-jp/azure/databricks/introduction/

Microsoft Fabric - Data Engineering:
https://learn.microsoft.com/ja-jp/fabric/data-engineering/data-engineering-overview

これも後日、時間を作って試そうかなー😎
:::


## 加工前のデータについて
先のデータの分析のチャレンジでも、政府観光局の**訪日外客者数**データを扱いました。
実は、この訪日外客数のデータは、Power BI Desktop (無料版) を使っての**データ分析の処理のハンズオンで使っている**ものなんです。

https://qiita.com/mimocihz/items/3c1fe6b06cd4da72c131#%E5%8F%82%E8%80%83

このBlogからの [参考] に 4つの Blog Post があります。ここで扱っているデータ加工の内容は、**実社会・ビジネスで本当によくある場合をカバー**しています。ハンズオン後に、即座に実データでワークショップ・演習をやっていますが、**感覚値ですが80-90%以上**は先の Blog でいけますね😎

その中の**データクレンジング編** を Code Interpreter でチャレンジします。

https://qiita.com/mimocihz/items/e7a4742c099691caa33b

どんなデータ構造になっているんでしょうか? 見ていきましょうー

これが元データのスクショです。訪日外客数が、国と月でクロス集計されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/21060993-8774-6bba-08bb-cb198a57b56f.png)

そして、1つのExcelシートに、1年分のデータが入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/21a786cd-f0e2-a74e-42fc-1527bbaad7a8.png)

実は、データの列が2019年までと、2020年からで異なります。国が、2023年以降はA,B列にまたがるようになりました。人が見る分にはたいして影響はないんですけどね。データソースにする際には、これが厄介です😅

2020年以降:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/386cc433-795c-1d83-3698-dae201da120b.png)

2019年以前:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/dcef77e9-2b93-3f07-7e31-c3e14aba1f73.png)

分析用の**データの構造**ですが。以下の図の様に、**同じデータは1つの列に纏める**のが大事です。**構造化データ**というやつですねー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e5683d94-0888-d61c-9db7-1cd93d20244b.png)

以下を行う必要がありますね。
- 列の構造の異なる複数シートのデータを、**1つのデータセットに結合**する
- クロス集計の**行列変換**を行う

PythonのPandasでそれらが出来るのはわかっています。後は、それを如何に Prompt の指示で実現できるか? ですね。例示が難しいですよね? データの構造は...

# リソース

こちらに、ChatGPT の Prompt を晒します! つまり、公開します。

Prompt at ChatGPT:

https://chat.openai.com/share/55aa3da1-2309-4031-aad3-f9b79b4a3230

- この Prompt では、データ分析にまつわる、**ほぼ全てのフロー**をやってみています。この Blog では、データ加工に焦点をあてるので、前半部分だけにとどまっている点にご注意!

そして、こちらが、Prompt 部分だけの文字列たちです。

Prompt at GitHub:

https://github.com/dahatake/ChatGPT-Prompt-Sample-Japanese/blob/main/%5BPlugin%5D%20Code%20Interpreter/%E8%A8%AA%E6%97%A5%E5%A4%96%E5%AE%A2%E6%95%B0%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E5%8A%A0%E5%B7%A5.md

# 手順

## 1. ファイルのダウンロード

以下よりファイルをダウンロードします。

[時系列推移表]の[国籍/月別 訪日外客数 (2003年-2023年) (Excel)]をダウンロードします。

https://www.jnto.go.jp/statistics/data/visitors-statistics/

ダウンロードしたファイルは、こちらにもあります。

https://github.com/dahatake/ChatGPT-Prompt-Sample-Japanese/blob/main/%5BPlugin%5D%20Code%20Interpreter/data/since2003_visitor_arrivals_May_2023.xlsx

## 2. Prompt 開始

まず、大まかな作業指示をします。

Prompt:
```cmd
### 役割 ###
データエンジニアのプロフェッショナルとして振舞ってください。

### 指示 ###
アップロードしたExcelのデータのクレンジングをします。その後、データの分析に入ります。指示をするまで分析には入らないでください。
Step by Step で実行してください。
```

次です。
ファイルをアップロードします。それと同時に以下の Prompt を入力します。

```cmd
### 指示 ###
最初にアップロードしたファイルから、「年月日」「国名」「訪日外客数」をもつデータを作成します。グラフの中の全ての文字列は、このフォントを使ってください。

### Excelファイルの特徴: ###
- このExcelファイルは年毎にシートで管理されています
- 各シートの上位３行はデータには不要
- 2019年以前のシートと、2020年以降のシートで国名の列のレイアウトが異なっています
- 2020年以降のシートはA列に中東地域と北欧地域の下のB列に国名が入っている行があるので、その場合は、B列の文字列を国名にしてください
- 「伸率」「累計」も削除してください。
- 「総数」「計」「累計」「地域」の文字を含むデータを削除してください。
- 国名データの前後のスペースを削除してください。
- 年月日は、YYYY/MM/01という日付型に変換をしてください。
```

だいぶ長文になってきましたね。そして、「Excelファイルの特徴:」に、**具体的に行ってもらいたいデータ加工の手順を指示**しています。

以下、気づきです。
- Excel のファイルをデータとして提供した場合は、**最初のシートのみ参照する**ことが多いです。
- 元のExcelには「国名」という列はありません。行列変換 (Pivot) をしている最中に、列名が無いので勝手に削除したりするコトがありました。
- 「総数」などの集計データを削除することはしてくれることが殆どなかったです。Prompt の仕方で出来る気もしますが...😅


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/66028423-5846-46b4-b415-67a2c6a3938d.png)

まずは、アップロードしたファイルの中身を確認してくれます。


そして、最初の指示である「このExcelファイルは年毎にシートで管理されています」を確認。その後、同じくシートについてである、「2019年以前のシートと、2020年以降のシートで国名の列のレイアウトが異なっています」の作業に入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/82b2216c-8729-eac8-ca8a-c15863af4a64.png)

2003年をサンプリングとしてデータの内容を確認しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/380699e8-a0e8-5008-e241-b86039595fdf.png)

いい感じ。

で、すかさず、2020年以降、つまりもう一つのレイアウトの確認にいきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/e3a8f0b6-d1f5-8c66-6a8e-fc3daaf57a5e.png)

エラーが出ていますね。
で、Code Interpreter は**エラーの修正を試みるん**です。ここ毎回思いますが、マジすげぇ😍


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/61317a25-dba1-d083-95a8-3407efdb23ba.png)

で、この通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/70a57388-858c-1d08-a7c8-862cf66f190f.png)

マジで、すげぇ!

ちょっと気になった個所をのぞいてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/eb1914fe-0bd2-f512-7d24-f3289fdb04b4.png)

この部分のコードが以下なんです。

```python
# Define a function to cleanse the data for years 2020 and onwards
def cleanse_data_post_2020(df, year):
    # Remove '伸率', '累計' columns
    df = df.drop(columns=[col for col in df.columns if '伸率' in col or '累計' in col])
    
    # Use B column as the country name if A column has a region
    df[df.columns[1]] = df[df.columns[1]].where(df[df.columns[1]].notna(), df[df.columns[0]])
    
    # Remove rows where the country column is '総数', '計', '累計', or ends with '計'
    df = df[~df[df.columns[1]].isin(['総数', '計', '累計', '中東地域'])]
    df = df[~df[df.columns[1]].str.endswith('計')]
    
    # Trim whitespace from country names
    df[df.columns[1]] = df[df.columns[1]].str.strip()
    
    # Melt the dataframe to a long format
    df_melted = df.melt(id_vars=df.columns[1], value_vars=df.columns[2:],
                        var_name='月', value_name='訪日外客数')
    
    # Convert month names to numbers
    df_melted['月'] = df_melted['月'].apply(month_name_to_number)
    
    # Convert year and month to datetime format
    df_melted['年月日'] = pd.to_datetime(df_melted['月'].astype(str) + '/01/' + str(year), format='%m/%d/%Y')
    
    # Drop the month column
    df_melted = df_melted.drop(columns=['月'])
    
    # Rename the country column
    df_melted = df_melted.rename(columns={df.columns[1]: '国名'})
    
    # Reorder the columns
    df_melted = df_melted[['年月日', '国名', '訪日外客数']]
    
    return df_melted

# Cleanse the 2020 data as an example
cleaned_2020 = cleanse_data_post_2020(sample_2020, 2020)
cleaned_2020.head()

```

これね。毎回 Code Interpreter 使っていて思うんですが。
はい、確かに**私もこの程度のコードは書けます**よ。でも、如何に **GitHub Copilot を駆使したとしても**。Code Interpreter の作成・実行する時間と比較したら。**私がコードを書いた方が、圧倒的に遅い**です。

目測:
- Code Interpreter: 5分
- @dahatake 氏: 60分 は欲しい😅

分かります? **圧倒的な早さ**。そして @dahatake 無しでも出来ちゃいますよね😅


Prompt:
```cmd
作成されたデータの内容を確認したいので、基礎解析を行ってください。
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/1ef7f1af-e030-6a6b-871b-2fc558c2d759.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/0139f0b3-ea8e-9ed1-b26b-720c6d21ae66.png)

そして、何も具体的には指示していないのですが、「基礎解析」という言葉だけで、可視化も始めてくれている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/fe65496d-93eb-f099-1b4a-0df26f9cf655.png)

強すぎるでしょ!

データ加工を行う際には、内容の確認は**必須**です。指示通り出来ていないコトが多々あります。ある程度の数のサンプリングを行って、処理結果の検証を必ず行ってください。

Prompt:
```cmd
データをCSV形式で保存してください。
```

保存したCSVファイルはこちらです。

https://github.com/dahatake/ChatGPT-Prompt-Sample-Japanese/blob/main/%5BPlugin%5D%20Code%20Interpreter/output/%E8%A8%AA%E6%97%A5%E5%A4%96%E5%AE%A2%E6%95%B0%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E5%8A%A0%E5%B7%A5/cleaned_visitor_data.csv

# 最後に

実ビジネスのシナリオでの応用範囲の広いデータクレンジングのシナリオ。これが Code Interpreter で動いてしまったのを確認したのは本当に**衝撃**でした。

前にも書きましたが、実現場でのデータ加工で武器になるTipsを再掲します:
- 複数ファイルや複数シートのマージ
- 行列変換

これが出来たんです😍!

となると...

ChatGPT + Code Interpreter の組み合わせ。データ分析にまつわるタスクを整理すると以下の様になるかと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/0dc6e5f6-4071-212a-77fa-0053fdab0ba0.png)

- 赤は人がやらねばならないところ
- 白抜きは任せられそうなところ

実社会・ビジネスで使うには、課題もあります。ですが、このベースの動きをやらせただけで。環境作成から開始して、作業時間はそうですね4時間も無いと思いますよ。やり方が分かった今は、おそらく15分で出来るでしょう。

データ加工ツールはいくつもあります。でも、**結構な時間をかけてのトレーニングが必要**なんです。

そして、データ加工の主役はエンジニアではないです。社会やビジネスの現場をご存じの皆さんです。エンジニアは、ツールの使い方ではなく、セキュアでパフォーマンス抜群で安心して動く裏方の整備。ここはエンジニアの腕の見せ所なんですが。これは今もこれからも変わらない。

Digital Transformation の肝は、Digigtal Feedback Loop だと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108143/df4746c9-6471-62eb-6302-9429e5867d57.png)

デジタル以前の世界では、これがほぼ実現不可能だった。これが比較的容易に実現できるようになった。それでも、データの利活用は殆ど全ての企業で未だに未着手だったりしていませんか?社員・職員の方。データを見る事はできますか?

いよいよ**データの民主化**が始まると思います。