QGISの使い方メモ

QGISの使い方メモ

まずは地図表示でOpenStreetMapを表示

次にGoogle Map を追加したいので
XYZタイルを右クリックし
新規接続を選択

URLを追加することで地図を追加できる
このURLは
QGIS Google Map
で検索すると出てくる

https://qiita.com/nigo1973/items/cb023983a498bcf8e73f
を参考に

名前を
Google Map衛星画像
にして

保存すれば追加できる

これで衛星画像が表示される

通常のgoogle map なら

https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}

のURLを同様に
XYZスタイルを右クリック
新規追加で追加して
名前を Google Map にして
URL を

https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}

にすれば追加できる

https://stickboost.net/qgis_googlemap
を参考にした

その他の汎用地図リンクは

Google Maps: https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}
Google Satellite: http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}
Google Satellite Hybrid: https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}
Google Terrain: https://mt1.google.com/vt/lyrs=t&x={x}&y={y}&z={z}
Google Roads: https://mt1.google.com/vt/lyrs=h&x={x}&y={y}&z={z}
国土地理院地図: https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png
OSM(Open Street Map): http://tile.openstreetmap.org/{z}/{x}/{y}.png

地図を複数表示している場合
上に設定しているレイヤーが表示される
つまり
衛星画像を1番上にすると
地図じゃなくて衛星画像が表示される

次に演習用CSVデータのダウンロード

地図は表示できたので
CSVファイルなどをダウンロードし
内容を重ねて表示する

今回は世田谷区GISオープンデータを使う

https://data-setagaya.opendata.arcgis.com
この中から
観光スポット > スポーツ
https://data-setagaya.opendata.arcgis.com/search?tags=%25E8%25A6%25B3%25E5%2585%2589%25E3%2582%25B9%25E3%2583%259D%25E3%2583%2583%25E3%2583%2588

ダウンロード形式が選べるので
とりあえず
CSV
GeoJSON
シェープファイル
KML

シェープファイルは圧縮されているので解凍すると
ccpg
dbf
prj
shp
shx
xml
のファイルが入っている

mkdir qgis
cd qgis 
mv ~/Downloads/%E* .

でダウンロードしたファイルを移動

unzip %E8%A6%B3%E5%85%89%E3%82%B9%E3%83%9D%E3%83%83%E3%83%88%EF%BC%88%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84%EF%BC%89.zip

で解凍

これをデータソースアイコンから読み込んで使う

今回はCSVを使う予定だけど
そのまま使おうとしたらCRSを指定しないとだめだった

2つ選べるようだけどわからないので調べた

* プロジェクトCRS:EPSG:3857 – WGS 84 / Pseudo-Mercator
* これは、GoogleマップやOpenStreetMapなど、多くのWeb地図サービスで採用されているCRSです。
* 「プロジェクトCRS」は、現在開いているQGISプロジェクト全体に適用されるCRSです。
* QGISでは、異なるCRSを持つ複数のレイヤを重ねて表示することができますが、その際には、すべてのレイヤがプロジェクトCRSに合わせて自動的に再投影されます。これにより、各レイヤが正しい位置に表示されます。
* つまり、プロジェクトCRSは、QGISの地図画面(マップキャンバス)の「地図の枠組み」を定義するCRSと言えます。
* デフォルトCRS:EPSG:4326 – WGS 84
* これは、GPSなどで一般的に使用される緯度・経度で位置を表す地理座標系です。
* 「デフォルトCRS」は、新しいレイヤを作成する際に、QGISが初期値として推奨するCRSです。
* CSVファイルのように、メタデータ(座標系の情報)が含まれていないデータを読み込む場合、QGISはどのCRSを使用すべきか判断できません。その際に、初期値として提示されるのがこのデフォルトCRSです。
* CSVファイルに緯度経度(WGS 84)のデータが入っている場合、このデフォルトCRSである EPSG:4326 – WGS 84 を選択するのが最も一般的で正しい選択となります。

* 「プロジェクトCRS」を選択する
* これは、読み込むCSVデータの座標が、すでにプロジェクトCRSである EPSG:3857 の形式で記録されている場合に選択します。
* 例えば、メートル単位の座標値(x, y)がCSVに入っている場合などです。
* 「デフォルトCRS」を選択する
* これは、読み込むCSVデータの座標が、緯度・経度(EPSG:4326)で記録されている場合に選択します。
* Webからダウンロードした多くのデータは、この緯度経度形式で提供されるため、通常はこちらを選択することが多いです。

OpenStreetMapやGoogleマップのレイヤーを背景地図として利用する場合、「プロジェクトCRS」を選択するのが正しい選択となります。
その理由は以下の通りです。

1. OpenStreetMapやGoogleマップのCRSは「EPSG:3857」
* これらのWeb地図サービスは、すべて EPSG:3857 – WGS 84 / Pseudo-Mercator というCRSで提供されています。これは、Web上で地図をスムーズに表示するために最適化された座標系です。
* QGISでは、これらのレイヤーを読み込むと、プロジェクトCRSも自動的に EPSG:3857 に設定されることが一般的です。

2. QGISの「オンザフライ(On-the-fly)再投影」機能
* QGISには、異なるCRSを持つレイヤーを重ねて表示できる「オンザフライ再投影」という機能があります。
* これは、すべてのレイヤーをプロジェクトCRSに合わせて、一時的に再投影して表示する機能です。
* つまり、あなたが追加しようとしているCSVデータが、もし緯度・経度 (EPSG:4326) であっても、QGISはそれを自動的に EPSG:3857 に変換して、OpenStreetMapなどの地図上にぴったり重ねて表示してくれます。

結論として
* 今回のケース(OpenStreetMapやGoogleマップが背景にある)では、CSVデータの座標系がEPSG:3857であると仮定して「プロジェクトCRS」を選択するのが合理的です。

* もしCSVデータが緯度・経度 (EPSG:4326) であり、かつ、プロジェクトのCRSがEPSG:3857である場合でも、QGISが自動的に再投影してくれますので、基本的には問題ありません。

ただし、データそのもののCRSが何かを正しく理解しておくことは非常に重要です。
もしCSVデータが明らかに緯度・経度で書かれているのに「プロジェクトCRS」として読み込んでしまうと、
QGISはCSVデータの座標値をEPSG:3857の座標値として解釈してしまい、本来とは全く異なる場所に表示される可能性があります。

正しく行うための手順
1. CSVデータの中身を確認する
* CSVファイルを開き、座標の列が緯度・経度(例:35.xxxx, 139.xxxx)か、メートル単位の座標(例:13900000, 4100000)かを確認します。

2. 適切なCRSを選択する
* CSVデータが緯度・経度の場合:**「デフォルトCRS(EPSG:4326)」**を選択します。
* CSVデータがメートル単位の座標の場合:**「プロジェクトCRS(EPSG:3857)」**を選択します。

これが gemini の回答

今回はプロジェクトCRSを使うことにする

これで追加しても何故か海の上に表示される

なので
CSVファイルを右クリックし
レイヤのCRS > レイヤのCRS設定
6677で検索し
選んでOKをすれば適用される

このままだと点だけで分かりにくいので
CSVファイルを右クリックし
ラベルを表示をクリック

これで施設名が表示される

また
CSVファイルを右クリックし
プロパティ > ラベル

フォントや文字の色などの変更が可能

これでマップで施設名を色を変更して表示できる
他の地域でもできるはず

PDFからGPTの連携

PDFからGPTの連携

chatGPT とPDFの連携
https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39774396?start=18#overview
を参考にする

ただしテキスト情報のみのPDFでの話

PDFと連携するには
まずPDFからテキスト情報を抽出する

PDFにはテキスト以外にも画像データがあるが
今回の講座は文字のみを想定

PDFから文字を抽出し
それが3000文字の場合
1000文字単位に分割すると3つの文章に分けることができる

ちなみにこっちは概要

https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39774404#overview

実践でllama index を使っている

https://www.udemy.com/course/chatgpt-linebot-gcp/learn/lecture/39877052#overview
でPDFの差し替えが載っている

ただい、これだと画像の入っているPDFはできないので他を探す

QGISのインストール

QGISのインストール

最新版はLTRのついてるものになり
意味は
Long Term Release

Ubuntu のLTSみたいな感じ

今回は Macで行う

https://qgis.org
が公式サイト

Downloadをクリックすると寄付するか聞かれるけど
最低でも10ユーロからになるので
今回は
Skip it and go to download
でダウンロード画面に遷移する

ダウンロード時には2つ選択があり
Long term version for Mac
なら安定版

Regular Version for Mac
なら最新版になる

今回は安定版を使うので
Long term version を選択

1.7GBあるので時間がかかる

なおインストーラーでこの容量で実際には2.7GB消費する

なお、そのままだと起動できないので
Mac で
システム設定 > プライバシーとセキュリティ
で下へスクロールすると
お使いのMacを保護するためにQGIS-LTRがブロックされました
とあるので
このまま開くをクリック

これでようやく起動する

これは
qgis mac 開けない
で検索し
MacでQGISが開けない場合の対応方法
を参考にした

graphDB graphRAG の他の用途

graphDB graphRAG の他の用途として
経済・金融データ分析
例: 経済指標・株価・商品価格・為替などの相関関係をグラフ構造に保存し、RAGで「現状と過去の類似パターン」を取得。
メリット:
価格・イベント・ニュースの因果関係を把握できる
RAGで時系列説明やリスク分析を生成可能
シナリオ:
質問:「過去10年間でWTIが急落したときの共通要因は?」
処理: GraphDBで急落イベントと関連経済指標を探索 → RAGが文章化

これを作成したい

GPTの答えを自分なりにまとめる

急落イベントの自動生成
閾値は2通り用意(どちらか一致でイベント化):
* 絶対閾値: return1d <= -0.05 * 統計的閾値: zscore <= -2.0 // 急落イベント生成 MATCH (a:Asset {symbol:"WTI"})-[:HAS_PRICE]->(p:Price)
WHERE p.return1d <= -0.05 OR p.zscore <= -2.0 MERGE (e:Event:PriceDrop {date:p.date, asset:"WTI"}) ON CREATE SET e.threshold = CASE WHEN p.return1d <= -0.05 THEN "ret<=-5%" ELSE "z<=-2" END MERGE (e)-[:ON_ASSET]->(a)
MERGE (e)-[:NEARBY_PRICE {lag:0}]->(p);

共起(要因候補)のひも付け
イベント±3営業日程度の窓で、関連しそうなファクトを CO_OCCURS_WITH で結ぶ。

// 経済指標サプライズと共起
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (ip:IndicatorPrint)
WHERE date(ip.date) >= date(e.date)-duration('P3D') AND date(ip.date) <= date(e.date)+duration('P3D')
MERGE (e)-[:CO_OCCURS_WITH {window:"±3d"}]->(ip);

// ドル指数(DXY)急騰など他資産の大変動
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (p:Price {asset:"DXY"})
WHERE date(p.date)=date(e.date) AND (p.return1d >= 0.01 OR p.zscore >= 2.0)
MERGE (e)-[:CO_OCCURS_WITH {window:"0d"}]->(p);

// ニュース(トピック抽出済み)も結ぶ
MATCH (e:Event:PriceDrop {asset:"WTI"}), (n:News)
WHERE date(n.date) >= date(e.date)-duration('P1D') AND date(n.date) <= date(e.date)+duration('P1D')
AND n.topic IN ["OPEC","在庫","中東地政学","需要見通し","景気後退懸念"]
MERGE (e)-[:CO_OCCURS_WITH {window:"±1d"}]->(n);

自動タグ付け(要因ノード化)
共起オブジェクトから 要因タグを抽出・集計して :Factor を作り、イベントと結ぶ。

// 例:DXY急騰なら「ドル高」を付与
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(p:Price {asset:"DXY"})
WHERE p.zscore >= 2.0 OR p.return1d >= 0.01
MERGE (f:Factor {name:"ドル高急伸"})
MERGE (e)-[:HAS_FACTOR {type:"market"}]->(f);

// 例:在庫サプライズ(EIA原油在庫が予想比+)
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(ip:IndicatorPrint)<-[:PUBLISHED_AS]-(:Indicator {code:"EIA_CRUDE_INV"})
WHERE ip.surprise > 0
MERGE (f:Factor {name:"EIA在庫予想超過(増)"})
MERGE (e)-[:HAS_FACTOR {type:"supply"}]->(f);

// 例:ニューストピックから
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(n:News)
WHERE n.topic IN ["OPEC","増産","協調減産不履行"]
MERGE (f:Factor {name:"OPEC供給ニュース"})
MERGE (e)-[:HAS_FACTOR {type:"policy"}]->(f);

回答から見ると
急落イベントの定義が必要

そして要員候補を定義し
Cyperで紐付け定義している
この要員候補が共起となるので

この共起をもとに
要因タグを抽出・集計して :Factor を作り、イベントと結ぶ

過去10年の共通要因」を求めるCypherを作成

ここまでできたら
GraphRAG(LlamaIndex例)
を作成

ゼロからやっていくとして やることの順番

0. 目的と範囲の固定(30分で決め切る)
目的:WTI急落の共通要因を、数値+ニュース根拠つきで説明・検知できる。
やること
* 期間:直近10年(例:2015-01-01〜)
* 対象:WTI, DXY, EIA原油在庫, 主要マクロ(CPI/NFP/ISM), ニュース見出し
* 急落定義:ret1d ≤ -5% または zscore ≤ -2
* 共起窓:±3日
完了条件:上記をREADMEに明文化。

1. 環境・リポジトリ準備
やること
* Gitリポジトリ作成:/graph-wti-poc
* Python 3.11系、仮想環境
* 依存:neo4j, pandas, numpy, python-dateutil, llama-index-graph-stores-neo4j, llama-index
* Neo4j(Docker可)起動、パスワード設定
完了条件:make setup && make testでimportなしのスモークテストが通る。

2. データの最小セットを落とす(まずはCSVでOK)
やること
* data/price_wti.csv(日次 Date, Close)
* data/price_dxy.csv
* data/eia_crude_inv.csv(週次 Date, actual, consensus)
* data/macro_{cpi,nfp,ism}.csv(Date, actual, consensus)
* data/news_titles.csv(Date, title, source, topic?)
完了条件:CSVが所定フォーマットで保存され、scripts/validate_csv.pyで列チェックOK。

3. グラフ・スキーマ定義
やること
* ノード:Asset, Price, Indicator, IndicatorPrint, News, Event:PriceDrop, Factor
* リレーション:HAS_PRICE, PUBLISHED_AS, ON_ASSET, NEARBY_PRICE, CO_OCCURS_WITH, HAS_FACTOR, MENTIONS
* インデックス/制約:Asset(symbol), Price(date,asset), Indicator(code), IndicatorPrint(date,code)
完了条件:scripts/init_schema.cypherを一発実行で作成される。

4. ETL(投入)——最小データ→Neo4j
やること
* scripts/load_assets.py(WTI/DXYなど)
* scripts/load_prices.py(ret1d/zscore計算込み)
* scripts/load_indicators.py(surprise = actual−consensus)
* scripts/load_news.py(topicは暫定でも可)
完了条件:Neo4j上でノード・関係の件数が期待範囲にある(簡易Cypherで確認)。

5. 急落イベント生成
やること
* jobs/mk_price_drop.cypher
* ルール① ret1d ≤ -0.05
* ルール② zscore ≤ -2.0
* イベント→資産・当日価格ノードへリンク
完了条件:MATCH (:Event:PriceDrop)で複数件が生成される。

6. 共起リンク付け(±3日)
やること
* jobs/link_cooccurrence.cypher
* Event ↔ IndicatorPrint(±3日)
* Event ↔ Price(DXY)(同日/±1日、急騰条件付き)
* Event ↔ News(±1日、topicフィルタ)
完了条件:各EventにCO_OCCURS_WITHが最低1件以上付く。

7. 要因タグ自動付与(Factor化)
やること
* ルールベースで開始(後でMLに発展)
* DXY急騰→「ドル高急伸」
* EIA在庫サプライズ>0→「在庫増サプライズ」
* News.topic in {OPEC, 需要減速, 地政学}→対応Factor
* jobs/mk_factors.cypher
完了条件:MATCH (e:Event)-[:HAS_FACTOR]->(f)がヒット、因子名の重複がない。

8. 集計クエリ(分析の芯)
やること
* TOP要因:頻度ランキング
* 事例リスト:各イベントと要因・信号の要約
* 反証:急落“でない”日との比較(同じ要因の出現率差)
完了条件:Cypher 3本がqueries/に保存され、結果がCSV/JSONで出力できる。

9. GraphRAG 接続(LlamaIndex最小構成)
やること
* Neo4j GraphStore接続
* ニュース本文(任意)をVector Index化
* 「イベント周辺サブグラフ抽出→要約」QueryEngine
完了条件:python rag_answer.py “過去10年のWTI急落の共通要因は?”が自然文で答えを返す。

10. 評価(人間の目で妥当性チェック)
やること
* ランダムに5〜10イベントを抽出し、当日の実ニュースと比較
* 誤検知/過検知の原因をメモ(topic付与・閾値調整など)
完了条件:改善ポイントのTODOが/docs/findings.mdにまとまる。

11. ルールのチューニング(再実行可能に)
やること
* 閾値・窓幅(±2/±3/±5日)、surpriseの標準化(z化)を切替可能に
* パラメタは.envやconfig.yamlへ
完了条件:make rebuild-with CONFIG=config.yamlで全処理が再実行できる。

12. アラート原型(将来の運用)
やること
* シンプルな条件2〜3本(例:WTI -3%以上&DXY +0.8%以上)
* 該当日の証跡(どの要因に引っかかったか)をテキスト生成
完了条件:CLIで日次スキャン→標準出力に最新ヒットを表示。

13. 可視化ミニUI(任意:後付け)
やること
* Streamlit or Dash
* タイムライン(急落イベント)
* ヒートマップ(要因×年)
* クリックで当日の共起ニュース・指標を展開
完了条件:ローカルで1ページ表示、スクリーンショット保存。

14. データ運用・再現性
やること
* Makefile:make all, make clean
* 週次/日次ジョブ(将来)向けに/jobs/を分離
* バックアップ手順(Neo4j dump, data/ バージョン付け)
完了条件:READMEに再現手順とバックアップ復元手順が記載。

