お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"StringGridから散布図・最小二乗法"





StringGridのデータをTChartにプロットし最小二乗法によって直線を引く。
StringGridの1列目にx,2列目にyが入力されているとする。

FormにStringGridとButton,直線の傾きと切片・それらの確率誤差を
表示するためのLabelを4つおいてください。

procedure LSM(const x, y: TStringList; var a, b,      //LeastSquareMethod
              KakuritsuGosa_a, Kakuritsugosa_b: Extended);
var
  i, bb: Integer;                               // y = ax + b
  aa, ab, aM, bM, rho, Bunbo: Extended;         // aa: Σ(xi_ * x_i)
begin                                           // ab: Σ(xi_ * 1)
  aa := 0; ab := 0; aM := 0; bM := 0; rho := 0; // aM: Σ(xi_ * y_i)
  bb := x.Count;                                // bM: Σ(1 * y_i)
  for i := 0 to bb - 1 do                       // rho: 残差
  begin                                         // KakuritsuGosa_a 
    aa := aa + Sqr(StrToFloat(x[i]));           //    aに対する確率誤差
    ab := ab + StrToFloat(x[i]);                // KakuritsuGosa_b
    aM := aM + StrToFloat(x[i]) * StrToFloat(y[i]); //bに対する確率誤差
    bM := bM + StrToFloat(y[i]);
  end;
  Bunbo := aa * bb - Sqr(ab);
  a := ( bb * aM - ab * bM ) / Bunbo;
  b := ( aa * bM - ab * aM ) / Bunbo;
  for i := 0 to bb - 1 do
   rho := rho + Sqr(a * StrToFloat(x[i]) + b - StrToFloat(y[i]));
  if bb > 2 then
  begin
    KakuritsuGosa_a := 0.6745 * Sqrt( bb / Bunbo * rho / ( bb - 2 ) );
    KakuritsuGosa_b := 0.6745 * Sqrt( aa / Bunbo * rho / ( bb - 2 ) );
  end else       // ただの誤差を求めたいときは 0.6745 を掛けなければよい
  begin
    KakuritsuGosa_a := 0;         // データが2点の時は誤差は0
    KakuritsuGosa_b := 0;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  DataX, DataY: TStringList;
  a, b, Gosa_a, Gosa_b: Extended;
  i: integer;
begin
  DataX := TStringList.Create;
  DataY := TStringList.Create;
  try
    DataX.Assign(StringGrid1.Cols[0]);          // StringGridに固定行
    DataY.Assign(StringGrid1.Cols[1]);          // がないとする
    LSM(DataX, DataY, a, b, Gosa_a, Gosa_b);    // 最小二乗法
    Label1.Caption := Format('%.5f', [a]);      // 小数点以下第5位
    Label2.Caption := Format('%.5f', [Gosa_a]); // までの求めたい時
    Label3.Caption := Format('%.5f', [b]);
    Label4.Caption := Format('%.5f', [Gosa_b]);
    with Chart1, Series1 do                     // 各データ
    begin                                       // Series1: TPointSeries
      Clear;
      for i := 0 to DataX.Count - 1 do
        AddXY(StrToFloat(DataX[i]), StrToFloat(DataY[i]), '', clBlack);
    end;
    with Chart1, Series2 do                     // 直線
    begin                                       // Series2: TLineSeries
      Clear;
      AddXY(BottomAxis.Minimum, a * BottomAxis.Minimum + b, '', clBlack)
      AddXY(BottomAxis.Maximum, a * BottomAxis.Maximum + b, '', clBlack)
    end;
  finally                                       // TChartの軸の最小値,
    DataX.Free;                                 // 最大値等は適当に設定
    DataY.Free;                                 // してください
  end;
end;

                                       97/10/26(日)  Masa(RXK02155)

Original document by Masa            氏 ID:(RXK02155)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum