R の統計解析結果を AI に解説させる

# R の統計解析結果を AI に解説させる統計ソフト (ウェブアプリ) を作って無料公開しました

プロンプトや実際のコード、AI のモデルによる違いなどの情報を載せてあります。

## 自己紹介

**[エミュイン合同会社](https://www.emuyn.net/)** で開発に関わっています。
ふだんは臨床医です。この記事が、Qiitaへの初投稿になります。
最近、弊社より **[ブラウザだけで使える無料統計ソフト Reactive stat](https://www.emuyn.net/stats)** をリリースしました。
信頼性の高い R で統計解析し、その結果を AI が解説します！
その背景には、統計に苦労している医療者の助けになりたい、という気持ちがあります。

## 医療における統計の環境

### 学会発表や学術論文では統計を避けて通れない

医師は、臨床以外に、学術活動として、学会発表や学術論文の記述をすることも求められます。専門医などの資格取得には、論文発表の業績を要求されることが一般的です。看護師も、学会などで看護研究の発表をします。
そこでは、多くの場合、統計解析が必要になります。

### 統計を授業で習ったことはあるけれど...

一般の医療従事者は、統計を授業で習ったことはあっても、普段は全く使いません。大学や一部の基幹病院は別として、大半の病院には、統計のことを相談できる人なんていません。
ですので、データを集めて統計解析をしたけれども、その結果を良く理解できないという場合がしばしばあります。

### よく使われている統計ソフト

現場でよく使われているのが [EZR](https://www.jichi.ac.jp/saitama-sct/SaitamaHP.files/statmed.html)という統計ソフトですが、非常によく考えられており、医療統計においてはスタンダードになっています。これは、R commanderを利用しており、Rがベースとなっています。
大学に所属していれば、[SAS JMP](https://www.jmp.com/ja_jp/home.html) など有料の統計ソフトのライセンスを使える場合があります。

### Rが最強

筆者は、EZRのベースにもなっているRが最強だと思います。無料ですし、多くの研究者がコミットしており、信頼性が高いです。
しかし、出てくる結果を見ても、統計に詳しくない向きにはよく意味がわからない、というのが現実です。
これはどんな統計ソフトでも基本的には同じです。

### 結果は出たけど、意味がよくわからないという問題をどう解決する？

そうだ、AIにお願いしよう！

## 具体例

新型コロナのパンデミックの初期には、PCRなどの検査の偽陽性や偽陰性の話題がお茶の間(死語？)のテレビ番組でも出ていましたよね。
さて、そのような検査の性能評価に用いられるROC曲線について、既存の試薬と新規試薬での結果を比較してみました。
(弊社で提供を開始した **[Reactive stat](https://www.emuyn.net/stats)** の出力になります。データは架空のサンプルデータです。)

### 統計解析結果

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781632/1a871111-6fdf-d0ab-bc68-a2eff301f811.png">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781632/74a0e7c7-8460-86b3-786e-1382716d557d.png">

```markdown:R の出力
#### ROC曲線 (Receiver Operating Characteristic curve)

設定

偽陽性に対する偽陰性の重みづけ: 1
想定される陽性率: 0.5

R 計算式
roc_curve <- pROC::roc(true_labels, predicted_scores, direction=auto)
pROC::auc(roc_curve)
pROC::coords(roc_curve, best, ret=threshold, best.method=youden, best.weights=c(1, 0.5), transpose = FALSE)

#### 従来法 ####

Setting levels: control = 0, case = 1
Setting direction: controls < cases

Area under the curve: 0.761

  threshold
1    10.765

#### 改良法 ####

Setting levels: control = 0, case = 1
Setting direction: controls < cases

Area under the curve: 0.9

  threshold
1    10.445
2    10.675
3    10.705


  Bootstrap test for two correlated ROC curves

data:  roc_curve1 and roc_curve2
D = -5.6, boot.n = 2000, boot.stratified = 1, p-value = 2.2e-08
alternative hypothesis: true difference in AUC is not equal to 0
sample estimates:
AUC of roc1 AUC of roc2 
    0.76135     0.90015 

--------------------------------------------------------------
Analysis is conducted using R version 4.4.0 (2024-04-24) 
The script uses the following packages and versions:
compiler 4.4.0
plyr 1.8.9
Rcpp 1.0.11
pROC 1.18.4
```

さて、いかがでしょうか？
...よくわかんないですよね。

### AI による解説

#### Claude-3-haiku に解説させてみました
実際に AI が出力してきたテキストを載せます。この内容が統計ソフトで表示されます。

> #### 統計手法:
> ROC (Receiver Operating Characteristic) 曲線は、二値分類問題における分類器の性能を評価する手法です。ROC 曲線は、真陽性率(sensitivity)と偽陽性率(1-specificity)をプロットしたものです。曲線下面積(AUC)は、分類器の総合的な性能を示す指標で、AUC が高いほど優れた分類性能を示します。本分析では、従来法と改良法の ROC 曲線を比較し、改良法の性能が有意に向上していることを確認しています。
>
> #### 結果の解説:
> この分析では、二つの ROC 曲線が比較されており、改良法の AUC が 0.90 と従来法の 0.76 に比べて有意に高いことが示されています。これは、改良法が従来法に比べて優れた分類性能を持っていることを意味しています。つまり、改良法を使うことで、より正確に真陽性を検出でき、偽陽性を抑えることができるということです。この結果から、改良法を採用することで、より効果的な分類が期待できると言えます。
>
> #### 効果量:
> AUC の違いが 0.90 - 0.76 = 0.14 であり、これは大きな効果量と言えます。ROC 曲線の AUC は 0.5 から 1.0 の範囲をとり、1.0 に近いほど優れた分類性能を示します。0.90 は非常に高い AUC 値であり、改良法が従来法に比べて優れた性能を発揮することが確認できました。
>
> #### 論文に書く場合の文章例:
> 本研究では、改良法を用いた ROC 曲線の AUC が 0.90 であり、従来法の 0.76 に比べて有意に高い性能を示したことから(p < 0.001)、改良法が優れた分類性能を持つことが明らかになりました。
>
> #### R のバージョン:
> この解析は R version 4.4.0 (2024-04-24) で行われました。

この解説があれば、統計を専門としていない方々にもRの出力結果を容易に理解していただくことができると思います。
また、論文や学会発表でどのように伝えれば良いかの例文もありますので、準備にかかる時間を大きく削減できます。
もちろん、AIですから、幻覚（ハルシネーション）には十分注意すべきです。ただ、この判断はユーザーに強いるのは、卵が先か鶏が先かという話になるので難しいかもしれません。一応プロンプトではある程度対策していますし、実際の回答を見てもあまり問題が無いように思えます。Claude3 はこの点で優秀ですが、今後のさらなる進化に期待しましょう！

#### Claude-3-opus にも解説させてみました
実際に AI が出力してきたテキストを載せます。

> #### 統計手法:
> ROC曲線（Receiver Operating Characteristic curve）は、二値分類モデルの性能を評価するための手法です。モデルの予測スコアに対して、感度（真陽性率）と特異度（真陰性率）の関係をプロットします。曲線下面積（AUC: Area Under the Curve）は、モデルの予測性能を表す指標で、0.5から1の値をとり、1に近いほど優れた予測性能を示します。最適な閾値は、感度と特異度のバランスが最も良い点として決定されます。ここでは、従来法と改良法の2つのモデルについてROC曲線が作成され、AUCと最適閾値が算出されています。また、2つのROC曲線の差異についてブートストラップ検定が行われています。
>
> #### 結果の解説:
> 従来法のAUCは0.761、改良法のAUCは0.900であり、改良法の方が高い予測性能を示しています。最適閾値は、従来法が10.765、改良法が10.445、10.675、10.705の3点となっています。ブートストラップ検定の結果、2つのROC曲線のAUCには有意な差があることが示されました（p = 2.2e-08）。以上より、改良法は従来法と比較して、より優れた二値分類の予測性能を有していると言えます。
>
> #### 論文に書く場合の文章例:
> ROC曲線解析の結果、改良法のAUCは0.900であり、従来法の0.761と比較して有意に高い値を示した（p < 0.001）。このことから、改良法は従来法よりも優れた二値分類の予測性能を有していることが明らかになった。
>
> #### R のバージョン:
> この解析は R version 4.4.0 (2024-04-24) で行われました。

こちらでは、**効果量** に関しては出力されていません。Rの結果に効果量が含まれていないと判断したようです。

#### Claude-3-haiku と Claude-3-opus の違い

本質的な部分での違いはなく、どちらもいわゆる幻覚を出力することはありませんでした。
しかし、同じ程度の文章量なのに、Claude-3-opus のほうが情報量が多いです。
逆に、Claude-3-haiku では AUC の差を効果量と判断できたのに対し、Claude-3-opus では見逃しています。

#### 実行時間、トークン、コスト

| Model                     | Model latency | Input Tokens | Output Tokens | Error | Cost    |
|---------------------------|---------------|--------------|---------------|-------|---------|
| claude-3-opus-20240229    | 24.20         | 961          | 679           | None  | $0.52 |
| claude-3-haiku-20240307   | 5.28          | 961          | 700           | None  | $0.011 |

Claude-3-haiku が Claude-3-opus の4倍以上早かったです。
値段は Claude-3-opus 50倍近く高いですね。無料で提供するにはちょっと高い...
迷わず **Claude-3-haiku を選択**することになりました。

### プロンプト

AI の API に送信したプロンプトは以下の通りです。
xml tag に出力させるように指示することで、コードで体裁を整えています。
試しに、```<answer-confidence>``` を自己評価させてみたところ、数値は概ね 90～100 でした。Claude3はかなりの自信家のようです。

```markdown:AI プロンプト
あなたは統計学、医療、心理学の分野で知識が豊富な教師である。
専門用語を正確に使い、統計学の初心者にもわかりやすく、正しい日本語を使って以下を出力せよ。

Rは統計ソフトであり、その出力結果が提供されるので、与えられたRの出力結果を読み取り、正確に理解せよ。
はじめに、使用されている統計手法（出力の「####」の部分に記載）について、詳細かつ簡潔に解説する文章を<method-explanation></method-explanation>に出力せよ。
次に、結果を簡潔にまとめ、その解釈をわかりやすく解説する文章を<result-interpretation></result-interpretation>に出力せよ。
次に、もし提供されたRの出力結果に効果量が含まれている場合、その意義について具体的に説明する文章を<effect_size></effect_size>に出力せよ。効果量の情報が含まれていなければ、<effect_size></effect_size>を出力しないこと。
次に、研究論文の執筆の際に、このRの結果を適切かつ科学的に表現する文章を<example-sentence></example-sentence>に出力せよ。
最後に、もしRの出力結果に "Analysis is conducted using R version..." のように書かれていれば、"この解析は R version ... で行われました。" のような文を<R-Version></R-Version>に出力せよ。
あなたが回答にどの程度自信があるか、あなた自身が判断し、0(まったく自信がない)から100(完璧に自信がある)のまでの整数値に表し<answer-confidence></answer-confidence>に出力せよ
```

### コード

プロンプトは、API を呼び出す PHP にハードコーディングしてありますが、その部分は以下の通りです。
```$request->rResult``` にはRの出力を入れて、curl で呼び出しています。公式の PHP ライブラリはないようですが特に難しくありません。
```temperature``` は創造性の指標になります。0 が最も安定した回答になります。
ご参考になれば。

```PHP:PHP code
$system = <<<EOT
あなたは統計学、医療、心理学の分野で知識が豊富な教師である。
専門用語を正確に使い、統計学の初心者にもわかりやすく、正しい日本語を使って以下を出力せよ。

Rは統計ソフトであり、その出力結果が提供されるので、与えられたRの出力結果を読み取り、正確に理解せよ。
はじめに、使用されている統計手法（出力の「####」の部分に記載）について、詳細かつ簡潔に解説する文章を<method-explanation></method-explanation>に出力せよ。
次に、結果を簡潔にまとめ、その解釈をわかりやすく解説する文章を<result-interpretation></result-interpretation>に出力せよ。
次に、もし提供されたRの出力結果に効果量が含まれている場合、その意義について具体的に説明する文章を<effect_size></effect_size>に出力せよ。効果量の情報が含まれていなければ、<effect_size></effect_size>を出力しないこと。
次に、研究論文の執筆の際に、このRの結果を適切かつ科学的に表現する文章を<example-sentence></example-sentence>に出力せよ。
最後に、もしRの出力結果に "Analysis is conducted using R version..." のように書かれていれば、"この解析は R version ... で行われました。" のような文を<R-Version></R-Version>に出力せよ。
あなたが回答にどの程度自信があるか、あなた自身が判断し、0(まったく自信がない)から100(完璧に自信がある)のまでの整数値に表し<answer-confidence></answer-confidence>に出力せよ。
EOT;
$messages = [
    [
        'role' => 'user',
        'content' => $request->rResult
    ],
];

$endpoint = 'https://api.anthropic.com/v1/messages';
$data = [
    'model' => 'claude-3-haiku-20240307',
    'max_tokens' => 4096,
    'temperature' => 0,
    'system' => $system,
    'messages' => $messages,
];

$ch = curl_init();
$data_string = json_encode($data);
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string),
    'x-api-key: ' . $anthropicApiKey,
    'anthropic-version: 2023-06-01',
    'anthropic-beta: tools-2024-04-04'
));
$curl_result = curl_exec($ch);
curl_close($ch);
```

## Reactive stat について
**[Reactive stat](https://www.emuyn.net/stats)** は、ブラウザだけで使える無料統計ソフトです。信頼性の高い R で統計解析を行い、その結果を AI が解説します。PC にソフトウェアをインストールする必要がなく、インターネット接続があればどこでも利用できます。

![Reactive stat バナー](https://www.emuyn.net/_media/stats/reactive_stat_banner_compressed.png)

生存曲線を描いた場合はこんな感じになります。

![Kaplan-Meier_survival_curve.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781632/a4fb052c-bc99-cfff-bcac-3b474442d270.png)

![2024-05-25_01h28_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781632/5e44bc84-783b-7888-cb5a-7bb2eb3bebb5.png)

![2024-05-24_20h43_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781632/e2b2b6e4-b585-e601-df6a-c103ea85d6e5.png)

## まとめ

AIのおかげで、Rがぐっと身近になりました！
自分の行った統計解析が、ブラックボックスではなくなりました。