ktansai / COVID-19-ExposeChecker

94 stars 10 forks source link

COCOAがエクスポートする接触データの読み込みに対応する #70

Closed keiji closed 2 years ago

keiji commented 2 years ago

COCOAコントリビューターの有山と申します。いつもありがとうございます。 題の通り、COCOAでは内部で保存している接触データのエクスポート機能の搭載を計画しています。

エクスポートするログの読み込み機能をCOCOAログチェッカーに追加することで、非対応となったiOS端末でのログチェックを再び可能にできると考えますが、いかがでしょうか。

COCOAが利用している接触通知APIの更新で、iOSの接触チェックのログの形式が変わることは、正直に言って想定していませんでした。 接触データのエクスポート機能は、接触チェックログの MatchCountの代替となる手段にもなると考えています。

https://github.com/cocoa-mhlw/cocoa/issues/928

Issueにも書いたとおり、アプリが保存しているデータは基本的には利用者のもので、利用者が確認できる手段は設けておくのが良いと言う考え方に基づいたアイデアです。

また実務的には、接触データをどのように表示すると利用者にとってよりわかりやすくなるのか、試行錯誤の途中です。よりよい表示を検討するために、今現在どのような接触データがあり得るのか、利用者からのデータ提供を受ける手段を確保しておきたいという事情もあります。

ご検討のほど、よろしくお願いいたします。

ktansai commented 2 years ago

有山さん、お返事が遅れてすいません。

COCOAの方でログがエクスポートできるようになったら、ぜひ検討させてください。 また、COCOAログチェッカーだけではなく、他のウェブサービスなどでも対応しようとするものも出てくると思いますので、 ぜひ、そういった機能をCOCOA本体の方で進めていただけると、社会全体のためになると思います。

とはいえ、まず、ログがどういったデータが出力されるかが分からない時点では、どういった対応や表示をするのかが何も検討できませんので、COCOAの方で、エクスポートされるログデータの方が決まりましたら、お教えいただけますと助かります。

よろしくおねがいします。

keiji commented 2 years ago

昨日からCOCOA v2.0.1の段階的リリースが開始されています。

https://github.com/cocoa-mhlw/cocoa/releases/tag/v2.0.1

ログデータの仕様について、別途cocoa側でも公開しますが、ソースコード自体は公開なのでこちらでもまとめておきます。

COCOAが出力するログは概ね次のような形です(リンクは、COCOAが利用しているライブラリCappuccinoのものです)。

https://github.com/keiji/chino/wiki/Sample-ExposureData-Android-(Exposure-Window-mode)

接触についてはこのJSONファイルのdaily_summariesexposure_windowsキーを見ることになります。

  "daily_summaries": [
    {
      "DateMillisSinceEpoch": 1630281600000,
      "DaySummary": {
        "MaximumScore": 1380.0,
        "ScoreSum": 5700.0,
        "WeightedDurationSum": 5700.0
      },
      ...
  ],
  "exposure_windows": [
    {
      "CalibrationConfidence": 3,
      "DateMillisSinceEpoch": 1630281600000,
      "Infectiousness": 2,
      "ReportType": 2,
      "ScanInstances": [
        {
          "MinAttenuationDb": 14,
          "SecondsSinceLastScan": 300,
          "TypicalAttenuationDb": 15
        },
        {
          "MinAttenuationDb": 9,
          "SecondsSinceLastScan": 300,
          "TypicalAttenuationDb": 11
        },
        {
          "MinAttenuationDb": 9,
          "SecondsSinceLastScan": 240,
          "TypicalAttenuationDb": 11
        },
        {
          "MinAttenuationDb": 6,
          "SecondsSinceLastScan": 240,
          "TypicalAttenuationDb": 8
        },
        {
          "MinAttenuationDb": 36,
          "SecondsSinceLastScan": 300,
          "TypicalAttenuationDb": 41
        }
      ]
    },
    ...
  ]

元データとしてExposureWindowがあり、それを諸条件(Configuration)と合わせてDailySummaryを計算しています。

COCOAログチェッカーとしての役割(陽性者の端末から電波を受信していたかを示す)を実現するのであれば、ExposureWindowだけを表示するに留めるのが良いかと思います。

DailySummaryのMaximumScoreなどはいわゆるリスクスコアと呼ばれるものですが、リスクを数値化することについては慎重にならざるを得ません。ようするに「100は120よりどの程度リスクがあるのですか。20だったらリスクはないのですか?」という質問に答えるのは非常に難しいという事情があります。

特に、ぼくたちはエンジニアであって感染症対策の専門家ではないので、そのあたりに踏み込むことは極力避けた方が良い。COCOAログチェッカーも「陽性者の端末から電波を受信していたかを示す」と言う目的に限定するのが良いと考えています。

このコメントを更新する形で各値の説明を補足しつつ、ひとまずぼくのほうでPull Requestを作ってみようと思います。 また相談をさせてください。

keiji commented 2 years ago

@ktansai https://github.com/ktansai/COVID-19-ExposeChecker/pull/73#issuecomment-1156716685

こちらについて、Pull Requestよりライフタイムの長いIssueの方に書いた方がいいかなと思ったのでこちら側にお返事します。


データの保管期間について

COCOAの接触データは14日以前は無効化されていて、接触画面に表示されないようにしてありますが、実データとしては残っているので出力しています。 https://github.com/cocoa-mhlw/cocoa/issues/121

ただ、本来は残しておく意味はないデータなので、いつかは「15日以前のデータは定期的に消す」変更が入るものと思って頂ければと思います。 https://github.com/cocoa-mhlw/cocoa/issues/217

ちなみにぼくのPull Requestでは、15日以前のデータは結果に表示しないようにしてあります。

同日の接触の記録に、同一人物との接触が含まれるか

はい。理論上は含まれます。より厳密に言えば「同一端末との接触」ですね。 その上で、同日のExposureWindowが3つあったとして、それらがすべて同一端末との接触であるのか、すべて異なる端末との接触であるのか。またはその混合かについてはわかりません。推測する必要もないし、推測できることでプライバシーを侵害する可能性があるため、接触通知API Version 2は、その点は曖昧になるように作ってあると認識しています。

一方、confidenceという値は端末の電波調整の確信度(信頼度?)を表しています。ExposureWindowでこの値が違えば、一般的に考えれば異なる機種(端末)との接触であると判断しても良さそうです。が、繰り返しになりますが、同一人物か複数人かの判別は必要ないでしょうというのが接触通知API Version 2の考え方です。

その他のプロパティについて

ExposureWindowやDailySummaryの意味についてはすべてGoogle(およびApple)のドキュメントに記載があります。

https://developers.google.com/android/exposure-notifications/exposure-notifications-api#data-structures

ExposureWindow

たとえば、ExposureWindowのInfectiousnessは感染性です。COCOAでは、陽性と診断された人しか陽性情報登録を行わないので感染性の値は常にHIGH(2)になると認識してます。

ただ、感染性が高いに該当する値だと言って実際に感染しているはずだとか、そういうことではありません。本来は、接触した時期などさまざまな条件で感染性を切り替えを可能にするための接触通知APIの仕組みに過ぎないので、あまり深刻に捉えることのないように伝えていく必要がありそうです。

ReportTypeは届け出の種類に関する情報です。COCOAでは、基本的にCONFIRMED_TEST(1)です。 最近では「みなし陽性」もあるので一時期議論になりましたが、現状ではCONFIRMED_TESTだけで運用しています(ぼくが上にコメントしたJSONだと2になっていますが、これはテストのために発生させた接触なのでそのようになっています)。 https://github.com/cocoa-mhlw/cocoa/issues/842

CalibrationConfidenceは、前述したように、「その電波を発信していた端末の電波強度がどの程度信頼できるか」を示す値です。特にAndroidは端末毎に電波が強かったり弱かったり、少し傾けただけで電波強度が大きく変動するので、Googleは機種毎に伝播特性を計測した補正値を内部で持っています。 https://developers.google.com/android/exposure-notifications/ble-attenuation-computation https://developers.google.com/android/exposure-notifications/files/en-calibration-2020-08-12.csv

端末に補正値があれば信頼度は高くなりますし、未計測であれば信頼度は低くなります。

ScanInstancesは、ExposureWindowを構成する電波の受信をもう少し細かく示すものです。 基本的にAttenuation系は電波の減衰をdbで示すものです。またsecondsSinceLastScanは電波を受信していた秒数で、60秒刻みで最長300秒(5分)となります。 COCOAではScanInstancessecondsSinceLastScanを合算して接触時間として表示しています(Attenuationでカットしていません)。なので、複数人の陽性登録者と同日に接触していると、1日の接触時間がとても大きな値になってしまう事があります。 https://github.com/cocoa-mhlw/cocoa/issues/967

DailySummary

DailySummaryは、ExposureWindowとexposure_configurationのキーで示される設定値を組み合わせて計算されます。接触通知APIが計算するもので、計算式は公開されています。 https://developer.apple.com/documentation/exposurenotification/enexposureconfiguration

DailySummaryのスコアが高いと、一般的にはより近い距離で、または長い時間接触したことを意味します。一方で、スコアが高いから感染の危険が高いとシンプルに結びつけることもできません(ここが接触通知アプリの難しいところです)。


個人的にはDailySummaryは使わず、まずはExposureWindowで日付だけ見ておくのが良いかと思います。

発展系としてCOCOAのように接触時間の総計を表示したり、各ScanInstanceのAttenuationを活用して、よりグラフィカルな表示ができるといいなと夢想したりします。ただ、それが利用者が求めているものか。また詳しく表示しすぎることで逆に不安につながらないか。と言う点は十分に気をつける必要がありますね。

長くなりましたが、他にも何かあれば聞いてください。 よろしくお願いします。

daisuke-nogami commented 2 years ago

ちょっとだけ、元々のPull-requestについている質問文そのものに対する回答を追記します

先程のSpreadsheetのデータを見ると、3/24に3回記録がありますが、これは、別々のユニークな端末と3回すれ違ったという理解になりますでしょうか? それとも、同一端末でも、時間を開けて、3回通信しても、記録されるものなのでしょうか?

この3回が、違うExposure Windowにあった場合の説明は前述の通りですが、 同じExposure Windowの中にあった場合には、同じ端末とのすれ違いを示します。 そして、3回すれ違ったのではなく、1回のすれ違いを3つに分解して表示しています。

ktansai commented 2 years ago

@keiji @daisuke-nogami お返事ありがとうございます。間が空いてしまってすいません。 色々読み解いて、教えていただいた内容は概ね理解できました。かなりクリアになりました。ありがとうございます。 一旦、頂いたPRはマージさせていただいて、別途、使い方や、アナウンスを追加させていただこうと思います。 できれば、6月中に公開できればと思っています。(7月に入ってしまったらすいません)

ktansai commented 2 years ago

@keiji すいません、追加で1点質問になってしまうのですが、exposure_data.json の形式はiOS/Android共通でしょうか?

keiji commented 2 years ago

@ktansai はい。exposure_data.jsonの形式はiOS/Androidで共通になるように作っています!

ktansai commented 2 years ago

@keiji 了解です〜!ありがとうございます。

keiji commented 2 years ago

対応自体はmainに取り込まれたので、このIssueはCloseしようと思いますがいかがでしょうか。

注意書きとかはデータ形式とはレイヤーの違う別タスクという考え方ですが、そういうのも合わせて「読み込みに対応」と言うことならIssueは残しておきます。

ktansai commented 2 years ago

@keiji そうですね。PRは一旦マージしましたが、 次のリリースまで、注意書きなどを含めて、このissueに書くので良いかなと思っていました。 まだ、相談させていただくこともあるかも。と思っていました。 もし、別issueにしてしまったほうが良ければ、自分はそれでも大丈夫です。

先週〜今週時間があまり取れてなくて、進捗悪く、なかなかリリースまでお待たせしてしまって申し訳ないです。

keiji commented 2 years ago

このプロジェクトは @ktansai さんの善意で成り立っているものなので、ご自身のペースで進めていただくのが一番だと思います。

仰るとおり、今後、注意書きなどを追加する上で、データの解釈について追加の確認事項が出てくるかも知れないので、このIssueで進めましょう!

ktansai commented 2 years ago

と被ってしまっているのでこちらのissueは一旦closeさせていただきます。