JavaScript での Cronbachのα信頼性係数の実装

# Reactive stat 内部のCronbachのα信頼性係数 の実装 です

Cronbachのα信頼性係数は、質問項目やテスト項目群の内的一貫性の信頼性を評価する指標です。

この記事では、Cronbachのα信頼性係数 の概要と、JavaScriptでの実装方法を説明します。

## はじめに

最近、弊社より **[ブラウザだけで使える無料統計ソフト Reactive stat](https://www.emuyn.net/stats)** をリリースしました。
信頼性の高い R で統計解析し、その結果を AI が解説します！
その背景には、統計に苦労している医療者の助けになりたい、という気持ちがあります。
最終的な統計解析は R で行うのですが、レスポンスとサーバー負荷の改善のため、一部の統計計算はブラウザ内で行っています。
そのうち、汎用性の高い部分を共有させていただきたいと思います。
できるだけ R の出力と整合性を持つように javascript をインプリメントしてあるので、参考になれば幸いです。

## 使用したライブラリ

このコードでは、jStatライブラリを使用しています。jStatは、JavaScriptで統計計算を行うための便利なライブラリです。
jStatの詳細については、[公式ドキュメント](https://github.com/jstat/jstat) を参照してください。
全関数の一覧は [jStat v1.9.3 Documentation](https://jstat.github.io/all.html) を参照してください。

## Cronbachのα信頼性係数 の概要

Cronbachのα信頼性係数は、質問項目やテスト項目群の内的一貫性の信頼性を評価する指標です。
この係数は0から1までの値を取り、高い値は項目間の一貫性が高いことを示します。
一般的に0.7以上であれば、項目群が一貫性を持っていると考えられますが、この基準は文脈によって異なる場合があります。

### 注意事項
1. 項目が同じ構成概念を測定しているという**仮定**に基づいています
2. 項目数が多いとα係数が高くなる傾向があります
3. 項目間の一貫性を示すものであり、テストや質問項目の有効性や内容の適切さを示すものではありません

### 計算式

**Cronbachのα係数**:

$$
\alpha = \frac{K}{K-1} \left( 1 - \frac{\sum_{i=1}^{K} \sigma_{Y_i}^2}{\sigma_X^2} \right)
$$

- $K$: 項目数
- $\sigma_{Y_i}^2$: 各項目の分散
- $\sigma_X^2$: 全項目の合計スコアの分散

#### 各項目を除いた場合のα係数:
特定の項目を除いてα係数を計算することで、その項目が全体の信頼性にどの程度影響を与えているかを評価できます。もし、ある項目を除いたときにα係数が大きく上昇する場合、その項目は他の項目と一貫性がなく、全体の信頼性を下げている可能性があります。逆に、ある項目を除いてもα係数がほとんど変化しない場合、その項目は全体の信頼性にあまり影響を与えていないと考えられます。

#### 項目間の相関:
各項目の得点と全体の得点（全項目の合計点）との相関係数を計算することで、各項目が測定しようとしている概念と全体の概念がどの程度関連しているかを評価できます。相関係数が高い項目は、全体の概念を良く反映していると考えられます。一方、相関係数が低い項目は、全体の概念とは異なる概念を測定している可能性があります。

これらの情報は、質問項目やテスト項目の質を評価し、改善するために役立ちます。
 
## コード

ライブラリ込みの html にしてありますので、
[jsfiddle](https://jsfiddle.net/) などにコピペして簡単に試せます。

```html:html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Cronbach's Alpha</title>
  <script src="https://cdn.jsdelivr.net/npm/jstat@latest/dist/jstat.min.js"></script>
</head>
<body>
  <h1>Cronbach's Alpha Example</h1>
  <p>Check the console for the result.</p>
  
  <script>
    // 共分散行列の計算
    function computeCovarianceMatrix(data, keys) {
        let n = data[keys[0]].length;
        let covarianceMatrix = {};

        for (let i = 0; i < keys.length; i++) {
            for (let j = 0; j < keys.length; j++) {
                let cov = jStat.covariance(data[keys[i]], data[keys[j]]);
                if (!covarianceMatrix[keys[i]]) covarianceMatrix[keys[i]] = {};
                covarianceMatrix[keys[i]][keys[j]] = cov;
            }
        }
        return covarianceMatrix;
    }

    // Cronbachのα係数の計算
    function cronbachAlpha(covMatrix, keys) {
        let numItems = keys.length;
        let variances = keys.map(key => covMatrix[key][key]);
        let totalCovariance = 0;

        for (let i = 0; i < keys.length; i++) {
            for (let j = 0; j < keys.length; j++) {
                if (i !== j) {
                    totalCovariance += covMatrix[keys[i]][keys[j]];
                }
            }
        }

        let averageVariance = jStat.sum(variances) / numItems;
        let averageCovariance = totalCovariance / (numItems * (numItems - 1));
        return (numItems * averageCovariance) / (averageVariance + (numItems - 1) * averageCovariance);
    }

    // サンプルデータ
    let data = {
        q1: [4, 5, 3, 4, 4],
        q2: [3, 4, 4, 4, 5],
        q3: [4, 4, 3, 3, 4],
        q4: [3, 3, 4, 2, 5]
    };
    let keys = ['q1', 'q2', 'q3', 'q4'];

    // 共分散行列の計算
    let covMatrix = computeCovarianceMatrix(data, keys);

    // Cronbachのα係数の計算
    let alpha = cronbachAlpha(covMatrix, keys);

    console.log("Covariance Matrix: ", covMatrix);
    console.log("Cronbach's Alpha: ", alpha);
  </script>
</body>
</html>
```

## 検証用 R コード

[rdrr](https://rdrr.io/snippets/) にコピペして簡単に試せます。

```R:R
# Cronbach's Alpha

# サンプルデータ
data <- data.frame(
  q1 = c(4, 5, 3, 4, 4),
  q2 = c(3, 4, 4, 4, 5),
  q3 = c(4, 4, 3, 3, 4),
  q4 = c(3, 3, 4, 2, 5)
)

# Cronbachのα係数を計算
result <- psych::alpha(data)

# 結果の表示
print(result)
```

## 注意点

- このコードは、jStatライブラリに依存しています。jStatを読み込まないと動作しません
- 浮動小数点数の計算では、わずかな誤差が生じる可能性があります

## 最後に

コードの内容はよく吟味し、R との食い違いが極力ないように気を付けていますが、もし間違いに気づかれた場合には指摘していただけますとありがたいです。

ただ、Chat GPT に読ませてその出力を検証もせず「問題があるので修正します」として貼り付けられると、他の方を混乱させてしまうのと、弊社の製品に対する信頼を損ねることにもつながりかねませんので、どうかそのようなことのないようにお願いいたします。

検証のための R のコードもつけてありますので、ご活用いただけますと幸いです。