見出し画像

MakeCodeのカスタムブロックを作成する/基礎統計量ブロック


ChatGPTを使用し MakeCodeのカスタムブロックを作成する」で紹介しましたカスタムブロックに基礎統計量を算出するブロックをいくつか追加しました。
今回の内容は、「ChatGPTを使用しMakeCodeのカスタムブロックを作成する」で紹介したカスタムブロックに基礎統計量を算出するブロックをいくつか追加しましたので紹介します。
また作成したブロックはBasicStatとして公開しています。

こちらが ベーシックスタットに含まれるブロックです。
内容は「標準誤差」、「最頻値」、「標準偏差」、「最小値」、「最大値」、「平均値」、「合計値」、「範囲」、「歪度」、「尖度」、「分散」、「中央値」 となります。

作成したBasicStatは公開していますので メークコードより取り込むことができます。
以下取り込み方法について説明します。
まず メークコードのエディターより拡張機能をクリックします。
そして 拡張機能メニューが表示されたらURL欄に公開されたURLを貼り付けます。

こちらに示すURLをテキストボックスの中に貼り付けてください。
そして下に表示された 「基礎統計量2」のタイルを クリックしてください。

そして「戻る」を押してブロックプログラムに戻ると 計算の下にBasicStatが追加されています。

次に使用例のプログラムを紹介します。
「最初だけ」ブロックに配列を設定します。
数値データを配列に入力し、「シリアル通信一行書き出し」で 文字列「結果」を出力します。
右プログラムは「Aボタンが押されたとき」に各カスタムブロックの値を「シリアル通信 名前と値を書き出す」で表示しています。
プログラムの実行時には、「show data」でコンソール画面に移動し「Aボタン」を押せばこのプログラムの結果が表示されます。

こちらのスライドの右側はExcelのデータ分析で基礎統計量の結果を表示したものです。
左側が今回作成したBasicStatの結果です
メークコードの計算精度が若干影響しているのか標準誤差、標準偏差などで 多少の誤差がみられました。
また最頻値では、1が3つ、2も3つとなった場合は、値の小さい方1が結果となります。

まとめ
今回は作成した基礎統計量のカスタムブロックの内容と導入法、使用例について紹介いたしました。
メークコードの計算精度の影響か 計算ブロックにより若干の誤差が出ているようです。
使用するブロックによっては 注意が必要となってきます。

ご視聴ありがとうございました なお ここで紹介した。

カスタムブロック「BasicStat」の内容

// カスタムブロック: 統計量を計算する
// リストを入力として受け取り、中央値、最頻値、分散、尖度、歪度、範囲、合計値を計算します。

namespace BasicStat {
    /**
     * リストの中央値を計算します。
     * @param numbers 数値のリスト
     * @returns 中央値
     */
    //% block="リストの中央値を計算する %numbers=variables_get(myList)"
    export function calculateMedian(numbers: number[]): number {
        const sortedNumbers = numbers.slice().sort((a, b) => a - b);
        const middle = Math.floor(sortedNumbers.length / 2);
        if (sortedNumbers.length % 2 === 0) {
            return (sortedNumbers[middle - 1] + sortedNumbers[middle]) / 2;
        } else {
            return sortedNumbers[middle];
        }
    }


    /**
   * リストの分散を計算します。
   * @param numbers 数値のリスト
   * @returns 分散
   */
    //% block="リストの分散を計算する %numbers=variables_get(myList)"
    export function calculateVariance(numbers: number[]): number {
        const mean = calculateMean(numbers);
        let sumOfSquares = 0;
        for (let i = 0; i < numbers.length; i++) {
            sumOfSquares += (numbers[i] - mean) ** 2;
        }
        return sumOfSquares / numbers.length;
    }
    /**
     * リストの尖度を計算します。
     * @param numbers 数値のリスト
     * @returns 尖度
     */
    //% block="リストの尖度を計算する %numbers=variables_get(myList)"
    export function calculateKurtosis(numbers: number[]): number {
        const mean = calculateMean(numbers);
        const n = numbers.length;
        let sumOfFourthPowerDeviations = 0;
        for (let i = 0; i < n; i++) {
            sumOfFourthPowerDeviations += (numbers[i] - mean) ** 4;
        }
        const variance = calculateVariance(numbers);
        return (sumOfFourthPowerDeviations / n) / (variance ** 2) - 3;
    }