まず動かす最短ルート(PoC 版)
1. 0→1→2(最小CSV)
2. 3(スキーマ)
3. 4(ETL投入)
4. 5(急落生成)
5. 6(共起リンク)
6. 8(要因TOP集計)
7. 9(RAG回答の骨格)
ここまでで**「数値+ニューストピックに基づく共通要因の説明」**が出ます。
その後、7(Factor強化)→11(チューニング)→12(アラート)→13(UI)で育てればOK。

GISについてのメモ

GISについてのメモ

GISは地理情報システムのこと

行政区域の境界
土地利用状況
地形図
統計情報
衛星画像
などがある

点、線、面で表せるような座標データなどはベクターデータで取り扱う

標高、気温など区切りができないものはラスターデータ

ベクターデータ
点、線、ポリゴンで地形を表現
位置情報と同時に属性を保持する
高い精度で地形の形状を表現
属性情報を持つことができる
道路、行政区域、建物の表現に適する
シェープファイル、GeoJSONなどの形式がある


地震があった時の震源の緯度経度が空間情報になる
これに加えて
属性のマグニチュード、発生時の時刻
などを保持できる
こういうのができるのがベクターデータの特徴

ラスターデータ
格子状のピクセルで地表を表現
位置情報と同時に画像を保持する
一定の解像度をもつグリッドセル
連続的な現象の表現に適する
衛星画像、標高データ、土地被覆などに利用
GeoTIFF JPEG 形式がある


温度とか標高

QGISでは両方のデータタイプを扱える

シェープファイル GeoJSON ファイルについて

シェープファイルは

ジオメトリデータ
点、線、面の空間情報

基本ファイル構成は
shp
shx
dpf

技術的制限は
サイズ上限
フィールド名制限

シェープファイルは最も広く使われるGISデータ形式
空間情報を収納するshp
インデックスを管理するshx
属性情報を保持するdbf
の3つのファイルが基本セットになる

なので渡される時には大抵zipなどで圧縮されてまとまっているが
展開した時に全て必要になるので注意

次にGeoJSON

JSON形式の拡張で
一般的なJSON形式を地理情報に拡張したファイル形式
Web開発との親和性が高い

様々なジオメトリ対応
Point
LineString
Polygon
など多様な空間オブジェクトを表現できる
複雑な地理データの扱いが可能

Webmapping での活用
特にwebベースのGISアプリで使われる
JS連携が容易

次にジオメトリオブジェクト
基本タイプ
Pint点
LineString線
これはPoint が2つ以上あれば線になる
Polygon面
これは3点あると面ができる
つまりいくつかの線を繋いで面にしている
なお面にするため、最初と最後の値は同じにする必要がある
これがないと面にならないので

これらをいくつか合わせたものが
複合タイプ
MultiPoint
MultiLineString
MultiPolygon

そしてまとめたものが
コレクション
複数のジオメトリをまとめる
GeometryCollection

GIS の応用分野

都市計画・地域計画
土地利用、都市のゾーニング、つまり用途地域の可視化、分析に使う
道路網、公共施設の配置の最適化
人工分布、将来的な発展エリアのシミュレーション

災害リスク分析、防災
洪水、土砂災害、地震などのハザードマップ
避難所の位置
避難経路の可視化
リスクエリアに住む人口、建物数の算出に使う

環境保全、自然資源管理
生態系、自然保護区のモニタリング
森林伐採、農地の変遷、水質管理などの分析
環境影響評価EIAへの活用

交通、インフラ計画
道路、鉄道、バスルートなどの交通ネットワーク分析
渋滞、通行量の可視化
交通事故のホットスポット解析

不動産、マーケティング
土地価格、地価公示データの可視化
商圏分析、店舗、支店などの立地選定
顧客分布の可視化とターゲティング

農業、林業
作物の栽培的値分析
土壌データ、気候条件のマッチング
農地の境界管理、収穫予測

教育、研究
地理学、地質学、歴史学などの研究支援
空間統計、空間相違の分析

GISデータの分析ソフト

ArcGIS
有償の業界標準ソフトウェア
機能が豊富で安定性が高い

QGIS
無料のOSS

pythonライブラリ
Geopandas
Shapley
など

今回使うのはQGIS
Mac
Windows
Linux
で動作する

多様なデータ形式に対応し
シェープファイル、GeoJSON、ラスターデータなど
様々なデータ形式が扱える

分析ツールとして
空間分析
地図作成
データ管理などが可能

プラグインによる拡張が可能

CRSとEPSGコード

CRSは
Coordinate reference system
で座標参照系

同じ座標と言っても原点をどこに取るかにより表し方が変わる
この決め方が座標系

EPSGは
European Petroleum Survey Group
で各国の測地系、投影法の識別子のこと

世界でよく使われる EPSGコードは
EPSG: 3857
Webメルカトル
OpenStreetMap など map系で使われる

EPSG: 4826
GPSで用いられる経緯度
世界測地系、WGS84で使われる

これらは世界標準で使われる

逆に地域特化のものものあり

日本でよく使われるEPSGコードは
EPSG:6677
平面直角座標系9系
日本測地系、東京都23区あたりに使われる

EPSG:6668〜6699
ユニバーサル横メルカトル座標系UTMで使われる
これは日本全体で使う

地図にプロットした時に座標系が異なるために
正しくプロットされないのはあるあるなので注意

複数の座標を可視化するならEPSGコードを揃える必要がある

この辺りはesri Japanの日本地図系で解説がある
https://www.esrij.com/gis-guide/coordinate-and-spatial/coordinate-system-japan/

あと
https://epsg.io
でコードを入力すれば詳細を見ることができる
例えば
6688
と入力すると
https://epsg.io/6688
で詳細の確認ができる

地域メッシュについて

GISでは日本全体を四角形に切って分析することがあり
その切り方を覚えておく

これが地域メッシュ
詳しくは
https://www.stat.go.jp/data/mesh/m_tuite.html
を参考に
大きさは約80km

第一次地域区画は5桁

第二次地域区画はこれを8分割したもので
約10km

第三次地域区画はさらに10等分したもので8桁になる
約一辺1kmでよく使われる

データを豊富にするなら
さらにこれを2分割した1/2地域メッシュで
これは500m

さらに細かいもので、これを2等分した
1/4地域メッシュもある
こちらは250m

分析に必要な各種経済指標のデータとの関連付け

分析に必要な各種経済指標のデータとの関連付け

AIによる時系列分析や予測において本当に必要なのは、
👉 「金価格(など予測対象)」と
👉 「各種経済指標との関連付け(=特徴量選定と因果仮説)」です。

✅ その理由(AIの本質に基づく)
AI(特にLSTMやProphetなどの時系列モデル)は、**「将来の値を予測するために、過去の関連データのパターンを学習」**します。
つまり:
* 単独の金価格系列では限界がある
→ 過去の金価格だけでは、政策変更・インフレ期待・為替変動に追いつけない
* 経済指標と結びつけてこそ「なぜ上がるか/下がるか」が予測できる
→ CPIの上昇やドル円の変動が金価格に与える影響など

✅ だから必要なのは「関連付け」=特徴量選定 + 時間的因果性
必要な処理 内容 例
📊 相関分析 金価格とCPI・WTI・ドル円の関係性を数値化 .corr() や ヒートマップ
🕒 ラグ特徴量 CPIやドル円の1日遅れ・1週間遅れの影響を追加 CPI_t-1, USDJPY_t-7
⛓ 因果関係の仮説 「インフレ率が上がると金が買われる」など CPI↑ → 金価格↑
⚙ 特徴量エンジニアリング 変化率、移動平均、ボラティリティなどの導入 ΔCPI, SMA_20

✅ 例:金価格を予測するための特徴量候補
特徴量 説明
CPI 消費者物価指数(インフレ期待)
WTI 原油価格(インフレ・景気指標)
USDJPY 為替(円安→金価格上昇しやすい)
金価格_t-1 前日終値
ΔCPI CPIの変化量(前月比)
SMA_20_gold 20日移動平均(トレンド)
金/CPI比 実質金価格(インフレ調整後価格)

✅ まとめ:分析に本当に必要なのは?
項目 必要性 補足
📈 チャート表示 ✅ 人間の理解に必要 傾向・異常・変動要因の発見
📊 指標との関連付け ✅ AI予測精度に不可欠 入力特徴量(多変量予測)
🧠 因果仮説 ✅ 分析の出発点 「何が影響しているか」をモデルに伝える

✅ 次にできること
* 🧠 特徴量エンジニアリングの開始(変化率・ラグ・差分)
* 📦 SQLiteやNeo4jで「日付→経済指標→金価格」の関連構造を保持
* 🔮 ProphetやLSTMにマルチ変数として入力して予測

ご希望あれば、次のステップとして:
* ✅ 「金価格予測用の学習データ(特徴量セット)」を自動生成するスクリプト
* ✅ 「影響度の高い特徴量ランキング」分析
* ✅ 「変化率・ラグ特徴量」を生成するコード
などご案内可能です。どこから進めたいですか?

