レシート画像からCSVを作成し、セルフメディケーション対象金額をSQLiteで集計する

レシート画像からCSVを作成し、セルフメディケーション対象金額をSQLiteで集計する

セルフメディケーション税制の対象商品について、年間の購入金額を集計できるようにしました。

レシート画像をGeminiやGPTで読み取り、CSV化したうえでSQLiteへインポートし、対象商品の合計金額を確認します。

最終的には、医薬品だけでなく食品や日用品も含めた購入履歴をデータベース化し、店舗ごとの価格比較や最安値店舗の確認にも使えるようにする予定です。

今回の目的

今回の目的は、レシート画像から購入履歴をCSV化し、セルフメディケーション対象商品の合計金額を集計することです。

必要な情報は以下です。

  • 購入店舗名
  • 購入年月日
  • 商品名
  • 単品税抜価格
  • 価格
  • 個数
  • セルフメディケーション対象金額

食品なども同時に購入することがあるため、セルフメディケーション対象外の商品は対象金額を 0 にします。

GeminiやGPTに渡すCSV作成指示

レシート画像を読み取ってCSV化するため、GeminiやGPTには以下のような形式で出力させます。

購入店舗名,購入年月日,商品名,単品税抜価格,価格,個数,セルフメディケーション対象金額

出力例は以下です。

購入店舗名,購入年月日,商品名,単品税抜価格,価格,個数,セルフメディケーション対象金額
杏林堂 袋井旭町店,2025/06/18,サンテビオ 15mL,968,871,1,871
ピアゴ 袋井店,2025/04/18,タイレノールA 30錠,1790,1772,1,1772
COOP ユーコープ 袋井町店,2025/06/19,COゼリーエネルギー,118,354,3,0
COOP ユーコープ 袋井町店,2025/06/19,鮭・くず桜,238,190,1,0
COOP ユーコープ 袋井町店,2025/06/19,天ぷら用えび,398,238,1,0
COOP ユーコープ 袋井町店,2025/06/19,たい,398,398,1,0
COOP ユーコープ 袋井町店,2025/06/19,塩銀鮭切身,398,398,1,0

ポイントは、セルフメディケーション対象商品だけでなく、対象外の商品も同じCSVに含めることです。

対象外の商品は セルフメディケーション対象金額0 にしておけば、後で集計するときに除外できます。

CSVファイルの保存場所

作成したCSVファイルは、以下のディレクトリへ保存します。

/csv_files/

複数のレシートCSVをこのフォルダに入れておき、まとめてインポートします。

CSVをSQLiteへインポートする

CSVファイルをSQLiteへ取り込むには、以下のスクリプトを実行します。

python import_receipts_with_dedup_and_log.py

このスクリプトでは、CSVファイルを読み込み、購入履歴としてデータベースへ保存します。

重複インポートを防ぐため、同じ購入日・店舗・商品名などが重複しないように処理します。

セルフメディケーション対象金額を集計する

インポート後、セルフメディケーション対象商品の合計金額を確認します。

python medication_summary.py

実行結果は以下のようになりました。

📋 セルフメディケーション対象商品の合計金額(2025年)
▶ 合計金額:¥37,576

📊 商品別セルフメディケーション対象金額ランキング(2025年)
商品名		金額
------------------------------
リングルアイビーα200 3 ¥17,213
タイレノールA 30錠    ¥5,494
リングルアイビーα200 3 ¥2,455
101佐藤製薬 リング(15 ¥1,944
101佐藤製薬 リング★   ¥1,944
118ロキソニンSテー★   ¥1,664
セタイレノールA 30錠   ¥1,611
セロキソニンSテープ 14枚 ¥1,422
新ルルAゴールドDXα 30 ¥1,069
ケラチナミン乾燥肌クリーム  ¥970
新ルルAゴールドs 30錠  ¥919
サンテビオ 15mL     ¥871

2025年のセルフメディケーション対象商品の合計金額は、37,576円 になりました。

商品名の表記ゆれが残っている

集計結果を見ると、同じ商品と思われるものが複数行に分かれています。

例えば、以下のような表記ゆれがあります。

  • リングルアイビーα200 3
  • 101佐藤製薬 リング(15
  • 101佐藤製薬 リング★

これはOCRやLLMによるレシート読み取りで、商品名が途中で切れたり、記号が混ざったりしているためです。

現時点では、合計金額の確認を優先していますが、今後は商品名の正規化が必要になりそうです。

Neo4jとのリンク

SQLiteへ保存した購入履歴は、Neo4jともリンクさせます。

リンク処理には以下のスクリプトを使います。

python link_sql_in_ne04jdb.py

これにより、SQLiteに保存した購入履歴をNeo4j側のノードや関係とつなげられるようにします。

例えば、商品、店舗、購入日、カテゴリ、セルフメディケーション対象などをグラフとして扱えるようになります。

最安値店舗を確認する

購入履歴が蓄積されると、商品ごとの最安値店舗も確認できます。

以下を実行します。

python cheapest_store.py

これにより、過去の購入履歴から、どの商品をどの店舗で買うのが安かったかを確認できます。

セルフメディケーション税制の集計だけでなく、日用品や食品の購入最適化にもつなげられます。

全体の流れ

今回の流れを整理すると、以下です。

  1. レシート画像を用意する
  2. GeminiまたはGPTでCSV化する
  3. CSVを /csv_files/ に保存する
  4. import_receipts_with_dedup_and_log.py でSQLiteへインポートする
  5. medication_summary.py でセルフメディケーション対象金額を集計する
  6. link_sql_in_ne04jdb.py でNeo4jへリンクする
  7. cheapest_store.py で最安値店舗を確認する

今回できたこと

今回の作業で、以下まで確認できました。

  • レシート画像からCSVを作成できた
  • 食品など対象外の商品も同じCSVに含められた
  • セルフメディケーション対象金額を列として持たせた
  • CSVをSQLiteへインポートできた
  • 2025年のセルフメディケーション対象金額を集計できた
  • Neo4jとのリンク処理へ進める状態になった
  • 最安値店舗を確認する流れも用意できた

ハマりどころ

商品名のOCRゆれ

レシートの商品名は短縮表記や記号が多く、OCRやLLMで正確に読み取るのが難しい場合があります。

特に、医薬品名は途中で切れたり、メーカー名や記号が混ざったりします。

今後は、商品名の正規化テーブルを作り、同じ商品をまとめられるようにしたいです。

セルフメディケーション対象商品の判定

セルフメディケーション対象かどうかは、商品名だけでは判断が難しい場合があります。

最初はGeminiやGPTで判定しつつ、あとから手動確認できるようにしておく方が安全です。

税制に関わる内容なので、最終的にはレシートや公式情報を確認する前提にします。

対象外商品もCSVに残す

セルフメディケーション対象外の商品もCSVに残しておくと、後で家計管理や購入頻度分析に使えます。

対象外商品は、セルフメディケーション対象金額0 にしておけば、税制集計からは除外できます。

次にやること

次は、商品名の表記ゆれを減らす処理を追加したいです。

  • 商品名正規化テーブルを作る
  • 医薬品カテゴリを付ける
  • セルフメディケーション対象商品の候補リストを作る
  • 店舗ごとの価格比較を見やすくする
  • Neo4jで商品・店舗・購入日の関係を可視化する
  • 年間のセルフメディケーション集計をCSV出力する

まとめ

レシート画像をGeminiやGPTでCSV化し、SQLiteへインポートすることで、セルフメディケーション対象商品の年間購入額を集計できました。

2025年のセルフメディケーション対象商品の合計金額は、現時点で 37,576円 でした。

まだ商品名の表記ゆれは残っていますが、レシート画像から購入履歴を作成し、税制対象金額を集計する流れは作れました。

今後は、商品名の正規化、Neo4j連携、最安値店舗の確認、家計管理や購入タイミング通知へ発展させていきます。

コメント

タイトルとURLをコピーしました