概要
身長が165cm~170cmである日本人男性の数、割合をいい加減な精度で算出した。
方法
chatGPT君にコードを生成してもらい、筆者が適宜コードを書き換えた。
使用した技術
筆者がReactの勉強をしたいと思っているので、chatGPTでコードを生成した。グラフ部分はchart.jsを利用した。
その他追記事項
筆者は統計学に関して全くの無知です。ですので、明らかに間違えている場合があります。
計算部分もJavaScriptで実装されているので、精度に関しては責任を一切負いません。
5分程ですべて実装(生成)したため、正しく動作していないような気がしています。
前提
平均値(中央値) 172cm
標準偏差 6cm
日本人男性総数 6175万人
結果
総数 15597709人
日本人男性に占める割合 0.252594478
使用したコード
PopulationInRangeWithLines.jsx
import React, { useState } from "react";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from "chart.js";
import { Line } from "react-chartjs-2";
import annotationPlugin from "chartjs-plugin-annotation"; // Annotation プラグイン
// 必要な要素を登録
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
annotationPlugin // Annotation プラグインを登録
);
const PopulationInRangeWithLines = () => {
const [mean, setMean] = useState(170); // 平均身長
const [stdDev, setStdDev] = useState(6); // 標準偏差
const [totalPopulation, setTotalPopulation] = useState(61750000); // 総人口
const [rangeMin, setRangeMin] = useState(160); // 区間の下限値
const [rangeMax, setRangeMax] = useState(180); // 区間の上限値
const calculateGaussian = (mean, stdDev) => {
const dataPoints = 100; // X軸の点数
const min = mean - 4 * stdDev; // 表示範囲の最小値
const max = mean + 4 * stdDev; // 表示範囲の最大値
const step = (max - min) / dataPoints; // 1ステップの幅
const xValues = [];
const yValues = [];
for (let i = 0; i <= dataPoints; i++) {
const x = min + i * step;
const pdf =
(1 / (Math.sqrt(2 * Math.PI) * stdDev)) *
Math.exp(-0.5 * Math.pow((x - mean) / stdDev, 2));
xValues.push(x.toFixed(1)); // 小数点1桁まで表示
yValues.push(pdf * totalPopulation * step); // 人口を計算
}
return { xValues, yValues };
};
const calculatePopulationInRange = (mean, stdDev, rangeMin, rangeMax, totalPopulation) => {
const step = 0.1; // 積分のステップ幅
let population = 0;
for (let x = rangeMin; x <= rangeMax; x += step) {
const pdf =
(1 / (Math.sqrt(2 * Math.PI) * stdDev)) *
Math.exp(-0.5 * Math.pow((x - mean) / stdDev, 2));
population += pdf * step * totalPopulation; // 人口を合計
}
return Math.round(population); // 四捨五入して整数に
};
const { xValues, yValues } = calculateGaussian(mean, stdDev);
const populationInRange = calculatePopulationInRange(mean, stdDev, rangeMin, rangeMax, totalPopulation);
const data = {
labels: xValues,
datasets: [
{
label: "Height Distribution (Population)",
data: yValues,
borderColor: "blue",
borderWidth: 2,
fill: false,
},
],
};
const options = {
responsive: true,
plugins: {
legend: {
display: true,
},
annotation: {
annotations: {
rangeMinLine: {
type: "line",
xMin: rangeMin,
xMax: rangeMin,
borderColor: "red",
borderWidth: 2,
label: {
content: `Min: ${rangeMin} cm`,
enabled: true,
position: "end",
},
},
rangeMaxLine: {
type: "line",
xMin: rangeMax,
xMax: rangeMax,
borderColor: "green",
borderWidth: 2,
label: {
content: `Max: ${rangeMax} cm`,
enabled: true,
position: "end",
},
},
},
},
},
scales: {
x: {
title: {
display: true,
text: "Height (cm)",
},
},
y: {
title: {
display: true,
text: "Population",
},
},
},
};
return (
<div style={{ width: "80%", margin: "0 auto", textAlign: "center" }}>
<h1>Population in Height Range</h1>
<div style={{ marginBottom: "20px" }}>
<label>
Mean (cm):{" "}
<input
type="number"
value={mean}
onChange={(e) => setMean(Number(e.target.value))}
/>
</label>
<label style={{ marginLeft: "10px" }}>
Standard Deviation (cm):{" "}
<input
type="number"
value={stdDev}
onChange={(e) => setStdDev(Number(e.target.value))}
/>
</label>
<label style={{ marginLeft: "10px" }}>
Total Population:{" "}
<input
type="number"
value={totalPopulation}
onChange={(e) => setTotalPopulation(Number(e.target.value))}
/>
</label>
<label style={{ marginLeft: "10px" }}>
Min Height (cm):{" "}
<input
type="number"
value={rangeMin}
onChange={(e) => setRangeMin(Number(e.target.value))}
/>
</label>
<label style={{ marginLeft: "10px" }}>
Max Height (cm):{" "}
<input
type="number"
value={rangeMax}
onChange={(e) => setRangeMax(Number(e.target.value))}
/>
</label>
</div>
<h2>
Population in Range ({rangeMin} cm - {rangeMax} cm): {populationInRange.toLocaleString()} people
</h2>
<Line data={data} options={options} />
</div>
);
};
export default PopulationInRangeWithLines;
おわりに
ReactはVueより実装しやすいような気がした。
特に
sample.js
const [val, setVal] = useState(12345);
この部分が、後から読み返したときに理解しやすいような気がします。