ChatGPT に質問する
あなた:
FX、為替の分析をしたい場合、必要となる指標は? できるかぎり集めたいので、必要な指標を全て示して

ChatGPT:
素晴らしい取り組みです!
FX(外国為替)・為替レートの分析を本格的に行うために必要となる経済指標・市場指標・ポジションデータを、以下にカテゴリ別・優先度付きで網羅的に整理しました。

✅ 【最重要】中核となる経済指標(為替を動かす主要因)
カテゴリ 指標名 FREDコード / 取得元 内容
🧑‍💼 雇用 非農業部門雇用者数(NFP) PAYEMS(FRED) 米国雇用統計の中心指標、サプライズで為替が大きく動く
👷‍♂️ 失業率 失業率 UNRATE(FRED) 労働市場の健全性を反映
📈 インフレ CPI(消費者物価指数) CPIAUCSL(FRED) インフレ率(注目度高)
📊 物価 PCEコアデフレーター PCEPILFE(FRED) FRBが重視する物価指標
📦 生産 鉱工業生産 INDPRO(FRED) 経済活動の実態を示す
🛒 消費 小売売上高 RSXFS(FRED) 個人消費の強さを表す
🏛 金融政策 政策金利(FF金利) FEDFUNDS(FRED) FOMCの最終利上げ判断指標
📈 金利差 米・日本の10年債利回り差 DGS10 / JP10Y 長期金利差は為替の方向を決定

✅ 【重要】短期変動・投機を捉えるための指標
カテゴリ 指標名 取得先 内容
💼 ADP雇用統計 ADP民間雇用者数 ADP公式 NFPの先行指標(民間推計)
🏗 ISM製造業/非製造業 PMI指標 ISM公式 景気の加熱・冷え込みを評価
🌍 貿易 貿易収支 NETEXP(FRED) 国際収支・通貨需要を反映
🧾 財政 政府財政収支 FRED / 統計局 政策余地・財政リスクの判断
💬 FOMC発言 FOMCドットチャートや声明 FRB公式 将来の金利動向を織り込む判断材料

✅ 【ポジション系】センチメント分析に不可欠な指標
カテゴリ 指標名 取得先 内容
📊 IMMポジション 通貨先物建玉(Netポジ) CFTC(毎週金曜) 投機筋の動向を把握(過熱判断)
💹 リスク指標 VIX指数(恐怖指数) VIXCLS(FRED) リスクオン/オフの判定に重要
📈 株式指数 S&P500, NASDAQなど SP500(FRED)など リスク資産への流入・退避確認
🏦 金利先物 FedWatch、SOFR先物 CMEなど 金利の織り込みを可視化

✅ 【通貨ごとに重視される補足指標】
🇺🇸 米ドル(USD):
* GDP(GDPC1)
* フィラデルフィア連銀指数(PHIIND)
* シカゴ購買部協会指数
🇯🇵 円(JPY):
* 日銀政策金利(BoJ)
* コアCPI(日本)
* 実質実効為替レート(REER)
🇪🇺 ユーロ(EUR):
* ドイツIFO景況感指数
* ユーロ圏CPI
* ECB政策金利
🇨🇳 人民元(CNY):
* 中国GDP・CPI・製造業PMI
* 人民元中間値(CNH基準値)

✅ 【補足】その他考慮すべき指標
カテゴリ 指標名 内容
📊 景気動向指数 景気先行指数(USSLIND)
🏡 住宅関連 住宅着工件数(HOUST)、中古住宅販売
🏦 中央銀行バランスシート FRB、ECB、BoJなど
🛢 コモディティ 金価格(GC=F)、原油(CL=F)、銅など

✅ 分析に使えるデータソース一覧
データソース 内容 APIなど
FRED 米経済指標(無料) pandas_datareader
CFTC IMMポジション Excel or スクレイピング
TradingEconomics 世界の経済指標 REST API(有料もあり)
Yahoo Finance 為替・コモディティ yfinance
Quandl 金利・コモディティ・COT 一部無料・有料
Investing.com イベントカレンダー スクレイピング or 手動

✅ 次におすすめのステップ
1. ✅ 必要指標リストをCSVで保存 or 管理
2. ✅ FREDやYahooから取得スクリプトを一括作成
3. ✅ SQLiteやNeo4jに格納 → 分析&予測

必要であれば:
* ✅ 上記リストをCSVファイルにして渡す
* ✅ FREDなどから自動取得するスクリプト
* ✅ SQLiteへ連携するコード
など、あなたの分析基盤を整える形でサポート可能です。
次に進めたいステップを教えてください!

これで気になることは
* 🧠 特徴量エンジニアリングの開始(変化率・ラグ・差分)
* 📦 SQLiteやNeo4jで「日付→経済指標→金価格」の関連構造を保持 はこの順番で行う? それとも別の案件になる?

この2つは基本的に同じ分析プロジェクトの中で「役割が違うだけ」

✅ それぞれの役割の違い
ステップ 目的 主なツール タイミング
🧠 特徴量エンジニアリング モデルの精度を上げるために、学習用データを整備する pandas, numpy, scikit-learn モデル構築前に必須
📦 SQLite/Neo4jへの関連構造保存 人が理解・探索・説明するための構造化された関係表現 SQLite, Neo4j, cypher 可視化・レポート・RAG/LLM活用に有効

関係性は
[時系列データの取得]

[SQLiteで一元管理] ─────→ (RAGやLLMとの連携)

[特徴量エンジニアリング(差分・変化率・ラグ)]

[AIモデル構築(LSTM・Prophet・回帰など)]

[結果をNeo4jに格納して因果関係として見える化]

となる

📌 現実的な実行順はこうなります:
1. ✅ SQLiteに元データを格納する(データ基盤を整える)
2. ✅ 特徴量エンジニアリングを行う(モデル用データを整える)
3. ✅ モデルで予測・分析する
4. ✅ 分析や因果関係を人が探索するためにNeo4jへ登録

✅ まとめ:分けるべきか?
条件 同一案件でOK 分けたほうが良い
モデル精度を高めたい ✅
モデルとLLM/RAGの両方やる ✅(役割分担すればOK)
LLM用に知識構造をつくりたい ✅ Neo4j中心の別構造として

✅ 提案:以下のように分けて設計するとスムーズです
モジュール名 内容
feature_engineering.py 差分・ラグ・変化率などを作成してCSV/DF化
store_data_sqlite.py すべての指標をSQLiteに保存・更新
export_to_neo4j.py 分析結果や関係性をグラフDBに格納
train_model.py LSTMやProphetで予測モデル構築

ドル円レートの取得

ドル円レートの取得

yfinance でドル円は以下のティッカーで取得できます:
* USDJPY=X

gold: 金先物価格(USD/oz)
cpi: 米国の消費者物価指数(FREDから)
oil: WTI原油価格(USD/バレル)
usd_jpy: ドル円為替レート(1 USD = ◯◯ JPY)

取得した結果はcsvに保存し sqliteに保存することで毎回再取得せずに行えるようにしたい

mkdir auto_deel
cd auto_deel 

で作業ディレクトリ作成

 vim fetch_and_save_all.py

でスクリプト作成

import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import datetime
import os

# 保存先
csv_dir = "csv_data"
os.makedirs(csv_dir, exist_ok=True)

# 日付範囲
start = "2000-01-01"
end = datetime.datetime.today().strftime("%Y-%m-%d")

# 金価格(すでに保存済みのCSVを使用)
gold = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
gold.rename(columns={"Price": "Date", "Close": "gold_price"}, inplace=True)
gold = gold[["Date", "gold_price"]]
gold.to_csv(f"{csv_dir}/gold.csv", index=False)

# CPI
cpi = web.DataReader("CPIAUCSL", "fred", start, end).reset_index()
cpi.columns = ["Date", "cpi"]
cpi.to_csv(f"{csv_dir}/cpi.csv", index=False)

# WTI
oil = web.DataReader("DCOILWTICO", "fred", start, end).reset_index()
oil.columns = ["Date", "oil"]
oil.to_csv(f"{csv_dir}/oil.csv", index=False)

# ドル円
usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
usd_jpy.rename(columns={"Close": "usd_jpy"}, inplace=True)
usd_jpy.reset_index(inplace=True)
usd_jpy.to_csv(f"{csv_dir}/usd_jpy.csv", index=False)

print("✅ すべてのデータをCSVに保存しました。")

