Skip to content

Instantly share code, notes, and snippets.

@immengineer
Last active September 4, 2017 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save immengineer/5e1c280d9e8fefe5ad6c6fabde5b69b1 to your computer and use it in GitHub Desktop.
Save immengineer/5e1c280d9e8fefe5ad6c6fabde5b69b1 to your computer and use it in GitHub Desktop.
決定係数R2計算
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace CalcR2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
radioButton2.Checked = true; // デフォルト 二次多項式近似
this.ActiveControl = this.textBox1; // X (textBox1)にフォーカス
}
private void button1_Click(object sender, EventArgs e)
{
// textBox1, texBox2 いずれか空なら終了
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("空のデータが有ります", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// textBox1, texBox2 行末の改行削除、改行で区切って、文字列配列に変換
string s;
s = textBox1.Text.TrimEnd('\r', '\n'); //textBox1 -> X
string[] X = s.Split(new string[] {"\r\n"}, StringSplitOptions.None);
s = textBox2.Text.TrimEnd('\r', '\n'); // textBox2 -> Y
string[] Y = s.Split(new string[] {"\r\n"}, StringSplitOptions.None);
// XとYのデータ個数が異なる場合は終了
if (X.Length != Y.Length)
{
MessageBox.Show("XとYのデータ数が違います\n" + "X : " + X.Length.ToString() + " Y : " + Y.Length.ToString(),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// データ数をラベルに表示
label3.Text = "データ数:" + X.Length.ToString();
// 変数初期化
double Sigma = X.Length; // データ数
double SigmaX = 0; // X 総和
double SigmaX2 = 0; // X 二乗 総和
double SigmaX3 = 0; // X 三乗 総和
double SigmaX4 = 0; // X 四乗 総和
double SigmaY = 0; // Y 総和
double SigmaXY = 0; // X * Y 総和
double SigmaX2Y = 0; // X 二乗 * Y 総和
double a = 0; // 係数 a
double b = 0; // 係数 b
double c = 0; // 係数 c
double numera = 0; // a 計算用 分子
double numerb = 0; // b 計算用 分子
double numerc = 0; // c 計算用 分子
double denom = 0; // 分母(共通)
// 総和の計算
double xval, yval;
for (int i = 0; i < Sigma; i++)
{
xval = Double.Parse(X[i]);
yval = Double.Parse(Y[i]);
SigmaX += xval;
SigmaX2 += Math.Pow(xval, 2);
SigmaX3 += Math.Pow(xval, 3);
SigmaX4 += Math.Pow(xval, 4);
SigmaY += yval;
SigmaXY += xval * yval;
SigmaX2Y += Math.Pow(xval, 2) * yval;
}
// 係数の計算 直線近似(y = ax + b)
if (radioButton1.Checked)
{
numera = (SigmaX * SigmaY) - (Sigma * SigmaXY);
numerb = (SigmaX * SigmaXY) - (SigmaY * SigmaX2);
denom = Math.Pow(SigmaX, 2) - (Sigma * SigmaX2);
a = numera / denom;
b = numerb / denom;
label4.Text = "近似式: " + a.ToString("F4") + " x + " + b.ToString("F4");
}
// 係数の計算 二次多項式近似(y = ax2 + bx + c)
else if (radioButton2.Checked)
{
numera = (Sigma * SigmaX2 * SigmaX2Y) - (SigmaX * SigmaX * SigmaX2Y) + (SigmaX * SigmaX2 * SigmaXY) -
(Sigma * SigmaX3 * SigmaXY) + (SigmaX * SigmaX3 * SigmaY) - (SigmaX2 * SigmaX2 * SigmaY);
numerb = (SigmaX * SigmaX2 * SigmaX2Y) - (Sigma * SigmaX3 * SigmaX2Y) + (Sigma * SigmaX4 * SigmaXY) -
(SigmaX2 * SigmaX2 * SigmaXY) + (SigmaX2 * SigmaX3 * SigmaY) - (SigmaX * SigmaX4 * SigmaY);
numerc = -(SigmaX2 * SigmaX2 * SigmaX2Y) + (SigmaX * SigmaX3 * SigmaX2Y) - (SigmaX * SigmaX4 * SigmaXY) +
(SigmaX2 * SigmaX3 * SigmaXY) - (SigmaX3 * SigmaX3 * SigmaY) + (SigmaX2 * SigmaX4 * SigmaY);
denom = (2 * SigmaX * SigmaX2 * SigmaX3) + (Sigma * SigmaX2 * SigmaX4) - (SigmaX * SigmaX * SigmaX4) -
(Sigma * SigmaX3 * SigmaX3) - (SigmaX2 * SigmaX2 * SigmaX2);
a = numera / denom;
b = numerb / denom;
c = numerc / denom;
label4.Text = "近似式: " + a.ToString("F4") + "x2 + " + b.ToString("F4") + "x + " + c.ToString("F2");
}
// 近似式より予測値を計算
double[] fx = new double[X.Length]; // 予測値
for (int i = 0; i < X.Length; i++)
{
xval = Double.Parse(X[i]);
if (radioButton1.Checked) fx[i] = (a * xval) + b;
else if (radioButton2.Checked) fx[i] = (a * Math.Pow(xval, 2)) + (b * xval) + c;
}
// 残差平方和と全平方和の計算
double ssr = 0; // 残差平方和
double tss = 0; // 全平方和
double aveY = SigmaY / Sigma; // Y平均値
for (int i = 0; i < X.Length; i++)
{
yval = Double.Parse(Y[i]);
ssr += Math.Pow((yval - fx[i]), 2);
tss += Math.Pow((yval - aveY), 2);
}
// 決定係数R2の計算
double r2 = 1 - (ssr / tss);
label5.Text = "R2 : " + r2.ToString("F5");
}
}
}
@immengineer
Copy link
Author

141行目 コメント修正

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment