石川県能登地方の地震における緊急地震速報（予報）精度検証（2024年版）

この記事は [防災アプリ開発 Advent Calendar 2024](https://adventar.org/calendars/9939) の25日目です。
24日目は、[ことほの](https://x.com/kotoho76) さんの [深発地震でも予想震度を計算したい！](https://note.com/kotoho7/n/n910578ba15bb) でした。

# はじめに

2024年1月1日に石川県能登地方で発生したM7.6の地震は、最大震度7を観測し、2011年の東北地方太平洋沖地震以来およそ13年ぶりとなる大津波警報の発表をもたらすなど、内陸地震として歴史に名を残す地震となりました。

2024年1月1日の地震後、地震活動は活発化し、緊急地震速報（予報）も多数発表されました。ただ個人的に、全体的に予測震度が過大予測気味だったのでは？という疑問を抱いています。
そこでは、この記事では、2024年に発表された石川県能登地方周辺の緊急地震速報（予報）に焦点を絞り、震度の誤差をもとに精度検証を行います。

# 目的
* 「全体的に予測震度が過大予測気味だったのでは？」の正誤を統計的に明らかにする

# 手順
1. 対象の地震を抽出
1. 当該地震の、緊急地震速報（予報）最終報の最大震度と、地震情報の最大震度の差を誤差とする
1. 誤差の統計的特徴を見る

# 実際にやってみた
## 対象地震の抽出
### 計画
まず、時間範囲について、2024/01/01 00:00 〜 2024/12/23 23:59:59 のあいだに発生した地震とします。
次に、空間範囲として、地震情報における震央地名（震央地名コード）が以下のいずれかに該当するものとします。
* 新潟県上中越沖（379）
* 石川県能登地方（390）
* 石川県西方沖（494）
* 能登半島沖（495）
* 富山湾（497）
* 佐渡付近（498）

震度を比較することから、これらのうち、緊急地震速報（予報）の最終報において震度1以上が予測されており、かつ地震情報（震源・震度に関する情報）の発表された地震が対象となります。

### 取得
#### 準備
地震情報は気象庁の震度データベースでも取れそうですが、緊急地震速報（予報）のデータはなかなか取りにくいものです。そこで今回も [DMDATA.JP](https://dmdata.jp/) に頼ります。
過去データを用いることから [GD Earthquake API](https://dmdata.jp/docs/reference/api/v2/gd.earthquake.list) および [GD Eew API](https://dmdata.jp/docs/reference/api/v2/gd.eew.list) を利用します。

ということで、以下の2つの権限を許可したAPIキーを発行しておきます。
```
gd.earthquake
gd.eew
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/54758ee0-d4cd-1623-5f47-99af996aeb9b.png)

#### 取得

APIキーを利用して、勢いで取得します。
後続のフローで取得した結果をまたPythonで処理することから、pickleで保存します。

なおここでは100件ずつ取得していますが、仮にレスポンス対象が100件を超える際は `nextToken` が出現し、続きをこのtokenを利用して取得するdmdataの仕様があります。地震情報は対応しましたが、緊急地震速報では100件を超える事例がなかったことを確認していますので、ここでは実装を省略しています。


```python
import json
import pickle
import time
import urllib.parse
from datetime import date, timedelta

import requests
from requests.auth import HTTPBasicAuth

DMDATA_API_KEY = "（ここにAPIキー）"


def main():
    epi_codes = ["379", "390", "494", "495", "497", "498"]
    start = date(2024, 1, 1)
    end = date(2024, 12, 24)

    eqlist = get_eqlist(epi_codes, start, end)
    with open("eqlist_tb.pickle", 'wb') as f:
        pickle.dump(eqlist, f)

    eewlist = get_eewlist(epi_codes, start, end)
    with open("eewlist_tb.pickle", 'wb') as f:
        pickle.dump(eewlist, f)


def get_eqlist(codes: list[str], start: date, end: date) -> list:
    """地震情報リストを取得する"""

    items = []

    for date in get_date_range(start, end):
        print(date, end="")

        nextToken = ""

        while True:
            params = {
                "date": date.strftime("%Y-%m-%d"),
                "limit": 100
            }
            if nextToken:
                params["cursorToken"] = nextToken

            query = urllib.parse.urlencode(params)
            res = requests.get(f"https://api.dmdata.jp/v2/gd/earthquake?{query}", auth=HTTPBasicAuth(DMDATA_API_KEY, ""))

            res_json = json.loads(res.text)
            res_items = res_json["items"]

            # 震源の決まっていないイベントを除外
            target_items = [item for item in res_items if "hypocenter" in item]

            # 対象の震央地名コードで絞る
            target_items = [item for item in target_items if item["hypocenter"]["code"] in codes]

            print(f" -> {len(target_items)}個追加", end="")
            items.extend(target_items)

            # 待機
            interval = res_json["nextPoolingInterval"]
            time.sleep(interval / 1000)

            # nextToken
            if "nextToken" in res_json:
                nextToken = res_json["nextToken"]
            else:
                print()
                break
    return items


def get_eewlist(codes: list[str], start: date, end: date) -> list:
    """緊急地震速報（予報）リストを取得する"""

    items = []

    for date in get_date_range(start, end):
        print(date, end="")

        next_date = date + timedelta(days=1)
        params = {
            "datetime": f"{date.strftime('%Y-%m-%d')}T00:00:00~{next_date.strftime('%Y-%m-%d')}T00:00:00",
            "limit": 100
        }
        query = urllib.parse.urlencode(params)
        res = requests.get(f"https://api.dmdata.jp/v2/gd/eew?{query}", auth=HTTPBasicAuth(DMDATA_API_KEY, ""))

        res_json = json.loads(res.text)
        res_items = res_json["items"]

        # キャンセル報を除外
        target_items = [item for item in res_items if not item["isCanceled"]]

        # 対象の震央地名コードで絞る
        target_items = [item for item in target_items if item["earthquake"]["hypocenter"]["code"] in codes]

        print(f" -> {len(target_items)}個追加")
        items.extend(target_items)

        # 待機 2秒固定
        time.sleep(2)
    return items


def get_date_range(start, stop, step=timedelta(1)):
    """from: https://qiita.com/ground0state/items/508e479335d82728ef91 """

    current = start
    while current < stop:
        yield current
        current += step


if __name__ == "__main__":
    main()

```

これを実行することで、カレントディレクトリに `eqlist.pickle` と `eewlist.pickle` が生成されました。
生成に掛かった時間は、地震情報が15分程度（ `nextPoolingInterval` が毎回おおよそ2500msでした）、緊急地震速報が12分程度（2秒固定スリープ）でした。

### 結合

ここでは、地震情報と緊急地震速報（予報）をそれぞれ `eqlist.pickle` と `eewlist.pickle` から取得し、その双方が存在している地震、すなわち緊急地震速報（予報）が出て地震情報も出た地震に絞り、それぞれを結合します。
取得結果は、イベントIDを1列目に、震度階級誤差を8列目にもつCSVファイル `output.csv` に保存します。

ここで震度階級誤差は、過大予想（緊急地震速報の予想震度が地震情報の実測震度より大きい）の場合に正の値を、過小予想の場合に負の値を返します。

```python
import csv
import dataclasses
import pickle
import time


@dataclasses.dataclass
class EventData:
    max_int: str | None
    epi_name: str | None = None
    lat: float | None = None
    lon: float | None = None
    magnitude: float | None = None


def main():
    with open("eqlist.pickle", "rb") as f:
        eqlist = pickle.load(f)

    with open("eewlist.pickle", "rb") as f:
        eewlist = pickle.load(f)

    eqmap = to_eqmap(eqlist)
    eewmap = to_eewmap(eewlist)

    # 地震情報も緊急地震速報もあるイベントを抽出
    id_list = list(set(eqmap.keys()) & set(eewmap.keys()))

    with open("output.csv", "w") as f:
        writer = csv.writer(f)
        writer.writerow(["eventId", "epiName", "Lat", "Lon", "Magnitude", "eqMaxInt", "eewMaxInt", "intError"])

        for id in sorted(id_list):
            eq = eqmap[id]
            eew = eewmap[id]

            if not eq.max_int or not eew.max_int:
                continue

            error = calc_int_error(eew.max_int, eq.max_int)
            writer.writerow([id, eq.epi_name, eq.lat, eq.lon, eq.magnitude, eq.max_int, eew.max_int, error])


def to_eqmap(eqlist):
    """地震情報を辞書に変換"""

    map: dict[str, EventData] = {}
    for eq in eqlist:
        id = eq["eventId"]
        hypo = eq["hypocenter"]
        epi_name = hypo["name"]
        coord = hypo["coordinate"]
        lat = float(coord["latitude"]["value"])
        lon = float(coord["longitude"]["value"])
        magnitude = float(eq["magnitude"]["value"])
        max_int = eq["maxInt"]

        map[id] = EventData(max_int, epi_name, lat, lon, magnitude)

    return map


def to_eewmap(eqlist):
    """緊急地震速報（予報）を辞書に変換"""

    map: dict[str, EventData] = {}
    for eq in eqlist:
        id = eq["eventId"]

        if "intensity" in eq:
            int_to = eq["intensity"]["forecastMaxInt"]["to"]
            int_from = eq["intensity"]["forecastMaxInt"]["from"]

            if int_to == "over":
                max_int = int_from
            else:
                max_int = int_to
        else:
            max_int = None

        map[id] = EventData(max_int)

    return map


def calc_int_error(est: str, obs: str):
    """震度階級誤差を計算"""

    jma_int_list = ["0", "1", "2", "3", "4", "5-", "5+", "6-", "6+", "7"]
    return jma_int_list.index(est) - jma_int_list.index(obs)


if __name__ == "__main__":
    main()

```

### 抽出結果
`output.csv` は以下のようになりました。合計件数は386件でした。

<details><summary>クリックして展開…</summary>

```plaintext
EventId,EpiName,Lat,Lon,Magnitude,EqMaxInt,EewMaxInt,IntError
20240101160608,石川県能登地方,37.5,137.3,5.7,5+,5+,0
20240101161010,石川県能登地方,37.495,137.27,7.6,7,7,0
20240101161845,石川県能登地方,37.2,136.9,6.1,5+,6-,1
20240101163246,石川県能登地方,37.3,137.0,4.8,3,4,1
20240101163953,新潟県上中越沖,37.5,137.5,5.2,4,4,0
20240101164236,石川県能登地方,37.4,137.2,5.2,4,4,0
20240101164552,佐渡付近,37.9,137.8,4.7,3,3,0
20240101164756,石川県能登地方,37.3,136.9,5.0,4,4,0
20240101165652,石川県能登地方,37.3,136.9,5.7,5+,5+,0
20240101170243,石川県能登地方,37.4,137.0,4.9,4,4,0
20240101170713,能登半島沖,37.2,136.6,5.2,4,4,0
20240101171750,石川県能登地方,37.5,137.2,4.6,4,4,0
20240101172214,能登半島沖,37.5,137.1,4.8,5-,5-,0
20240101174834,佐渡付近,38.0,137.7,4.7,3,3,0
20240101180353,能登半島沖,37.6,137.4,5.3,5-,5-,0
20240101180618,新潟県上中越沖,37.6,137.5,4.7,3,4,1
20240101180821,能登半島沖,37.6,137.4,5.6,5-,6+,3
20240101181418,石川県能登地方,37.5,137.2,4.3,3,4,1
20240101182309,石川県能登地方,37.3,137.2,4.4,4,4,0
20240101183027,能登半島沖,37.6,137.4,4.9,4,5-,1
20240101184002,能登半島沖,37.1,136.6,4.7,5-,4,-1
20240101184401,石川県能登地方,37.3,136.8,3.8,3,3,0
20240101184531,佐渡付近,37.7,137.7,4.8,3,2,-1
20240101185240,佐渡付近,37.7,137.5,3.9,3,3,0
20240101185342,石川県能登地方,37.5,137.3,4.1,3,3,0
20240101190020,能登半島沖,37.5,137.4,3.9,3,3,0
20240101202543,石川県能登地方,37.3,137.0,3.5,2,2,0
20240101202739,石川県能登地方,37.4,136.9,4.2,3,3,0
20240101203244,石川県能登地方,37.4,137.0,3.8,3,3,0
20240101204159,能登半島沖,37.5,137.1,3.7,3,3,0
20240101205728,能登半島沖,37.6,137.4,4.5,2,3,1
20240101211332,石川県能登地方,37.4,137.1,4.1,2,3,1
20240101211702,石川県能登地方,37.3,136.8,4.0,2,3,1
20240101212048,石川県能登地方,37.5,137.2,4.5,4,4,0
20240101220206,石川県能登地方,37.3,137.0,3.5,3,3,0
20240101221059,石川県能登地方,37.4,137.1,4.6,3,4,1
20240101222827,能登半島沖,37.1,136.6,3.8,3,3,0
20240101230056,石川県能登地方,37.3,136.9,3.7,2,3,1
20240101230402,佐渡付近,37.7,137.7,4.6,3,3,0
20240101231928,能登半島沖,37.5,137.4,4.2,3,4,1
20240101233037,石川県能登地方,37.2,136.7,4.3,4,3,-1
20240101235828,能登半島沖,37.2,136.6,3.7,3,3,0
20240102000837,石川県能登地方,37.5,137.3,4.5,4,4,0
20240102002443,石川県能登地方,37.3,137.0,3.7,2,2,0
20240102012936,石川県能登地方,37.5,137.2,3.5,2,3,1
20240102014234,佐渡付近,37.8,137.6,4.2,2,3,1
20240102014328,能登半島沖,37.6,137.4,4.4,2,3,1
20240102015904,石川県能登地方,37.5,137.2,3.3,2,3,1
20240102030200,能登半島沖,37.3,136.7,3.8,2,3,1
20240102030604,石川県能登地方,37.4,136.9,3.2,2,2,0
20240102032939,石川県能登地方,37.2,136.8,4.0,4,3,-1
20240102033358,石川県能登地方,37.4,137.0,3.9,3,3,0
20240102034704,石川県能登地方,37.0,136.8,3.7,3,3,0
20240102040226,石川県能登地方,37.3,136.8,4.0,2,3,1
20240102040543,能登半島沖,37.5,137.1,4.0,3,3,0
20240102042717,能登半島沖,37.1,136.6,4.7,3,3,0
20240102044213,能登半島沖,37.3,136.7,4.9,4,4,0
20240102045546,石川県能登地方,37.3,137.0,3.5,2,3,1
20240102050338,石川県能登地方,37.3,137.0,3.9,2,3,1
20240102055638,石川県能登地方,37.4,137.2,3.9,2,2,0
20240102063024,石川県能登地方,37.3,136.8,3.6,2,2,0
20240102063431,石川県能登地方,37.4,137.0,4.2,3,3,0
20240102071322,石川県能登地方,37.3,136.9,4.7,4,4,0
20240102072702,石川県能登地方,37.4,137.0,4.3,3,3,0
20240102073735,石川県能登地方,37.5,137.3,4.3,3,4,1
20240102074032,能登半島沖,37.2,136.6,3.5,2,2,0
20240102082102,石川県能登地方,37.4,137.0,3.6,2,3,1
20240102083508,石川県能登地方,37.2,136.7,3.4,2,2,0
20240102084228,石川県能登地方,37.3,137.0,3.9,2,3,1
20240102090137,能登半島沖,37.4,136.8,3.9,4,3,-1
20240102091427,石川県能登地方,37.4,137.2,4.7,4,4,0
20240102101738,石川県能登地方,37.2,136.7,5.6,5-,5-,0
20240102110357,石川県能登地方,37.2,136.7,3.7,3,2,-1
20240102111600,石川県能登地方,37.5,137.2,3.7,3,3,0
20240102111942,石川県西方沖,37.1,136.3,4.1,3,2,-1
20240102114200,能登半島沖,37.5,137.1,3.7,2,3,1
20240102114918,石川県能登地方,37.4,137.1,2.9,1,3,2
20240102115130,新潟県上中越沖,37.6,137.7,3.9,1,2,1
20240102130200,石川県能登地方,37.4,136.9,3.0,1,2,1
20240102134122,富山湾,37.4,137.3,3.5,2,3,1
20240102135006,石川県能登地方,37.2,136.7,3.3,1,2,1
20240102140202,能登半島沖,37.4,136.8,4.3,3,3,0
20240102150543,石川県能登地方,37.3,136.9,3.4,1,2,1
20240102155755,石川県能登地方,37.2,136.7,4.5,4,3,-1
20240102161111,石川県能登地方,37.2,136.7,3.0,1,2,1
20240102171347,能登半島沖,37.1383,136.633,4.6,5+,4,-2
20240102172312,石川県能登地方,37.3,136.8,2.9,1,2,1
20240102175209,佐渡付近,37.7,137.7,4.2,1,3,2
20240102175614,能登半島沖,37.3,136.7,4.2,2,3,1
20240102182547,石川県能登地方,37.2,136.7,3.2,1,2,1
20240102182939,石川県能登地方,37.5,137.3,4.3,3,4,1
20240102185013,佐渡付近,37.7,137.6,4.1,2,2,0
20240102200408,能登半島沖,37.5,136.9,3.7,1,2,1
20240102200620,石川県能登地方,37.2,136.7,3.0,1,2,1
20240102201323,石川県能登地方,37.3,136.8,3.0,1,2,1
20240102203055,石川県能登地方,37.4,137.1,3.3,1,2,1
20240102211324,石川県能登地方,37.3,136.9,4.3,3,3,0
20240102220329,石川県能登地方,37.3,136.8,3.6,3,3,0
20240102233859,石川県能登地方,37.4,137.1,3.5,1,3,2
20240103002402,石川県能登地方,37.2,136.7,3.2,2,3,1
20240103012111,能登半島沖,37.2,136.6,3.2,3,2,-1
20240103022151,石川県能登地方,37.4817,137.303,4.9,5+,5-,-1
20240103023033,石川県能登地方,37.5,137.3,4.4,4,4,0
20240103024913,石川県能登地方,37.4,137.2,3.3,1,3,2
20240103025440,石川県能登地方,37.4,137.1,3.9,2,3,1
20240103030007,石川県能登地方,37.5,137.3,3.2,2,3,1
20240103043927,石川県能登地方,37.3,136.8,2.9,1,2,1
20240103045008,石川県能登地方,37.2,136.7,3.3,2,2,0
20240103053644,石川県能登地方,37.2,136.7,3.5,2,3,1
20240103054724,新潟県上中越沖,37.6,137.5,3.5,2,2,0
20240103075152,石川県西方沖,37.1,136.5,4.0,2,2,0
20240103105438,石川県能登地方,37.3733,136.872,5.6,5+,5+,0
20240103114830,石川県能登地方,37.5,137.2,4.2,3,4,1
20240103123724,能登半島沖,37.2,136.6,4.2,3,3,0
20240103124823,佐渡付近,37.8,138.1,4.1,1,2,1
20240103125417,新潟県上中越沖,37.6,137.6,4.9,4,4,0
20240103134411,能登半島沖,37.6,137.4,4.1,1,3,2
20240103151744,石川県能登地方,37.5,137.3,3.4,1,3,2
20240103155217,能登半島沖,37.4,136.8,3.0,1,2,1
20240103160815,石川県能登地方,37.4,136.9,4.2,3,3,0
20240103171523,佐渡付近,37.7,137.6,4.0,1,2,1
20240103184804,石川県能登地方,37.3,136.8,4.8,4,5-,1
20240103190102,能登半島沖,37.2,136.6,3.7,2,3,1
20240103190754,石川県能登地方,37.5,137.2,3.7,2,3,1
20240103194215,石川県能登地方,37.2,136.7,4.0,3,3,0
20240103194916,新潟県上中越沖,37.6,137.5,4.1,2,4,2
20240103204840,石川県能登地方,37.4,137.2,3.8,3,3,0
20240103205500,能登半島沖,37.1,136.6,3.6,3,2,-1
20240103212841,石川県能登地方,37.5,137.3,3.8,1,4,3
20240103214248,石川県能登地方,37.2,136.7,3.2,2,3,1
20240103220949,佐渡付近,37.7,137.9,4.0,1,2,1
20240103233319,石川県能登地方,37.3,137.0,4.2,3,3,0
20240104001226,石川県能登地方,37.4,136.9,4.0,2,3,1
20240104002953,石川県能登地方,37.5,137.3,3.6,1,3,2
20240104003656,能登半島沖,37.5,137.1,4.8,4,4,0
20240104043850,佐渡付近,37.8,137.9,4.9,2,3,1
20240104055114,石川県能登地方,37.3,136.8,3.5,1,3,2
20240104060220,能登半島沖,37.1,136.7,2.7,2,2,0
20240104081138,石川県能登地方,37.2,136.9,3.4,2,2,0
20240104101002,石川県能登地方,37.4,137.2,4.1,3,4,1
20240104102426,石川県能登地方,37.4,137.1,3.5,1,3,2
20240104105146,能登半島沖,37.2,136.6,4.0,2,2,0
20240104122646,石川県能登地方,37.5,137.3,3.5,3,3,0
20240104150602,石川県能登地方,37.5,137.3,3.4,1,2,1
20240104154650,石川県能登地方,37.5,137.3,4.4,4,4,0
20240104155648,石川県能登地方,37.2,136.7,3.9,4,3,-1
20240104171642,佐渡付近,37.8,137.6,5.0,3,3,0
20240104202530,石川県能登地方,37.5,137.2,4.1,1,3,2
20240105000416,石川県能登地方,37.2,136.8,4.4,4,4,0
20240105013732,石川県能登地方,37.3,136.8,3.5,2,3,1
20240105071527,能登半島沖,37.1,136.6,2.6,2,2,0
20240105092734,石川県能登地方,37.2,136.7,4.1,3,2,-1
20240105093953,石川県能登地方,37.4,137.2,4.2,3,4,1
20240105095335,石川県能登地方,37.2,136.7,3.9,3,3,0
20240105102115,石川県能登地方,37.5,137.2,3.9,3,3,0
20240105105649,佐渡付近,37.8,137.7,3.9,1,2,1
20240105124616,能登半島沖,37.4,136.8,3.6,2,3,1
20240105131722,石川県能登地方,37.3,136.9,3.5,1,3,2
20240105134442,石川県能登地方,37.3,136.9,3.4,2,2,0
20240105141506,石川県能登地方,37.5,137.2,4.1,3,3,0
20240105150355,新潟県上中越沖,37.6,137.6,4.0,1,2,1
20240105151900,石川県能登地方,37.3,137.0,3.7,1,3,2
20240105153117,石川県能登地方,37.4,137.1,4.0,2,3,1
20240105174329,能登半島沖,37.1,136.7,3.5,3,3,0
20240105190917,石川県能登地方,37.5,137.2,3.8,3,3,0
20240105191053,能登半島沖,37.5,137.1,4.1,3,3,0
20240105220930,石川県能登地方,37.4,137.0,4.4,4,3,-1
20240105234837,石川県能登地方,37.5,137.3,3.6,3,3,0
20240106010603,石川県能登地方,37.4,136.9,3.7,2,3,1
20240106015909,能登半島沖,37.2,136.6,4.6,4,4,0
20240106052655,石川県能登地方,37.2167,136.832,5.4,5+,5-,-1
20240106053252,石川県能登地方,37.2,136.9,3.2,2,3,1
20240106053552,石川県能登地方,37.2,136.9,3.7,2,3,1
20240106054349,佐渡付近,37.8,137.7,4.1,1,3,2
20240106065716,能登半島沖,37.5,136.9,4.5,3,4,1
20240106150942,石川県能登地方,37.5,137.2,3.6,3,3,0
20240106182330,石川県能登地方,37.4,136.9,4.0,2,3,1
20240106215213,能登半島沖,37.5,137.4,3.9,2,3,1
20240106232024,能登半島沖,37.1717,136.645,4.3,6-,4,-3
20240107051826,石川県能登地方,37.5,137.3,3.2,2,3,1
20240107051903,石川県能登地方,37.5,137.3,3.7,1,4,3
20240107052655,石川県能登地方,37.3,136.9,3.4,2,2,0
20240107065728,石川県能登地方,37.3,136.8,3.2,2,2,0
20240107073831,能登半島沖,37.2,136.6,3.4,3,2,-1
20240107111921,能登半島沖,37.1,136.7,3.4,1,2,1
20240107143802,石川県能登地方,37.5,137.3,4.5,4,5-,1
20240107152658,石川県能登地方,37.2,136.7,4.5,4,4,0
20240107213822,石川県能登地方,37.2,136.8,4.7,4,4,0
20240107234402,石川県能登地方,37.4,136.9,4.0,3,3,0
20240108025923,石川県能登地方,37.4,137.1,3.7,2,3,1
20240108031543,石川県能登地方,37.3,136.8,3.6,2,3,1
20240108061836,新潟県上中越沖,37.6,137.6,3.8,1,3,2
20240108094922,能登半島沖,37.4,136.8,3.5,2,2,0
20240108110505,石川県能登地方,37.1,136.8,3.7,2,3,1
20240108131501,石川県能登地方,37.2,136.8,2.9,1,2,1
20240108183537,佐渡付近,37.7,137.6,3.5,1,2,1
20240109012003,石川県能登地方,37.3,136.8,3.7,2,3,1
20240109131255,石川県能登地方,37.2,136.8,3.7,3,3,0
20240109141916,新潟県上中越沖,37.6,137.6,3.7,1,2,1
20240109175919,佐渡付近,37.9,137.8,6.0,5-,5-,0
20240109184542,石川県能登地方,37.2,136.8,3.0,1,2,1
20240109185518,佐渡付近,37.8,137.8,4.4,2,2,0
20240109191057,佐渡付近,37.9,137.8,3.9,1,2,1
20240109201056,佐渡付近,37.8,137.8,4.2,2,3,1
20240110085415,佐渡付近,37.9,137.8,4.0,1,2,1
20240110085844,能登半島沖,37.1,136.6,3.4,1,2,1
20240110091639,佐渡付近,37.8,137.8,3.6,1,2,1
20240110200038,石川県能登地方,37.4,137.0,4.1,3,3,0
20240110200247,佐渡付近,37.8,137.7,4.0,1,2,1
20240111043228,佐渡付近,37.9,137.7,4.1,1,2,1
20240111075752,石川県能登地方,37.5,137.2,3.4,1,3,2
20240111122143,佐渡付近,37.9,137.8,3.5,1,2,1
20240112055436,新潟県上中越沖,37.6,137.6,4.2,1,3,2
20240112105856,石川県能登地方,37.2,136.8,3.1,1,2,1
20240112160103,石川県能登地方,37.2,136.8,3.5,3,2,-1
20240112172913,石川県能登地方,37.5,137.3,4.4,3,4,1
20240112191929,石川県能登地方,37.2,136.7,2.8,1,2,1
20240112211024,石川県能登地方,37.2,136.7,4.4,4,3,-1
20240113040431,石川県能登地方,37.2,136.8,4.4,4,4,0
20240113075129,石川県能登地方,37.4,136.9,3.5,2,3,1
20240113092107,佐渡付近,37.7,137.7,4.0,1,2,1
20240114000133,石川県能登地方,37.2,136.8,4.4,3,3,0
20240114074243,石川県能登地方,37.2,136.8,3.0,1,2,1
20240115011101,石川県能登地方,37.2,136.8,3.4,2,3,1
20240115090908,石川県能登地方,37.5,137.3,3.2,1,3,2
20240115095904,石川県能登地方,37.3,136.8,3.4,2,3,1
20240115153729,石川県能登地方,37.2,136.8,3.4,1,2,1
20240116041134,石川県能登地方,37.2,136.8,3.4,3,3,0
20240116184216,石川県能登地方,37.2,136.7,4.8,5-,5+,1
20240116220222,石川県能登地方,37.5,137.2,3.7,2,3,1
20240117040158,石川県能登地方,37.3,136.9,3.5,3,3,0
20240117183239,石川県能登地方,37.4,137.0,3.1,1,2,1
20240118105146,佐渡付近,37.8,137.7,4.1,1,3,2
20240118173111,石川県能登地方,37.4,137.0,3.4,2,2,0
20240119030443,石川県能登地方,37.4,137.0,4.5,4,4,0
20240119070610,能登半島沖,37.1,136.7,4.3,4,3,-1
20240119120249,石川県能登地方,37.4,137.1,4.1,2,3,1
20240119154836,石川県能登地方,37.4,137.2,4.1,3,3,0
20240119202238,佐渡付近,37.7,137.5,4.3,2,3,1
20240119220622,佐渡付近,37.9,137.7,4.2,2,2,0
20240122160042,能登半島沖,37.4,136.6,4.1,2,2,0
20240123021320,石川県能登地方,37.2,136.7,4.2,3,3,0
20240125092451,石川県能登地方,37.5,137.3,3.2,2,3,1
20240125111551,能登半島沖,37.3,136.7,3.6,2,3,1
20240126093242,石川県能登地方,37.3,136.9,4.2,3,3,0
20240126144006,能登半島沖,37.2,136.6,4.5,4,4,0
20240127023355,石川県能登地方,37.2,136.8,3.4,2,2,0
20240127045330,石川県能登地方,37.2,136.8,3.3,1,2,1
20240130120922,石川県能登地方,37.5,137.3,2.9,2,3,1
20240131125524,石川県能登地方,37.5,137.3,3.1,2,3,1
20240201080716,能登半島沖,37.4,136.8,4.4,3,3,0
20240201134334,石川県西方沖,37.0,136.4,4.1,2,2,0
20240201141033,佐渡付近,37.9,137.8,4.0,1,2,1
20240202014532,石川県能登地方,37.2,136.9,3.9,3,3,0
20240202205057,能登半島沖,37.6,137.4,3.2,1,3,2
20240203051314,能登半島沖,37.3,136.7,3.6,2,3,1
20240203105945,石川県能登地方,37.3,136.8,3.0,1,2,1
20240203165456,石川県能登地方,37.5,137.2,3.1,1,2,1
20240203220906,能登半島沖,37.1,136.7,3.6,2,3,1
20240204011605,石川県能登地方,37.5,137.3,4.2,3,4,1
20240204064337,石川県能登地方,37.2,136.7,3.6,2,3,1
20240205005717,石川県能登地方,37.3,136.8,3.3,2,2,0
20240205113837,石川県西方沖,37.0,136.4,3.9,2,2,0
20240206022349,石川県能登地方,37.2,136.9,3.0,2,2,0
20240206115640,石川県能登地方,37.2,136.9,4.0,3,3,0
20240207060821,佐渡付近,37.7,137.6,5.1,4,4,0
20240208011342,石川県西方沖,37.0,136.4,3.9,1,2,1
20240209115853,石川県能登地方,37.3,136.9,2.8,1,2,1
20240210051854,能登半島沖,37.6,137.4,4.0,2,3,1
20240211003446,新潟県上中越沖,37.6,137.6,4.3,2,3,1
20240211123602,石川県能登地方,37.4,137.2,4.7,4,5-,1
20240211183520,佐渡付近,37.7,137.6,4.2,2,2,0
20240211232636,能登半島沖,37.1,136.7,3.2,2,2,0
20240211234855,能登半島沖,37.3,136.7,3.6,2,3,1
20240212042345,能登半島沖,37.6,137.4,3.5,1,3,2
20240214021331,石川県能登地方,37.5,137.3,3.0,1,3,2
20240214103256,石川県能登地方,37.2,136.8,4.5,4,4,0
20240214153421,能登半島沖,37.4,136.7,4.1,2,3,1
20240215124828,佐渡付近,37.9,137.8,5.1,3,3,0
20240215142241,石川県能登地方,37.2,136.9,2.7,2,2,0
20240215152948,新潟県上中越沖,37.6,137.6,5.0,3,4,1
20240215200027,新潟県上中越沖,37.6,137.6,4.3,2,3,1
20240216174954,石川県能登地方,37.5,137.2,3.2,2,2,0
20240217062334,石川県能登地方,37.2,136.8,3.3,3,2,-1
20240217071433,石川県能登地方,37.2,136.8,3.2,2,2,0
20240221035824,石川県能登地方,37.5,137.3,3.4,2,3,1
20240221113406,石川県能登地方,37.5,137.3,3.4,3,3,0
20240228161432,石川県能登地方,37.4,136.9,3.5,3,3,0
20240304173121,石川県能登地方,37.2,136.7,4.3,3,3,0
20240304174644,石川県能登地方,37.2,136.8,2.9,2,2,0
20240304214235,石川県能登地方,37.5,137.3,3.4,2,2,0
20240305111742,佐渡付近,37.7,137.7,4.1,1,2,1
20240305200149,能登半島沖,37.1,136.7,3.2,2,2,0
20240307154147,石川県能登地方,37.4,136.9,4.3,3,3,0
20240308203531,能登半島沖,37.4,136.7,3.3,1,2,1
20240309124727,石川県能登地方,37.4,137.1,3.9,2,3,1
20240313033159,能登半島沖,37.1,136.7,4.0,3,3,0
20240314145621,石川県能登地方,37.4,137.1,3.3,1,2,1
20240315192811,石川県能登地方,37.5,137.2,3.5,2,3,1
20240319192111,石川県能登地方,37.5,137.3,3.2,1,3,2
20240323025605,能登半島沖,37.6,137.4,4.4,2,4,2
20240329001440,石川県能登地方,37.2,136.8,3.0,1,2,1
20240330170523,石川県能登地方,37.3,136.9,3.0,1,2,1
20240402172440,石川県能登地方,37.4,136.9,3.5,3,3,0
20240403105641,石川県能登地方,37.2,136.9,3.4,3,2,-1
20240408222929,石川県能登地方,37.5,137.2,4.1,3,3,0
20240409202655,石川県能登地方,37.5,137.3,2.9,2,3,1
20240411131618,石川県能登地方,37.5,137.2,3.7,2,3,1
20240414083213,石川県能登地方,37.2,136.8,3.2,2,2,0
20240418144149,能登半島沖,37.5,137.1,3.2,1,2,1
20240419205554,石川県能登地方,37.5,137.2,3.1,1,2,1
20240424114215,石川県能登地方,37.2,136.7,3.4,2,3,1
20240428182804,佐渡付近,37.8,137.7,4.0,1,2,1
20240430000853,石川県能登地方,37.5,137.3,3.2,2,3,1
20240430162457,石川県能登地方,37.5,137.2,3.3,1,3,2
20240508065346,能登半島沖,37.6,137.4,3.7,1,3,2
20240510185016,石川県能登地方,37.4,136.9,3.8,3,3,0
20240603063142,石川県能登地方,37.4667,137.302,6.0,5+,6+,2
20240603064022,能登半島沖,37.5,137.4,4.8,4,4,0
20240603064546,能登半島沖,37.5,137.4,3.7,2,3,1
20240603064940,石川県能登地方,37.5,137.3,3.2,2,3,1
20240603065035,富山湾,37.4,137.3,3.2,1,3,2
20240603065434,石川県能登地方,37.5,137.3,3.4,2,3,1
20240603070902,石川県能登地方,37.5,137.3,2.8,1,3,2
20240603080326,石川県能登地方,37.5,137.3,3.1,1,3,2
20240608080828,佐渡付近,37.9,137.7,3.7,1,2,1
20240611061258,能登半島沖,37.6,137.4,3.4,1,3,2
20240612072401,石川県能登地方,37.5,137.3,4.1,3,4,1
20240618210422,石川県能登地方,37.3,136.8,3.2,1,2,1
20240619112431,石川県能登地方,37.3,136.9,3.4,2,2,0
20240627032400,石川県能登地方,37.4,137.0,3.7,2,3,1
20240628005517,石川県能登地方,37.3,136.9,2.6,1,1,0
20240701123235,佐渡付近,37.7,137.6,4.2,1,2,1
20240705140856,石川県西方沖,37.0,136.6,4.1,2,3,1
20240711120124,富山湾,37.0,137.5,4.6,3,3,0
20240731144330,石川県能登地方,37.3,136.9,3.0,1,2,1
20240809031720,能登半島沖,37.4,136.8,3.1,1,2,1
20240809135630,石川県能登地方,37.4,136.9,3.1,2,2,0
20240827171314,佐渡付近,37.7,137.7,3.9,1,2,1
20240829111727,石川県能登地方,37.4,137.0,4.0,3,3,0
20241001051139,石川県能登地方,37.5,137.2,3.5,1,3,2
20241009201945,能登半島沖,37.6,137.4,4.2,2,4,2
20241018074033,能登半島沖,37.5,137.4,3.1,2,3,1
20241101102329,石川県能登地方,37.2,136.9,3.0,1,2,1
20241111110013,能登半島沖,37.4,136.8,2.7,1,2,1
20241123083353,石川県能登地方,37.4,136.9,3.1,2,2,0
20241126224709,石川県西方沖,37.0083,136.397,6.6,5-,5+,1
20241126231356,石川県西方沖,37.0,136.4,4.3,2,2,0
20241126231725,石川県西方沖,37.0,136.4,3.9,2,2,0
20241126233304,石川県西方沖,37.0,136.4,4.1,2,2,0
20241126233656,石川県西方沖,37.0,136.5,3.6,1,2,1
20241126235257,石川県西方沖,37.0,136.4,4.9,3,3,0
20241127001758,石川県西方沖,37.0,136.4,3.8,2,2,0
20241127003034,石川県西方沖,37.0,136.4,3.7,2,2,0
20241127014819,石川県西方沖,36.9,136.4,4.1,2,2,0
20241127021952,石川県西方沖,37.0,136.4,4.9,3,3,0
20241127022253,石川県西方沖,37.0,136.4,4.0,2,2,0
20241127035547,石川県西方沖,37.0,136.4,4.2,1,2,1
20241127041727,石川県西方沖,37.0,136.4,3.8,2,2,0
20241127064511,石川県西方沖,37.0,136.4,3.4,1,2,1
20241127112902,石川県西方沖,37.0,136.4,4.0,2,2,0
20241127124826,石川県西方沖,37.0,136.4,3.9,2,2,0
20241127130414,石川県西方沖,36.9,136.4,4.1,1,2,1
20241127150128,石川県西方沖,37.0,136.4,4.2,2,2,0
20241127160553,石川県西方沖,37.0,136.4,3.7,2,2,0
20241128003258,石川県西方沖,36.9,136.4,4.3,3,2,-1
20241128061448,石川県西方沖,37.0,136.4,3.8,2,2,0
20241128171657,石川県西方沖,37.0,136.4,3.7,1,2,1
20241128173112,石川県西方沖,36.9,136.4,4.8,4,3,-1
20241128201951,石川県西方沖,36.9,136.4,3.7,2,2,0
20241129125734,石川県能登地方,37.5,137.2,3.7,2,3,1
20241129182205,石川県西方沖,36.9,136.4,4.0,1,2,1
20241130095234,石川県西方沖,37.1,136.4,4.9,3,3,0
20241130174008,石川県西方沖,37.0,136.4,3.9,2,2,0
20241130180634,石川県西方沖,37.0,136.4,4.3,2,2,0
20241201112132,石川県西方沖,37.0,136.4,4.2,2,3,1
20241201131503,石川県西方沖,37.1,136.4,3.8,1,2,1
20241201164138,石川県能登地方,37.5,137.2,3.2,2,3,1
20241202083959,佐渡付近,37.7,137.7,4.1,1,2,1
20241202092057,石川県西方沖,37.0,136.4,4.1,2,2,0
20241202092407,石川県西方沖,37.1,136.4,3.9,1,2,1
20241204060549,石川県西方沖,37.0,136.4,4.0,2,2,0
20241207202745,石川県西方沖,36.9,136.4,3.4,1,2,1
20241208225852,石川県西方沖,36.9,136.4,4.2,2,2,0
20241218003844,石川県能登地方,37.5,137.3,3.2,2,3,1
20241221170133,石川県能登地方,37.2,136.7,2.5,1,2,1
```
</details>

## 統計
### 全体傾向

ヒストグラムで見てみましょう。
だんだん疲れてきたので、ChatGPTに「ヒストグラム描いて〜ついでに平均値も描いて〜」とお願いしたものをベースに手直ししました。

```python
import csv

import matplotlib.pyplot as plt
import numpy as np


def main():
    with open('output.csv') as f:
        reader = csv.DictReader(f)
        l = [row for row in reader]

    # 震度誤差
    errors = [int(x["IntError"]) for x in l]

    # 平均値を計算
    mean_errors = np.mean(errors)

    # ヒストグラムを描画
    plt.hist(errors, bins=np.arange(-4.5, 4.5 + 1, 1), color="skyblue", edgecolor="black", alpha=0.7)

    # 平均値を描画 (縦線)
    plt.axvline(mean_errors, color='red', linestyle='dashed', linewidth=1.5, label=f'Mean = {mean_errors:.2f}')

    # x軸の目盛り設定
    plt.xticks(np.arange(-4, 4 + 1, 1))

    # グラフのタイトルとラベルを設定
    plt.title("JMA Seismic Intensity Error (All Events)")
    plt.xlabel('Error (Est - Obs)')
    plt.ylabel('Number')

    # 凡例を追加
    plt.legend()

    # グラフを表示
    plt.show()


if __name__ == "__main__":
    main()
```

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

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/5cab85d3-5692-25e2-665c-b541980ab3b4.png)


誤差の平均値は+0.55ということで、実測に比べて緊急地震速報（予報）はやや過大予測傾向にあることが統計的に証明されました。
ヒストグラムを見ると、1階級大きく予想しているイベントが、誤差が0であるイベントよりも僅かに多いことも分かりました。

### 震源地別

地域性を見るために、震源地ごとにヒストグラムを作ってみます。

### 石川県能登地方

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/e21b478a-bc1b-e880-8109-89b3d47d8901.png)

対象のほとんどが能登地方の地震なので、ほぼ全体傾向と同じですね。

### 石川県西方沖

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/b529f34a-c5a3-3f51-ba78-6684dd40be7f.png)

### 能登半島沖
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/de2cbb61-fb5b-d60f-9c6c-4b36a4d65c1e.png)

### 富山湾
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/31166706-1953-f4d1-89f2-b52c76622361.png)

対象が3件しかなく、いびつなヒストグラムとなっています。

### 新潟県上中越沖

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/716731fd-f0cd-a80e-eb7c-e347cbab1142.png)

### 佐渡付近
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/e7112e02-ad08-a219-ea73-7b4450b3c43a.png)

### 空間分布
`output.csv` をもとに、0.1度格子ごとの誤差の平均をGMT6でプロットしてみます。

```shell
awk -F',' 'NR > 1 { print $4, $3, $8 }' output.csv > tmp.txt

gmt begin avemap png
    gmt basemap -JM12 -R136/139/36.5/38.5 -Bafg -BWSne --FORMAT_GEO_MAP=DF

    gmt makecpt -Cpolar -T-2/2/0.05
    gmt colorbar -DJBR+jBL+o0.5/0+w10/0.2 -Baf+l"Error (Est - Obs)"

    gmt xyz2grd tmp.txt -Gdat.grd -I0.1 -R136/139/36.5/38.5

    gmt grdview dat.grd -JM12 -C -T+o+s
    gmt coast -Df -W0.25
gmt end
```

結果は以下の画像のようになりました。
赤色が強いほど過大予測の傾向、青色が強いほど過小予測の傾向にあることを示します。

![avemap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565515/48cf11d4-e3a1-4d4d-0cba-019eb1c6a38b.png)

こう見ると、やはり全体的に過大予測をしていることが分かります。

ただし、石川県西方沖のごく一部だけ、過小予測傾向にあります。
この地域で発生した地震は最大震度を「志賀町香能」観測点で観測する傾向にありますが、この観測点の地盤は周辺に比べて短周期がかなり卓越している特徴があります。それが影響してか、志賀町香能観測点の震度を予測すると過小予測傾向が強くなります。この影響が、志賀町香能で最大震度を観測しやすい石川県西方沖の地震に特徴として現れているのだと推測されます。

# おわりに
今回は、最大震度という1つのパラメータを用いて、緊急地震速報の精度検証を行いました。その結果、震度階級にして0.5程度、過大予測の傾向にあることが分かりました。
できることなら震度予測式を使って震度分布図を作り、どの地域が強く揺れるかなどの地域特性の検証もしてみたかったのですが、時間がなく出来ませんでした。また挑戦します。

2024年も防災アプリ開発アドベントカレンダーは以上となります。ご参加頂いた方、本当にありがとうございました。
是非また来年も、よろしくお願いします。