これで実行すると

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py", line 16, in <module>
    gold = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1026, in read_csv
    return _read(filepath_or_buffer, kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 620, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1620, in __init__
    self._engine = self._make_engine(f, self.engine)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1880, in _make_engine
    self.handles = get_handle(
                   ^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/common.py", line 873, in get_handle
    handle = open(
             ^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'gold_price_gc_f.csv'

これは金価格を保存ファイルから読み込んでいるため
新規に作業ディレクトリ作成しているため、これだと動作しない

import pandas as pd
import pandas_datareader.data as web
import yfinance as yf
import datetime
import os

# 保存先ディレクトリ
csv_dir = "csv_data"
os.makedirs(csv_dir, exist_ok=True)

# 期間
start = "2000-01-01"
end = datetime.datetime.today().strftime("%Y-%m-%d")

# ✅ 金価格(GC=F)
gold = yf.download("GC=F", start=start, end=end, interval="1d")[["Close"]]
gold.rename(columns={"Close": "gold_price"}, inplace=True)
gold.reset_index(inplace=True)
gold.to_csv(f"{csv_dir}/gold.csv", index=False)

# ✅ CPI(FRED)
cpi = web.DataReader("CPIAUCSL", "fred", start, end).reset_index()
cpi.columns = ["Date", "cpi"]
cpi.to_csv(f"{csv_dir}/cpi.csv", index=False)

# ✅ 原油(WTI:FRED)
oil = web.DataReader("DCOILWTICO", "fred", start, end).reset_index()
oil.columns = ["Date", "oil"]
oil.to_csv(f"{csv_dir}/oil.csv", index=False)

# ✅ ドル円(USD/JPY)
usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
usd_jpy.rename(columns={"Close": "usd_jpy"}, inplace=True)
usd_jpy.reset_index(inplace=True)
usd_jpy.to_csv(f"{csv_dir}/usd_jpy.csv", index=False)

print("✅ すべてのデータをCSVに保存しました。")

というように全て取得するに修正

これで実行すれば

/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py:16: FutureWarning: YF.download() has changed argument auto_adjust default to True
  gold = yf.download("GC=F", start=start, end=end, interval="1d")[["Close"]]
[*********************100%***********************]  1 of 1 completed
/Users/snowpool/aw10s/auto_deel/fetch_and_save_all.py:32: FutureWarning: YF.download() has changed argument auto_adjust default to True
  usd_jpy = yf.download("USDJPY=X", start=start, end=end, interval="1d")[["Close"]]
[*********************100%***********************]  1 of 1 completed
✅ すべてのデータをCSVに保存しました。

となって CSVファイルに保存ができる

次に
CSV → SQLite登録スクリプト

vim save_to_sqlite.py  

内容は

import sqlite3
import pandas as pd
import os

csv_dir = "csv_data"
db_path = "commodity_data.db"

conn = sqlite3.connect(db_path)

# 読み込むCSVファイル
datasets = {
    "gold_price": "gold.csv",
    "cpi": "cpi.csv",
    "oil": "oil.csv",
    "usd_jpy": "usd_jpy.csv"
}

for table, file in datasets.items():
    df = pd.read_csv(os.path.join(csv_dir, file), parse_dates=["Date"])
    df.to_sql(table, conn, if_exists="replace", index=False)
    print(f"✅ {table} を保存しました。")

conn.close()
print("✅ すべてのデータを SQLite に保存しました。")

これを実行すると

✅ gold_price を保存しました。
✅ cpi を保存しました。
✅ oil を保存しました。
✅ usd_jpy を保存しました。
✅ すべてのデータを SQLite に保存しました。

次に
SQLiteからデータ読み込んで相関分析する

🔹 対象テーブル
* gold_price
* cpi
* oil
* usd_jpy

SQLite → Pandas データフレーム → 日付で結合
相関分析・ヒートマップの作成

ステップ 説明 優先度
SQLite→Pandas→結合 分析のベースとなる時系列データを生成 ✅必須
相関係数・ヒートマップ 経済指標と金価格の関係性を把握 ✅必須
Prophet予測 簡単・解釈しやすい時系列予測 👍推奨
LSTM予測 複雑だが精度の高い多変量時系列予測 必要に応じて

とりあえず価格予測は置いておいて
相関関係までをやる

SQLite → pandas データ読み込み & 日付で整形

import sqlite3
import pandas as pd

# SQLiteファイルのパス
db_path = "commodity_data.db"

# SQLiteに接続
conn = sqlite3.connect(db_path)

# 各テーブルを読み込み(Dateをdatetime型に)
gold = pd.read_sql("SELECT * FROM gold_price", conn, parse_dates=["Date"])
cpi = pd.read_sql("SELECT * FROM cpi", conn, parse_dates=["Date"])
oil = pd.read_sql("SELECT * FROM oil", conn, parse_dates=["Date"])
usd_jpy = pd.read_sql("SELECT * FROM usd_jpy", conn, parse_dates=["Date"])

conn.close()

日付で結合(内部結合)
# 日付で結合(内部結合:全ての指標が揃っている日付のみ残す)
df = gold.merge(cpi, on="Date") \
         .merge(oil, on="Date") \
         .merge(usd_jpy, on="Date")

# 欠損値を除外
df.dropna(inplace=True)

# 日付順に並べ替え
df.sort_values("Date", inplace=True)

# 結果確認
print(df.head())
print(df.tail())

これを保存
# 必要に応じてCSV保存して後工程へ渡せるように

df.to_csv("merged_commodity_data.csv", index=False)
print("✅ データを merged_commodity_data.csv に保存しました。")

データの中身確認(列構成)

print("📊 列名一覧:", df.columns.tolist())

を行うようにする

結合方式の違い(用途別)
結合方式 使いどころ
how=”inner” 全ての指標が存在する日だけ使いたい(分析用)✅推奨
how=”outer” 欠損があっても全部のデータを残したい場合
how=”left” 特定の指標(例:金価格)を中心に他を揃えたい時

これらを行うスクリプト

sqlite_to_pandas_and_merge.py

を作成

これは
SQLite → pandas → 結合&保存スクリプト

内容は

import sqlite3
import pandas as pd

# SQLiteファイルのパス
db_path = "commodity_data.db"

# SQLiteに接続
conn = sqlite3.connect(db_path)

# 各テーブル読み込み(Date列をdatetime型として読み込む)
gold = pd.read_sql("SELECT * FROM gold_price", conn, parse_dates=["Date"])
cpi = pd.read_sql("SELECT * FROM cpi", conn, parse_dates=["Date"])
oil = pd.read_sql("SELECT * FROM oil", conn, parse_dates=["Date"])
usd_jpy = pd.read_sql("SELECT * FROM usd_jpy", conn, parse_dates=["Date"])

conn.close()

# 日付で内部結合(共通の日付のみ残す)
df = gold.merge(cpi, on="Date") \
         .merge(oil, on="Date") \
         .merge(usd_jpy, on="Date")

# 欠損値を除去
df.dropna(inplace=True)

# 日付順に並べ替え
df.sort_values("Date", inplace=True)

# 結果の確認
print("✅ 結合完了。データの先頭:")
print(df.head())

print("\n📊 列構成:")
print(df.columns.tolist())

# CSVとして保存
df.to_csv("merged_commodity_data.csv", index=False)
print("\n✅ merged_commodity_data.csv に保存完了")


実行結果

python sqlite_to_pandas_and_merge.py 
✅ 結合完了。データの先頭:
        Date          gold_price    cpi    oil             usd_jpy
0 2000-09-01               277.0  173.6  33.42  105.94999694824219
1 2000-11-01   263.8999938964844  174.2  33.14              108.25
2 2000-12-01  268.70001220703125  174.6  32.06  111.19000244140625
3 2001-02-01               268.5  176.0  29.88  115.41999816894531
4 2001-03-01  265.20001220703125  176.1  27.78               117.5

📊 列構成:
['Date', 'gold_price', 'cpi', 'oil', 'usd_jpy']

✅ merged_commodity_data.csv に保存完了

これで
* 📊 相関分析(ヒートマップ)
* 🔮 Prophetで金価格予測(CPI・ドル円あり)
* 🤖 LSTM構築(多変量予測)

ができるらしいのでまずは目的の相関分析を試す

相関分析+ヒートマップ表示のスクリプトを作成

 vim correlation_heatmap.py

内容は

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# CSVファイル読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])

# 相関対象の列だけ抽出
corr_df = df[["gold_price", "cpi", "oil", "usd_jpy"]]

# 相関係数を計算
corr_matrix = corr_df.corr(method="pearson")  # 他に "spearman", "kendall" も可能

# 相関係数の表示
print("📊 相関係数:")
print(corr_matrix)

# ヒートマップ描画
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", fmt=".2f", square=True)
plt.title("相関ヒートマップ(金価格・CPI・WTI・ドル円)")
plt.tight_layout()
plt.show()

実行結果は

📊 相関係数:
            gold_price       cpi       oil   usd_jpy
gold_price    1.000000  0.919815  0.541180  0.156031
cpi           0.919815  1.000000  0.445084  0.431734
oil           0.541180  0.445084  1.000000 -0.224121
usd_jpy       0.156031  0.431734 -0.224121  1.000000
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 30456 (\N{CJK UNIFIED IDEOGRAPH-76F8}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 38306 (\N{CJK UNIFIED IDEOGRAPH-95A2}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12498 (\N{KATAKANA LETTER HI}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12540 (\N{KATAKANA-HIRAGANA PROLONGED SOUND MARK}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12488 (\N{KATAKANA LETTER TO}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12510 (\N{KATAKANA LETTER MA}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12483 (\N{KATAKANA LETTER SMALL TU}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12503 (\N{KATAKANA LETTER PU}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 37329 (\N{CJK UNIFIED IDEOGRAPH-91D1}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 20385 (\N{CJK UNIFIED IDEOGRAPH-4FA1}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 26684 (\N{CJK UNIFIED IDEOGRAPH-683C}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12539 (\N{KATAKANA MIDDLE DOT}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12489 (\N{KATAKANA LETTER DO}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 12523 (\N{KATAKANA LETTER RU}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 20870 (\N{CJK UNIFIED IDEOGRAPH-5186}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:22: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
  plt.tight_layout()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 30456 (\N{CJK UNIFIED IDEOGRAPH-76F8}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 38306 (\N{CJK UNIFIED IDEOGRAPH-95A2}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12498 (\N{KATAKANA LETTER HI}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12540 (\N{KATAKANA-HIRAGANA PROLONGED SOUND MARK}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12488 (\N{KATAKANA LETTER TO}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12510 (\N{KATAKANA LETTER MA}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12483 (\N{KATAKANA LETTER SMALL TU}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12503 (\N{KATAKANA LETTER PU}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 65288 (\N{FULLWIDTH LEFT PARENTHESIS}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 37329 (\N{CJK UNIFIED IDEOGRAPH-91D1}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 20385 (\N{CJK UNIFIED IDEOGRAPH-4FA1}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 26684 (\N{CJK UNIFIED IDEOGRAPH-683C}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12539 (\N{KATAKANA MIDDLE DOT}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12489 (\N{KATAKANA LETTER DO}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 12523 (\N{KATAKANA LETTER RU}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 20870 (\N{CJK UNIFIED IDEOGRAPH-5186}) missing from font(s) DejaVu Sans.
  plt.show()
/Users/snowpool/aw10s/auto_deel/correlation_heatmap.py:23: UserWarning: Glyph 65289 (\N{FULLWIDTH RIGHT PARENTHESIS}) missing from font(s) DejaVu Sans.
  plt.show()

となるが表示されるグラフは文字化けをしている

表示されている 文字化けの原因 は、matplotlib(および seaborn)が 日本語フォント(特にCJK漢字やカタカナ)をサポートしていないフォントを使っているため

macOSの場合、ヒラギノ角ゴ ProN や AppleGothic などを使うと安定するらしい

import matplotlib.font_manager as fm
import platform

# 日本語フォント設定(macOS想定)
if platform.system() == 'Darwin':  # macOS
    plt.rcParams['font.family'] = 'Hiragino Sans'
elif platform.system() == 'Windows':
    plt.rcParams['font.family'] = 'Meiryo'
else:  # Linux(必要ならIPAフォントなど)
    plt.rcParams['font.family'] = 'IPAexGothic'


Import文の後に追加すると解決した

次に
金価格・CPI・原油価格・ドル円 を、日付をX軸にして色分けした折れ線グラフで可視化
economic_indicators_time_series.py:
経済指標の時系列データであることを折れ線グラフで表示するスクリプトの作成

 vim economic_indicators_time_series.py

内容は

import pandas as pd
import matplotlib.pyplot as plt
import platform

# ✅ 日本語フォント設定(macOSなどで文字化け防止)
if platform.system() == 'Darwin':
    plt.rcParams['font.family'] = 'Hiragino Sans'
elif platform.system() == 'Windows':
    plt.rcParams['font.family'] = 'Meiryo'
else:
    plt.rcParams['font.family'] = 'IPAexGothic'

# 📥 CSVファイル読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

# 📊 折れ線グラフを描画
plt.figure(figsize=(14, 6))

plt.plot(df["Date"], df["gold_price"], label="金価格", linewidth=2)
plt.plot(df["Date"], df["cpi"], label="CPI", linewidth=2)
plt.plot(df["Date"], df["oil"], label="WTI原油", linewidth=2)
plt.plot(df["Date"], df["usd_jpy"], label="ドル円", linewidth=2)

plt.title("金価格・CPI・WTI原油・ドル円の推移")
plt.xlabel("日付")
plt.ylabel("値")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

これで表示できるけどわかりにくい

株のチャートみたいに 金価格の推移とWTI価格の推移 ドル円レートの推移 CPIの推移が一度にわかるチャートを表示したい

pip install plotly

でインストール

import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go

# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

# サブプロット作成(4行1列)
fig = make_subplots(
    rows=4, cols=1, shared_xaxes=True,
    subplot_titles=("① 金価格", "② WTI原油価格", "③ ドル円レート", "④ CPI(消費者物価指数)"),
    vertical_spacing=0.02
)

# 金価格
fig.add_trace(go.Scatter(x=df["Date"], y=df["gold_price"], name="金価格", line=dict(color='gold')), row=1, col=1)
# 原油価格
fig.add_trace(go.Scatter(x=df["Date"], y=df["oil"], name="WTI原油", line=dict(color='green')), row=2, col=1)
# ドル円
fig.add_trace(go.Scatter(x=df["Date"], y=df["usd_jpy"], name="ドル円", line=dict(color='red')), row=3, col=1)
# CPI
fig.add_trace(go.Scatter(x=df["Date"], y=df["cpi"], name="CPI", line=dict(color='blue')), row=4, col=1)

# レイアウト
fig.update_layout(
    height=800,
    title="金・原油・ドル円・CPIの推移(マルチチャート)",
    showlegend=False,
    xaxis4=dict(rangeslider=dict(visible=True)),  # ✅ スクロール可能
    template="plotly_white"
)

fig.show()


表示はできたけど、いまいちわかりにくい

マウスオーバーした時に一番上にマウスオーバーした日時の全ての値を表示するようにしたい

hovermode="x unified",  # ✅ ここでマウスオーバー時に全値を表示

を追記

しかしこれだと個々の値にしかならない

なので重ねて表示する

import pandas as pd
import plotly.graph_objects as go

# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

# 折れ線グラフを1つの図に重ねて表示
fig = go.Figure()

fig.add_trace(go.Scatter(x=df["Date"], y=df["gold_price"], name="金価格", line=dict(color='gold')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["oil"], name="WTI原油", line=dict(color='green')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["usd_jpy"], name="ドル円", line=dict(color='red')))
fig.add_trace(go.Scatter(x=df["Date"], y=df["cpi"], name="CPI", line=dict(color='blue')))

# レイアウト設定
fig.update_layout(
    title="金価格・WTI原油・ドル円・CPIの重ね表示チャート",
    xaxis_title="日付",
    yaxis_title="値",
    hovermode="x unified",  # ✅ 一括マウスオーバー
    template="plotly_white",
    height=600,
    xaxis=dict(rangeslider=dict(visible=True))  # ✅ スクロール可能
)

fig.show()

これだと全て数値は出るけどグラフが読みにくい

すべて同じグラフに描いても、スケールが違っていて視認しづらい
金価格:2000〜3000(単位:ドル/トロイオンス)
CPI:100〜300
ドル円:100〜150
原油:30〜80

金価格の値が圧倒的に大きく、他の指標が 下に張り付いて見えにくい

解決策:二次Y軸(dual y-axis)または正規化

2軸グラフでスケールの異なる指標を分離表示

Plotlyで金価格とその他を別Y軸で描画する

import pandas as pd
import plotly.graph_objects as go

df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

fig = go.Figure()

# 金価格(左Y軸)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["gold_price"],
    name="金価格", line=dict(color='gold'),
    yaxis="y1"
))

# その他(右Y軸)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["cpi"],
    name="CPI", line=dict(color='blue'),
    yaxis="y2"
))

fig.add_trace(go.Scatter(
    x=df["Date"], y=df["usd_jpy"],
    name="ドル円", line=dict(color='red'),
    yaxis="y2"
))

fig.add_trace(go.Scatter(
    x=df["Date"], y=df["oil"],
    name="WTI原油", line=dict(color='green'),
    yaxis="y2"
))

# レイアウト設定
fig.update_layout(
    title="金価格(左軸) vs CPI・WTI・ドル円(右軸)",
    xaxis=dict(title="日付", rangeslider=dict(visible=True)),
    yaxis=dict(title="金価格", side="left"),
    yaxis2=dict(title="他指標", overlaying="y", side="right"),
    hovermode="x unified",
    height=600,
    template="plotly_white"
)

fig.show()

これで
📈 金価格は左Y軸
📉 CPI・ドル円・WTIは右Y軸
🖱 マウスオーバーで全ての値を同時に表示

ただしこれだとCPIが飛び出ているのでわかりにくい

CPIはグラフに線としては描かず、マウスオーバー時の数値表示だけにしたい

指標 グラフ表示 マウスオーバー表示
金価格 ✅ 線あり ✅ 値を表示
WTI原油 ✅ 線あり ✅ 値を表示
ドル円 ✅ 線あり ✅ 値を表示
CPI ❌ 線なし ✅ 値のみ表示

CPIは透明な線として追加(表示されないがホバー時は値が出る)
Plotlyでは line=dict(width=0) や opacity=0 を使うことで実現

コードを

import pandas as pd
import plotly.graph_objects as go

# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

fig = go.Figure()

# 金価格(左軸)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["gold_price"],
    name="金価格", line=dict(color='gold'),
    yaxis="y1"
))

# WTI原油(右軸)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["oil"],
    name="WTI原油", line=dict(color='green'),
    yaxis="y2"
))

# ドル円(右軸)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["usd_jpy"],
    name="ドル円", line=dict(color='red'),
    yaxis="y2"
))

# ✅ CPIを透明線で追加(線は非表示、値だけ表示)
fig.add_trace(go.Scatter(
    x=df["Date"], y=df["cpi"],
    name="CPI(表示なし)",
    line=dict(color='rgba(0,0,0,0)'),  # 完全に透明
    yaxis="y2",
    hoverinfo="x+y+name",  # ホバーは有効
    showlegend=False       # 凡例も非表示
))

# レイアウト設定
fig.update_layout(
    title="金価格・WTI・ドル円(CPIは非表示・値のみ)",
    xaxis=dict(title="日付", rangeslider=dict(visible=True)),
    yaxis=dict(title="金価格", side="left"),
    yaxis2=dict(title="WTI・ドル円", overlaying="y", side="right"),
    hovermode="x unified",
    height=600,
    template="plotly_white"
)

fig.show()

として保存

📈 金・WTI・ドル円は見やすく線で表示
🖱 CPIは線は出ないが、マウスオーバーで数値が見える

だいぶわかりやすくなった

次は
正規化して同軸で比較(相対変化に注目)を試す

pip install plotly scikit-learn

でインストール

normalized_economic_indicators_comparison.py

がファイル名

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import plotly.graph_objects as go

# データ読み込み
df = pd.read_csv("merged_commodity_data.csv", parse_dates=["Date"])
df.sort_values("Date", inplace=True)

# 正規化する対象列
columns_to_normalize = ["gold_price", "oil", "usd_jpy", "cpi"]

# 正規化処理
scaler = MinMaxScaler()
df_normalized = df.copy()
df_normalized[columns_to_normalize] = scaler.fit_transform(df[columns_to_normalize])

# グラフ作成(正規化された値で重ね描き)
fig = go.Figure()

fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["gold_price"], name="金価格", line=dict(color='gold')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["oil"], name="WTI原油", line=dict(color='green')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["usd_jpy"], name="ドル円", line=dict(color='red')))
fig.add_trace(go.Scatter(x=df["Date"], y=df_normalized["cpi"], name="CPI", line=dict(color='blue')))

fig.update_layout(
    title="正規化された金価格・WTI・ドル円・CPIの相対変動比較",
    xaxis_title="日付",
    yaxis_title="正規化値(0〜1)",
    hovermode="x unified",
    xaxis=dict(rangeslider=dict(visible=True)),
    template="plotly_white",
    height=600
)

fig.show()

として実行

これでだいぶ見やすくなった

外付けSSDへのバックアップ

外付けSSDへのバックアップ

mv: fastcopy: read() failed: /Users/snowpool/Desktop/スクリーンショット 2025-05-11 6.26.05.png: Need authenticator

となるため
ファイルを調べたら iCloud に保存されている
これが原因だった

最初に外付けSSDが認識しなかったため

df -h /Volumes/KINGSTON 

としたが認識していない

このため

diskutil list

で調べた

 diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:             Apple_APFS_ISC Container disk1         524.3 MB   disk0s1
   2:                 Apple_APFS Container disk3         245.1 GB   disk0s2
   3:        Apple_APFS_Recovery Container disk2         5.4 GB     disk0s3

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +245.1 GB   disk3
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            16.1 GB    disk3s1
   2:              APFS Snapshot com.apple.os.update-... 16.1 GB    disk3s1s1
   3:                APFS Volume Preboot                 13.9 GB    disk3s2
   4:                APFS Volume Recovery                2.1 GB     disk3s3
   5:                APFS Volume Data                    208.1 GB   disk3s5
   6:                APFS Volume VM                      2.1 GB     disk3s6

/dev/disk4 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +3.4 GB     disk4
   1:                        EFI NO NAME                 209.7 MB   disk4s1
   2:                  Apple_HFS QGIS-LTR.app            3.1 GB     disk4s2

/dev/disk5 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *1.0 TB     disk5
   1:               Windows_NTFS KINGSTON                1.0 TB     disk5s1

どうやらマウントできているらしい

/dev/disk5 (external, physical):
   #:                       TYPE NAME     SIZE       IDENTIFIER
   0:     FDisk_partition_scheme         *1.0 TB     disk5
   1:               Windows_NTFS KINGSTON 1.0 TB     disk5s1

がその部分

このあとは認識したので

mkdir /Volumes/KINGSTON/M1Mac_bak/download_bak
mv ~/Desktop/* /Volumes/KINGSTON/M1Mac_bak/desctok_bak

でバックアップフォルダを作成

あとは

 mv ~/Downloads/* /Volumes/KINGSTON/M1Mac_bak/download_bak

でバックアップしておく

yfinanceで金価格の取得

yfinanceで金価格の取得

mkdir yfianace 
vim gold.py

内容を

import yfinance as yf
import datetime

# 金先物のティッカー
ticker = "GC=F"

# 非常に古い日付から現在まで取得
start_date = "1900-01-01"  # yfinanceが対応している限界に挑戦
end_date = datetime.datetime.today().strftime('%Y-%m-%d')

# データの取得(日足)
gold_data = yf.download(ticker, start=start_date, end=end_date, interval="1d")

# 結果の表示
print(gold_data.head())  # 最初の5件
print(gold_data.tail())  # 最新の5件
print(f"\n最古のデータ: {gold_data.index[0]}")
print(f"最新のデータ: {gold_data.index[-1]}")

として保存

これを実行

/Users/snowpool/aw10s/yfinance/gold.py:12: FutureWarning: YF.download() has changed argument auto_adjust default to True
  gold_data = yf.download(ticker, start=start_date, end=end_date, interval="1d")
[*********************100%***********************]  1 of 1 completed
Price            Close        High         Low        Open Volume
Ticker            GC=F        GC=F        GC=F        GC=F   GC=F
Date                                                             
2000-08-30  273.899994  273.899994  273.899994  273.899994      0
2000-08-31  278.299988  278.299988  274.799988  274.799988      0
2000-09-01  277.000000  277.000000  277.000000  277.000000      0
2000-09-05  275.799988  275.799988  275.799988  275.799988      2
2000-09-06  274.200012  274.200012  274.200012  274.200012      0
Price             Close         High          Low         Open  Volume
Ticker             GC=F         GC=F         GC=F         GC=F    GC=F
Date                                                                  
2025-07-21  3401.899902  3411.699951  3350.300049  3350.300049      53
2025-07-22  3439.199951  3441.000000  3395.600098  3411.000000      39
2025-07-23  3394.100098  3433.899902  3388.100098  3430.300049      63
2025-07-24  3371.000000  3371.000000  3367.000000  3367.000000      63
2025-07-25  3332.300049  3376.600098  3328.899902  3372.100098  156194

最古のデータ: 2000-08-30 00:00:00
最新のデータ: 2025-07-25 00:00:00

これを他で使えるようにcsvに保存する

import yfinance as yf
import datetime

# 金先物のティッカー
ticker = "GC=F"

# 非常に古い日付から現在まで取得
start_date = "1900-01-01"
end_date = datetime.datetime.today().strftime('%Y-%m-%d')

# データの取得(日足)
gold_data = yf.download(ticker, start=start_date, end=end_date, interval="1d")

# 結果の表示(最初と最後の数件)
print("=== 最初の5行 ===")
print(gold_data.head())
print("\n=== 最後の5行 ===")
print(gold_data.tail())

# 最古と最新のデータ日付
print(f"\n最古のデータ: {gold_data.index[0].date()}")
print(f"最新のデータ: {gold_data.index[-1].date()}")

# CSVに保存
csv_file = "gold_price_gc_f.csv"
gold_data.to_csv(csv_file)
print(f"\n✅ CSVファイルとして保存完了: {csv_file}")

実行すると

 python gold_csv.py 
/Users/snowpool/aw10s/yfinance/gold_csv.py:12: FutureWarning: YF.download() has changed argument auto_adjust default to True
  gold_data = yf.download(ticker, start=start_date, end=end_date, interval="1d")
[*********************100%***********************]  1 of 1 completed
=== 最初の5行 ===
Price            Close        High         Low        Open Volume
Ticker            GC=F        GC=F        GC=F        GC=F   GC=F
Date                                                             
2000-08-30  273.899994  273.899994  273.899994  273.899994      0
2000-08-31  278.299988  278.299988  274.799988  274.799988      0
2000-09-01  277.000000  277.000000  277.000000  277.000000      0
2000-09-05  275.799988  275.799988  275.799988  275.799988      2
2000-09-06  274.200012  274.200012  274.200012  274.200012      0

=== 最後の5行 ===
Price             Close         High          Low         Open  Volume
Ticker             GC=F         GC=F         GC=F         GC=F    GC=F
Date                                                                  
2025-07-21  3401.899902  3411.699951  3350.300049  3350.300049      53
2025-07-22  3439.199951  3441.000000  3395.600098  3411.000000      39
2025-07-23  3394.100098  3433.899902  3388.100098  3430.300049      63
2025-07-24  3371.000000  3371.000000  3367.000000  3367.000000      63
2025-07-25  3328.899902  3376.600098  3328.100098  3372.100098  157705

最古のデータ: 2000-08-30
最新のデータ: 2025-07-25

✅ CSVファイルとして保存完了: gold_price_gc_f.csv

となってcsvが保存される

次にSqlite へ登録する

しかし

import sqlite3
import pandas as pd

# CSV読み込み
df = pd.read_csv("gold_price_gc_f.csv", parse_dates=["Date"])

# SQLiteに保存
conn = sqlite3.connect("commodity_data.db")
df.to_sql("gold_price_daily", conn, if_exists="replace", index=False)
conn.close()
print("✅ SQLiteに保存完了: gold_price_daily テーブル")

だとエラーになる


Traceback (most recent call last):
  File "/Users/snowpool/aw10s/yfinance/add_sqldb.py", line 5, in <module>
    df = pd.read_csv("gold_price_gc_f.csv", parse_dates=["Date"])
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1026, in read_csv
    return _read(filepath_or_buffer, kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 620, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1620, in __init__
    self._engine = self._make_engine(f, self.engine)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 1898, in _make_engine
    return mapping[engine](f, **self.options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/c_parser_wrapper.py", line 161, in __init__
    self._validate_parse_dates_presence(self.names)  # type: ignore[has-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/io/parsers/base_parser.py", line 243, in _validate_parse_dates_presence
    raise ValueError(
ValueError: Missing column provided to 'parse_dates': 'Date'

これは
行目にティッカー情報の行が含まれており、本来のヘッダーが1行目 になっていないため、pandas.read_csv()がうまく処理できていないのが原因

このため
2行目スキップして1行目をヘッダーとして読み込むように変更

import sqlite3
import pandas as pd

# 2行目(ティッカー行)をスキップし、1行目をヘッダーとして使用
df = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
df.rename(columns={"Price": "Date"}, inplace=True)  # Date列として扱う

# SQLiteに保存
conn = sqlite3.connect("commodity_data.db")
df.to_sql("gold_price_daily", conn, if_exists="replace", index=False)
conn.close()

print("✅ SQLiteに保存完了: gold_price_daily テーブル")

これを実行すると

 python add_sqldb.py
/Users/snowpool/aw10s/yfinance/add_sqldb.py:5: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
  df = pd.read_csv("gold_price_gc_f.csv", skiprows=[1], parse_dates=["Price"])
✅ SQLiteに保存完了: gold_price_daily テーブル

となる

これにより

* Price 列 → Date に名前変更(DateTime型として扱える)
* SQLite テーブル名:gold_price_daily
* 後続のクエリや可視化処理が簡単になります
となる

保存後に確認したいのなら

# 保存したDBの中身を確認(任意)
conn = sqlite3.connect("commodity_data.db")
df_check = pd.read_sql("SELECT * FROM gold_price_daily LIMIT 5", conn)
print(df_check)
conn.close()

を追加すると良い

WTI原油、ドル円の過去レートの取得

WTI原油、ドル円の過去レートの取得

yfinance 経由で取得できる WTI原油(CL=F)やドル円(JPY=X) のデータは、Yahoo Finance に基づき、以下のようにかなり長期間に渡って利用可能

✅ 取得可能な過去データの期間(概算)
資産 シンボル 開始可能な年 備考
WTI原油先物 CL=F 1983年頃〜現在 日足・週足・月足データあり
ドル円(USD/JPY) JPY=X 1971年頃〜現在 固定相場制移行後のデータあり

GPTで

 pip install yfinance pandas matplotlib sqlite3

で必要ならライブラリインストール
とあったが

ERROR: Could not find a version that satisfies the requirement sqlite3 (from versions: none)
ERROR: No matching distribution found for sqlite3

となる

sqlite3 は Pythonに標準で内蔵されているライブラリ なので、pip install sqlite3 は不要

Python で最古の日付を確認する

 vim earliest_rate.py

内容を

import yfinance as yf

# 1銘柄ずつ最大データ期間を確認
wti = yf.download("CL=F", period="max")
usdjpy = yf.download("JPY=X", period="max")

print("WTI最古の日付:", wti.index.min())
print("ドル円最古の日付:", usdjpy.index.min())

しかし
これだと

[*********************100%***********************]  1 of 1 completed

1 Failed download:
['CL=F']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
[*********************100%***********************]  1 of 1 completed

1 Failed download:
['JPY=X']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
WTI最古の日付: NaT
ドル円最古の日付: NaT

となって
ahoo Finance の yfinance ライブラリが アクセス制限(レートリミット) に引っかかる

なので期間を限定する

import yfinance as yf

def get_earliest_date(symbol):
    try:
        df = yf.download(symbol, start="1900-01-01", end="1975-01-01", interval="1mo", progress=False)
        if df.empty:
            df = yf.download(symbol, start="1970-01-01", end="1990-01-01", interval="1mo", progress=False)
        return df.index.min()
    except Exception as e:
        print(f"{symbol} の取得でエラー: {e}")
        return None

# 実行
wti_start = get_earliest_date("CL=F")
jpy_start = get_earliest_date("JPY=X")

print("WTI原油の最古日:", wti_start)
print("ドル円の最古日:", jpy_start)

としたが

1 Failed download:
['CL=F']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')

1 Failed download:
['CL=F']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')

1 Failed download:
['JPY=X']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')

1 Failed download:
['JPY=X']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
WTI原油の最古日: NaT
ドル円の最古日: NaT

となる

これだと変わらないので
Csvをダウンロードしようとしたが
現在CSVダウンロードはできない

WTI原油先物(CL=F)」ではなく、W&T Offshore, Inc.(ティッカー: WTI) という個別株の履歴ページがるので注意

項目 正しいWTI原油先物 間違いやすいW&T Offshore株
正式名称 WTI Crude Oil Futures W&T Offshore, Inc.
シンボル CL=F WTI
内容 原油先物価格(NYMEX) エネルギー会社の株価
利用目的 原油価格の分析 企業株の投資分析

Yahoo Finance の WTI原油先物(CL=F) に関する正しいデータであり、取得可能な最古の日付は 2000年8月23日

試しに
yfinance api で一番古いデータから3カ月分だけ取得する

import yfinance as yf
import pandas as pd
import sqlite3

# === データ取得範囲 ===
start_date = pd.Timestamp("2000-08-23")
end_date = start_date + pd.Timedelta(days=90)

# === データ取得 ===
df = yf.download("CL=F", start=start_date, end=end_date, progress=False)

# 日付インデックスをリセットして通常の列に
df.reset_index(inplace=True)

# === SQLiteに保存 ===
db_path = "commodities.db"
table_name = "wti_first_3months"

# 不要なNaN行削除
df = df.dropna(subset=["Date"])

with sqlite3.connect(db_path) as conn:
    df.to_sql(table_name, conn, if_exists="replace", index=False)

print(f"{len(df)} 件のWTI原油データを {db_path} の {table_name} に保存しました。")

を実行すると

1 Failed download:
['CL=F']: YFRateLimitError('Too Many Requests. Rate limited. Try after a while.')
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/wti/earliest_rate.py", line 20, in <module>
    df = df.dropna(subset=["Date"])
         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/snowpool/.pyenv/versions/3.11.0/lib/python3.11/site-packages/pandas/core/frame.py", line 6670, in dropna
    raise KeyError(np.array(subset)[check].tolist())
KeyError: ['Date']

これを元に修正する

import yfinance as yf
import pandas as pd
import sqlite3

# === データ取得範囲 ===
start_date = pd.Timestamp("2000-08-23")
end_date = start_date + pd.Timedelta(days=90)

# === データ取得 ===
try:
    df = yf.download("CL=F", start=start_date, end=end_date, progress=False)

    if df.empty:
        print("⚠ データ取得に失敗しました(アクセス制限などの可能性あり)")
    else:
        df.reset_index(inplace=True)

        # 安全に 'Date' カラムの存在確認
        if "Date" in df.columns:
            df = df.dropna(subset=["Date"])
        else:
            print("⚠ 'Date' カラムが見つかりません。保存せず終了します。")
            exit()

        # === SQLiteに保存 ===
        db_path = "commodities.db"
        table_name = "wti_first_3months"

        with sqlite3.connect(db_path) as conn:
            df.to_sql(table_name, conn, if_exists="replace", index=False)

        print(f"✅ {len(df)} 件のWTI原油データを {db_path} の {table_name} に保存しました。")

except Exception as e:
    print(f"❌ 予期せぬエラー: {e}")

データが古すぎて取れない可能性がある

調べた結果、

https://web-dev.hatenablog.com/entry/python/yfinance/error/rate-limit
yfinance エラー対応方法「Too Many Requests. Rate limited.」
にあるように

pip install --upgrade yfinance

を実行しバージョンをアップすると解決した

実行時のログは

Installing collected packages: curl_cffi, yfinance
  Attempting uninstall: yfinance
    Found existing installation: yfinance 0.2.52
    Uninstalling yfinance-0.2.52:
      Successfully uninstalled yfinance-0.2.52
Successfully installed curl_cffi-0.12.0 yfinance-0.2.65

どうやら 0.2.52だとエラーになるが
0.2.65だと解決しているらしい

試しに

import yfinance as yf

# リアルタイムのWTI価格を取得(1分間隔の最新データ)
wti = yf.Ticker("CL=F")
data = wti.history(period="1d", interval="1m").tail(1)  # 最新の1分データ
price = data['Close'].iloc[-1]  # 最新の終値
print(f"Current WTI Price: ${price}")

を実行

python wti.py  
Current WTI Price: $65.51000213623047

となって最新のWTI価格を取得できる