はじめに
ChatGPTにhtmlファイルで最小二乗法で回帰分析ができるものをつくってもらいました。ついでに「教育用のページっぽくして」とお願いして、それっぽくしてもらいました。
作り方
私が与えたプロンプトはこんな感じです。
値の組を複数うけつけて、最小二乗法によって回帰分析を行い図示するようなものを1枚のhtmlファイルでつくってみてほしい
式や座標をかいてほしい
簡単に回帰分析の解説みたいなものも入れた教育用のページっぽくできる?
初期状態でそれっぽい例となる座標と結果が入っているようにしてほしい
コード中にコメントを入れて。
このやりとりででできたものがこちら(コード全文)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>最小二乗法 回帰分析</title>
<style>
/* 基本的なスタイル */
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
text-align: center;
}
h2 {
color: #4CAF50;
}
p {
font-size: 16px;
line-height: 1.6;
}
canvas {
border: 1px solid black;
margin-top: 20px;
}
.container {
display: flex;
justify-content: space-between;
}
.left, .right {
width: 45%;
}
.explanation {
background-color: #f9f9f9;
padding: 10px;
border-radius: 5px;
margin-top: 20px;
}
.explanation ul {
padding-left: 20px;
}
.explanation li {
margin-bottom: 5px;
}
input[type="text"] {
width: 80%;
padding: 8px;
margin-right: 10px;
}
button {
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<h1>最小二乗法 回帰分析</h1>
<div class="container">
<!-- 解説エリア -->
<div class="left">
<h2>回帰分析とは?</h2>
<p>回帰分析は、2つの変数間の関係をモデル化する統計的手法です。特に、1つの変数(従属変数)が他の変数(独立変数)によってどのように影響されるかを明らかにするために用いられます。</p>
<h3>最小二乗法</h3>
<p>最小二乗法は、回帰分析でよく使われる方法で、与えられたデータに最も適した直線を求めます。直線の方程式は次のように表されます:</p>
<div class="explanation">
<p><strong>y = ax + b</strong></p>
<ul>
<li><strong>a:</strong> 回帰直線の傾き</li>
<li><strong>b:</strong> 切片(y軸との交点)</li>
</ul>
<p>最小二乗法は、データ点と直線との誤差(縦方向の距離)の二乗和を最小化することによって、最適な直線を求めます。</p>
</div>
<h3>このページの使い方</h3>
<ul>
<li>データを「x,y」の形式で入力してください(例: 1,2 2,4 3,6)。</li>
<li>「回帰分析実行」ボタンを押すと、データ点と回帰直線が描画されます。</li>
<li>回帰直線の方程式も表示されます。</li>
</ul>
</div>
<!-- 入力フォームとキャンバス -->
<div class="right">
<h2>データ入力</h2>
<label for="data-input">データをカンマ区切りで入力 (例: 1,2 2,4 3,5):</label>
<div>
<input type="text" id="data-input" placeholder="x1,y1 x2,y2 ..." value="1,2 2,3 3,5 4,7 5,8">
<button onclick="performRegression()">回帰分析実行</button>
</div>
<canvas id="canvas" width="600" height="400"></canvas>
</div>
</div>
<script>
// 入力されたデータを解析して座標の配列を作成する関数
function parseData(input) {
// 入力文字列をスペースで分割し、各ペアをカンマで分割してx,yの値に変換
const points = input.split(' ').map(item => {
const [x, y] = item.split(',').map(Number);
return { x, y };
});
return points;
}
// 最小二乗法を使って回帰直線の係数を計算する関数
function leastSquares(points) {
const n = points.length;
const sumX = points.reduce((sum, p) => sum + p.x, 0); // xの合計
const sumY = points.reduce((sum, p) => sum + p.y, 0); // yの合計
const sumXY = points.reduce((sum, p) => sum + p.x * p.y, 0); // x*yの合計
const sumX2 = points.reduce((sum, p) => sum + p.x * p.x, 0); // x^2の合計
// 最小二乗法の式を使ってaとbを計算
const denominator = n * sumX2 - sumX * sumX;
const a = (n * sumXY - sumX * sumY) / denominator; // 傾き
const b = (sumY * sumX2 - sumX * sumXY) / denominator; // 切片
return { a, b }; // y = ax + b の式
}
// 座標と回帰直線を描画する関数
function drawGraph(points, line) {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height); // 既存のグラフをクリア
// 軸の描画
ctx.beginPath();
ctx.moveTo(50, 350); // x軸の起点
ctx.lineTo(550, 350); // x軸の終点
ctx.moveTo(50, 350); // y軸の起点
ctx.lineTo(50, 50); // y軸の終点
ctx.stroke();
// データ点の描画
ctx.fillStyle = 'red'; // データ点を赤色で描画
points.forEach(point => {
ctx.beginPath();
ctx.arc(50 + point.x * 50, 350 - point.y * 50, 5, 0, Math.PI * 2); // 座標点を描画
ctx.fill();
// 座標の表示
ctx.fillStyle = 'black';
ctx.fillText(`(${point.x}, ${point.y})`, 50 + point.x * 50, 350 - point.y * 50 - 10);
});
// 回帰直線の描画
ctx.beginPath();
const startX = 0;
const startY = line.a * startX + line.b; // 直線の始点
const endX = 10;
const endY = line.a * endX + line.b; // 直線の終点
ctx.moveTo(50 + startX * 50, 350 - startY * 50);
ctx.lineTo(50 + endX * 50, 350 - endY * 50);
ctx.strokeStyle = 'blue'; // 回帰直線は青色
ctx.stroke();
// 回帰直線の式の描画
ctx.fillStyle = 'blue';
ctx.fillText(`y = ${line.a.toFixed(2)}x + ${line.b.toFixed(2)}`, 200, 50); // 方程式表示
}
// 回帰分析を実行する関数
function performRegression() {
const input = document.getElementById('data-input').value; // 入力されたデータを取得
const points = parseData(input); // データを解析して座標に変換
// データ点が2つ以上でないと回帰分析を行えないので、警告を表示
if (points.length < 2) {
alert("データポイントが少なすぎます。最低でも2つのデータが必要です。");
return;
}
// 最小二乗法を使って回帰直線の方程式を求める
const line = leastSquares(points);
drawGraph(points, line); // グラフの描画
}
// ページ読み込み時に初期データを使って回帰分析を実行
window.onload = function() {
document.getElementById('data-input').value = "1,2 2,3 3,5 4,7 5,8"; // 初期データ
performRegression(); // 初期データで回帰分析実行
};
</script>
</body>
</html>
以下はCodePen。htmlとCSSとJavaScriptに切り分けました。
あと縦並びになるようにCSSに少し手を加えています。
See the Pen 最小二乗法回帰分析 by ken1math (@8787kazuye) on CodePen.
おわりに
最近暇なときにこんなの作らせて遊んでいます。おもしろいです