    /**
     * リストの歪度を計算します。
     * @param numbers 数値のリスト
     * @returns 歪度
     */
    //% block="リストの歪度を計算する %numbers=variables_get(myList)"
    export function calculateSkewness(numbers: number[]): number {
        const mean = calculateMean(numbers);
        const n = numbers.length;
        let sumOfCubedPowerDeviations = 0;
        for (let i = 0; i < n; i++) {
            sumOfCubedPowerDeviations += (numbers[i] - mean) ** 3;
        }
        const variance = calculateVariance(numbers);
        return (sumOfCubedPowerDeviations / n) / (variance ** 1.5);
    }

    /**
     * リストの範囲を計算します。
     * @param numbers 数値のリスト
     * @returns 範囲
     */
    //% block="リストの範囲を計算する %numbers=variables_get(myList)"
    export function calculateRange(numbers: number[]): number {
        const max = calculateMax(numbers);
        const min = calculateMin(numbers);
        return max - min;
    }

    /**
     * リストの合計値を計算します。
     * @param numbers 数値のリスト
     * @returns 合計値
     */
    //% block="リストの合計値を計算する %numbers=variables_get(myList)"
    export function calculateSum(numbers: number[]): number {
        let sum = 0;
        for (let i = 0; i < numbers.length; i++) {
            sum += numbers[i];
        }
        return sum;
    }

    /**
     * リストの平均値を計算します。
     * @param numbers 数値のリスト
     * @returns 平均値
     */
    //% block="リストの平均値を計算する %numbers=variables_get(myList)"
    export function calculateMean(numbers: number[]): number {
        let sum = 0;
        for (let i = 0; i < numbers.length; i++) {
            sum += numbers[i];
        }
        return sum / numbers.length;
    }

    /**
     * リストの最大値を計算します。
     * @param numbers 数値のリスト
     * @returns 最大値
     */
    //% block="リストの最大値を計算する %numbers=variables_get(myList)"
    export function calculateMax(numbers: number[]): number {
        let max = numbers[0];
        for (let i = 1; i < numbers.length; i++) {
            if (numbers[i] > max) {
                max = numbers[i];
            }
        }
        return max
    }

    /**
     * リストの最小値を計算します。
     * @param numbers 数値のリスト
     * @returns 最小値
     */
    //% block="リストの最小値を計算する %numbers=variables_get(myList)"
    export function calculateMin(numbers: number[]): number {
        let min = numbers[0];
        for (let i = 1; i < numbers.length; i++) {
            if (numbers[i] < min) {
                min = numbers[i];
            }
        }
        return min;
    }

    /**
     * リストの標準偏差を計算します。
     * @param numbers 数値のリスト
     * @returns 標準偏差
     */
    //% block="リストの標準偏差を計算する %numbers=variables_get(myList)"
    export function calculateStandardDeviation(numbers: number[]): number {
        let mean = calculateMean(numbers);
        let sumOfSquares = 0;
        for (let i = 0; i < numbers.length; i++) {
            sumOfSquares += (numbers[i] - mean) * (numbers[i] - mean);
        }
        let variance = sumOfSquares / numbers.length;
        return Math.sqrt(variance);
    }
    /**
         * リストの最頻値を計算します。
         * @param numbers 数値のリスト
         * @returns 最頻値
         */
    //% block="リストの最頻値を計算する %numbers=variables_get(myList)"
    export function calculateMode(numbers: number[]): number {
        const frequencyMap: number[] = [];
        let maxFrequency = 0;

        for (let i = 0; i < numbers.length; i++) {
            frequencyMap.push(0);
        }

        for (let i = 0; i < numbers.length; i++) {
            frequencyMap[i] = 1;
            for (let j = i + 1; j < numbers.length; j++) {
                if (numbers[i] === numbers[j]) {
                    frequencyMap[i]++;
                    frequencyMap[j] = -1;
                }
            }
        }

        for (let i = 0; i < numbers.length; i++) {
            if (frequencyMap[i] !== -1 && frequencyMap[i] > maxFrequency) {
                maxFrequency = frequencyMap[i];
            }
        }

        const modeList: number[] = [];
        for (let i = 0; i < numbers.length; i++) {
            if (frequencyMap[i] === maxFrequency) {
                modeList.push(numbers[i]);
            }
        }

        return calculateMin(modeList);
    }

    /**
        * リストの標準誤差を計算します。
        * @param numbers 数値のリスト
        * @returns 標準誤差
        */
    //% block="リストの標準誤差を計算する %numbers=variables_get(myList)"
    export function calculateES(numbers: number[]): number {
        let SE;
        SE = calculateStandardDeviation(numbers) / Math.sqrt(numbers.length);
        return SE;
    }


}


この記事が気に入ったらサポートをしてみませんか?