LazStats: Split output of LSMRUnit into several tabs. Better layout of the output.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7769 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-11 16:28:57 +00:00
parent 183776a664
commit ae6622ff7c
3 changed files with 234 additions and 65 deletions

View File

@ -127,9 +127,9 @@ inherited LSMregForm: TLSMregForm
Left = 0
Height = 15
Top = 232
Width = 163
Width = 192
BorderSpacing.Right = 8
Caption = 'Minimum Prob. to enter block:'
Caption = 'Minimum probability to enter block:'
ParentColor = False
end
object OptionsGroup: TGroupBox[12]
@ -194,7 +194,7 @@ inherited LSMregForm: TLSMregForm
Caption = 'Show Variances'
TabOrder = 4
end
object SDChkBox: TCheckBox
object StdDevChkBox: TCheckBox
Left = 190
Height = 19
Top = 48
@ -295,7 +295,7 @@ inherited LSMregForm: TLSMregForm
AnchorSideLeft.Side = asrBottom
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = OptionsGroup
Left = 171
Left = 200
Height = 23
Top = 228
Width = 50
@ -326,7 +326,36 @@ inherited LSMregForm: TLSMregForm
Left = 413
Height = 430
end
object SaveDialog: TSaveDialog[2]
object PageControl: TPageControl[2]
Left = 422
Height = 414
Top = 8
Width = 580
ActivePage = MeanVarStddevPage
Align = alClient
BorderSpacing.Left = 4
BorderSpacing.Top = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
TabIndex = 4
TabOrder = 2
object RegressionPage: TTabSheet
Caption = 'Regression'
end
object CrossProductsPage: TTabSheet
Caption = 'Cross-Products Matrix'
end
object VarCovarPage: TTabSheet
Caption = 'Variance-Covariance'
end
object CorrelationsPage: TTabSheet
Caption = 'Correlations'
end
object MeanVarStddevPage: TTabSheet
Caption = 'MeanVarStdDev'
end
end
object SaveDialog: TSaveDialog[3]
Left = 45
Top = 357
end

View File

@ -6,14 +6,14 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls, Globals, MainUnit, MatrixLib,
DataProcs, DictionaryUnit, BasicStatsReportFormUnit;
StdCtrls, Buttons, ExtCtrls, ComCtrls, Globals, MainUnit, MatrixLib,
DataProcs, DictionaryUnit, BasicStatsParamsFormUnit, ReportFrameUnit;
type
{ TLSMregForm }
TLSMregForm = class(TBasicStatsReportForm)
TLSMregForm = class(TBasicStatsParamsForm)
AllBtn: TBitBtn;
IndepVars: TListBox;
CorrsChkBox: TCheckBox;
@ -31,10 +31,16 @@ type
Label5: TLabel;
MatSaveChkBox: TCheckBox;
MeansChkBox: TCheckBox;
PageControl: TPageControl;
SaveDialog: TSaveDialog;
OutBtn: TBitBtn;
PredictChkBox: TCheckBox;
SDChkBox: TCheckBox;
StdDevChkBox: TCheckBox;
RegressionPage: TTabSheet;
CrossProductsPage: TTabSheet;
CorrelationsPage: TTabSheet;
MeanVarStddevPage: TTabSheet;
VarCovarPage: TTabSheet;
VarChkBox: TCheckBox;
VarList: TListBox;
procedure AllBtnClick(Sender: TObject);
@ -47,14 +53,21 @@ type
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
private
{ private declarations }
FRegressionFrame: TReportFrame;
FCrossProductsFrame: TReportFrame;
FCorrelationsFrame: TReportFrame;
FVarCovarFrame: TReportFrame;
FMeanVarStddevFrame: TReportFrame;
IndepVarsCols: IntDyneVec;
NoVars: integer;
NoBlocks: integer;
procedure HideTabs;
protected
procedure AdjustConstraints; override;
procedure Compute; override;
procedure UpdateBtnStates; override;
public
constructor Create(AOwner: TComponent); override;
procedure Reset; override;
end;
@ -73,6 +86,64 @@ uses
{ TLSMregForm }
constructor TLSMregForm.Create(AOwner: TComponent);
begin
inherited;
FRegressionFrame := TReportFrame.Create(self);
FRegressionFrame.Name := '';
FRegressionFrame.Parent := RegressionPage;
FRegressionFrame.Align := alClient;
FRegressionFrame.BorderSpacing.Left := 0;
FRegressionFrame.BorderSpacing.Top := 0;
FRegressionFrame.BorderSpacing.Bottom := 0;
FRegressionFrame.BorderSpacing.Right := 0;
InitToolbar(FRegressionFrame.ReportToolbar, tpRight);
FCrossProductsFrame := TReportFrame.Create(self);
FCrossProductsFrame.Name := '';
FCrossProductsFrame.Parent := CrossProductsPage;
FCrossProductsFrame.Align := alClient;
FCrossProductsFrame.BorderSpacing.Left := 0;
FCrossProductsFrame.BorderSpacing.Top := 0;
FCrossProductsFrame.BorderSpacing.Bottom := 0;
FCrossProductsFrame.BorderSpacing.Right := 0;
InitToolbar(FCrossProductsFrame.ReportToolbar, tpRight);
FCorrelationsFrame := TReportFrame.Create(self);
FCorrelationsFrame.Name := '';
FCorrelationsFrame.Parent := CorrelationsPage;
FCorrelationsFrame.Align := alClient;
FCorrelationsFrame.BorderSpacing.Left := 0;
FCorrelationsFrame.BorderSpacing.Top := 0;
FCorrelationsFrame.BorderSpacing.Bottom := 0;
FCorrelationsFrame.BorderSpacing.Right := 0;
InitToolbar(FCorrelationsFrame.ReportToolbar, tpRight);
FVarCovarFrame := TReportFrame.Create(self);
FVarCovarFrame.Name := '';
FVarCovarFrame.Parent := VarCovarPage;
FVarCovarFrame.Align := alClient;
FVarCovarFrame.BorderSpacing.Left := 0;
FVarCovarFrame.BorderSpacing.Top := 0;
FVarCovarFrame.BorderSpacing.Bottom := 0;
FVarCovarFrame.BorderSpacing.Right := 0;
InitToolbar(FVarCovarFrame.ReportToolbar, tpRight);
FMeanVarStddevFrame := TReportFrame.Create(self);
FMeanVarStddevFrame.Name := '';
FMeanVarStddevFrame.Parent := MeanVarStdDevPage;
FMeanVarStddevFrame.Align := alClient;
FMeanVarStddevFrame.BorderSpacing.Left := 0;
FMeanVarStddevFrame.BorderSpacing.Top := 0;
FMeanVarStddevFrame.BorderSpacing.Bottom := 0;
FMeanVarStddevFrame.BorderSpacing.Right := 0;
InitToolbar(FMeanVarStddevFrame.ReportToolbar, tpRight);
PageControl.ActivePage := RegressionPage;
end;
procedure TLSMregForm.AdjustConstraints;
begin
ParamsPanel.Constraints.MinWidth := Max(
@ -125,6 +196,14 @@ var
errcode: boolean = false;
anerror: Integer = 0;
lReport: TStrings;
procedure AddHeaderToReport;
begin
lReport.Clear;
lReport.Add('LEAST SQUARES MULTIPLE REGRESSION by Bill Miller');
lReport.Add('');
end;
begin
NCases := NoCases;
SetLength(corrs,NoVariables+1,NoVariables+1);
@ -159,8 +238,6 @@ begin
lReport := TStringList.Create;
try
lReport.Add('LEAST SQUARES MULTIPLE REGRESSION by Bill Miller');
lReport.Add('');
errorcode := false;
{ get dependendent variable column }
@ -199,55 +276,75 @@ begin
if CPChkBox.Checked then
begin
title := 'Cross-Products Matrix';
AddHeaderToReport;
GridXProd(NEntered, ColEntered, Corrs, errcode, NCases);
MatPrint(Corrs, NEntered, NEntered, title, IndRowLabels, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
FCrossProductsFrame.DisplayReport(lReport);
CrossProductsPage.TabVisible := true;
end else
CrossProductsPage.TabVisible := false;
if CovChkBox.Checked then
begin
title := 'Variance-Covariance Matrix';
AddHeaderToReport;
GridCovar(NEntered,ColEntered, Corrs, Means, Variances, StdDevs, errcode, NCases);
MatPrint(Corrs, NEntered, NEntered, title, IndRowLabels, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
FVarCovarFrame.DisplayReport(lReport);
VarCovarPage.TabVisible := true;
// lReport.Add(DIVIDER_SMALL);
end;
Correlations(NEntered,ColEntered,Corrs,Means,Variances, StdDevs,errcode,NCases);
Correlations(NEntered,ColEntered,Corrs,Means,Variances, StdDevs,errcode,NCases);
if CorrsChkBox.Checked then
begin
title := 'Product-Moment Correlations Matrix';
AddHeaderToReport;
MatPrint(Corrs, NEntered, NEntered, title, IndRowLabels, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
FCorrelationsFrame.DisplayReport(lReport);
CorrelationsPage.TabVisible := true;
end else
CorrelationsPage.TabVisible := false;
if MeansChkBox.Checked then
if MeansChkBox.Checked or VarChkBox.Checked or StdDevChkBox.Checked then
begin
title := 'Means';
DynVectorPrint(Means, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
AddHeaderToReport;
if VarChkBox.Checked = true then
begin
title := 'Variances';
DynVectorPrint(Variances, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
if MeansChkBox.Checked then
begin
title := 'Means';
DynVectorPrint(Means, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
if SDChkBox.Checked = true then
begin
title := 'Standard Deviations';
DynVectorPrint(StdDevs, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
if VarChkBox.Checked then
begin
title := 'Variances';
DynVectorPrint(Variances, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
if StdDevChkBox.Checked then
begin
title := 'Standard Deviations';
DynVectorPrint(StdDevs, NEntered, title, IndColLabels, NCases, lReport);
lReport.Add(DIVIDER_SMALL);
end;
FMeanVarStddevFrame.DisplayReport(lReport);
MeanVarStddevPage.TabVisible := true;
end else
MeanVarStddevPage.TabVisible := false;
if errorcode then
begin
MessageDlg('A selected variable has no variability. Run aborted.', mtError, [mbOK], 0);
ErrorMsg('A selected variable has no variability. Run aborted.');
exit;
end;
NoIndepVars := NEntered - 1;
AddHeaderToReport;
MReg(NoIndepVars, ColEntered, DepVarCol, IndRowLabels, Means, Variances,
StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs, R2,
StdErrEst, NCases, errorcode, true, lReport);
@ -256,6 +353,7 @@ begin
df2 := NCases - NoIndepVars - 1;
F := ((R2 - OldR2) / (1.0 - R2)) * df2 / df1;
FProbF := ProbF(F,df1,df2);
lReport.Add('');
if FProbF < probIn then
lReport.Add('Entry requirements met')
else
@ -279,9 +377,6 @@ begin
BetaWeights, StdErrEst, IndepVarsCols, NoIndepVars);
end;
// OutputFrm.ShowModal;
// OutputFrm.RichEdit.Clear;
if MatSaveChkBox.Checked then
begin
SaveDialog.Filter := 'LazStats matrix files (*.mat)|*.mat;*.MAT|All files (*.*)|*.*';
@ -293,7 +388,7 @@ begin
end;
end;
FReportFrame.DisplayReport(lReport);
FRegressionFrame.DisplayReport(lReport);
finally
lReport.Free;
@ -358,6 +453,15 @@ begin
end;
procedure TLSMregForm.HideTabs;
var
i: Integer;
begin
for i := 1 to PageControl.PageCount-1 do // i=1 --> keep 1st page visible
PageControl.Pages[i].TabVisible := false;
end;
procedure TLSMregForm.OutBtnClick(Sender: TObject);
var
i: integer;
@ -394,7 +498,7 @@ begin
CorrsChkBox.Checked := true;
MeansChkBox.Checked := true;
VarChkBox.Checked := false;
SDChkBox.Checked := true;
StdDevChkBox.Checked := true;
MatSaveChkBox.Checked := false;
PredictChkBox.Checked := false;
@ -403,6 +507,7 @@ begin
InProb.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL);
SetLength(IndepVarsCols, NoVariables+1);
HideTabs;
UpdateBtnStates;
end;
@ -412,11 +517,21 @@ var
lSelected: Boolean;
begin
inherited;
if Assigned(FRegressionFrame) then
FRegressionFrame.UpdateBtnStates;
if Assigned(FCrossProductsFrame) then
FCrossProductsFrame.UpdateBtnStates;
if Assigned(FCorrelationsFrame) then
FCorrelationsFrame.UpdateBtnStates;
if Assigned(FVarCovarFrame) then
FVarCovarFrame.UpdateBtnStates;
if Assigned(FMeanVarStddevFrame) then
FMeanVarStddevFrame.UpdateBtnStates;
lSelected := AnySelected(VarList);
DepInBtn.Enabled := lSelected;
InBtn.Enabled := lSelected;
OutBtn.Enabled := AnySelected(IndepVars);
DepOutBtn.Enabled := DepVar.Text <> '';
AllBtn.Enabled := VarList.Items.Count > 0;

View File

@ -8,6 +8,9 @@ uses
Classes, SysUtils, Dialogs,
Globals, DictionaryUnit, FunctionsLib, DataProcs, MainUnit;
//type
// TRegItem = (riMeanVarStdDev, riXTX);
procedure GridDotProd(col1, col2: integer; out Product: double; var Ngood: integer);
procedure GridXProd(NoSelected : integer;
@ -27,7 +30,7 @@ procedure Correlations(NoSelected: integer; const Selected: IntDyneVec;
procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
out ErrorCode: boolean);
procedure MatTrn(var A, B: DblDyneMat; BRows, BCols: Integer);
procedure MatTrn(var A: DblDyneMat; const B: DblDyneMat; BRows, BCols: Integer);
procedure nonsymroots(a : DblDyneMat; nv : integer;
var nf : integer; c : real;
@ -46,6 +49,7 @@ procedure EffectCode(GridCol, min, max : integer;
VAR startcol : integer;
VAR endcol : integer;
VAR novectors : integer);
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
const RowLabels: StrDyneVec;
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
@ -368,8 +372,8 @@ end; { of MATAxB }
//-------------------------------------------------------------------
// transpose the b matrix and return it in a
procedure MatTrn(var A, B: DblDyneMat; BRows, BCols : integer);
// transpose the B matrix and return it in A
procedure MatTrn(var A: DblDyneMat; const B: DblDyneMat; BRows, BCols : integer);
var
i, j: integer;
begin
@ -624,27 +628,27 @@ procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
PrintAll: boolean; AReport: TStrings);
var
i, j, N: integer;
X: DblDyneMat;
XT: DblDyneMat;
XTX: DblDyneMat;
XTY: DblDyneVec;
Y: DblDyneVec;
indx: IntDyneVec;
ColLabels: StrDyneVec;
X: DblDyneMat = nil;
XT: DblDyneMat = nil;
XTX: DblDyneMat = nil;
XTY: DblDyneVec = nil;
Y: DblDyneVec = nil;
indx: IntDyneVec = nil;
ColLabels: StrDyneVec = nil;
F, Prob, VarY, SDY, MeanY: double;
value, TOL, VIF, AdjR2: double;
SSY, SSres, resvar, SSreg: double;
title: string;
deplabel: string;
errcode: boolean;
errcode: boolean = false;
begin
Assert(OS3MainFrm <> nil);
SetLength(X, NoCases+1, NoIndep+1); // augmented independent var. matrix
SetLength(XT, NoIndep+1, NoCases); // transpose of independent var's
SetLength(XTX, NoIndep+1, NoIndep+1); // product of transpose X times X
SetLength(Y, NCases+1); // Y variable values
SetLength(XTY, NoIndep+1); // X transpose times Y
SetLength(X, NoCases+1, NoIndep+1); // augmented independent var. matrix
SetLength(XT, NoIndep+1, NoCases); // transpose of independent var's
SetLength(XTX, NoIndep+1, NoIndep+1); // product of (transpose X) times X
SetLength(Y, NCases+1); // Y variable values
SetLength(XTY, NoIndep+1); // (X transpose) times Y
SetLength(indx, NoIndep+1);
SetLength(ColLabels, NCases);
@ -706,9 +710,11 @@ begin
VarY := VarY / (NCases - 1);
SDY := sqrt(VarY);
AReport.Add('Variance Y: %10.3f', [VarY]);
AReport.Add('SSY: %10.3f', [SSY]);
AReport.Add('SDY: %10.3f', [SDY]);
AReport.Add('Sum of Squares Y: %20.3f', [SSY]);
AReport.Add('Variance Y: %20.3f', [VarY]);
AReport.Add('Std. Deviation Y: %20.3f', [SDY]);
AReport.Add('');
AReport.Add(DIVIDER_SMALL);
// augment the matrix
for i := 1 to NCases do
@ -719,8 +725,11 @@ begin
MatTrn(XT, X, NCases, NoIndep+1);
if PrintAll then
begin
AReport.Add('');
title := 'XT MATRIX';
MatPrint(XT, NoIndep+1, NCases, title, RowLabels, ColLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
end;
// get product of the augmented X transpose times augmented X
@ -729,6 +738,8 @@ begin
begin
title := 'XTX MATRIX';
MatPrint(XTX, Noindep+1, NoIndep+1, title, RowLabels, RowLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
end;
//Get means, variances and standard deviations
@ -747,8 +758,14 @@ begin
if PrintAll then
begin
DynVectorPrint(Means, NoIndep+1, 'MEANS', RowLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
DynVectorPrint(Variances, NoIndep+1,'VARIANCES',RowLabels, NCases, AReport);
DynVectorPrint(StdDevs, NoIndep+1, 'STD. DEV.S', RowLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
DynVectorPrint(StdDevs, NoIndep+1, 'STD. DEVs', RowLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
end;
// get product of the augmented X transpose matrix times the Y vector
@ -756,14 +773,19 @@ begin
for j := 0 to NCases-1 do
XTY[i] := XTY[i] + (XT[i,j] * Y[j]);
if PrintAll then
begin
DynVectorPrint(XTY, NoIndep+1, 'XTY VECTOR', RowLabels, NCases, AReport);
AReport.Add(DIVIDER_SMALL);
end;
// get inverse of the augmented cross products matrix among independent variables
SVDInverse(XTX,N);
if PrintAll then
begin
AReport.Add('');
title := 'XTX MATRIX INVERSE';
MatPrint(XTX, NoIndep+1, NoIndep+1, title, RowLabels, RowLabels, NCases, AReport);
AReport.Add(DIVIDER);
end;
// multiply augmented inverse matrix times the XTY vector
@ -797,23 +819,24 @@ begin
AdjR2 := 1.0 - (1.0 - R2) * (NCases - 1) / (NCases - N);
if PrintAll then
begin
AReport.Add('');
AReport.Add('Dependent variable: ' + deplabel);
AReport.Add('');
DynVectorPrint(BWeights, NoIndep+1, 'B WEIGHTS', RowLabels, NCases, AReport);
AReport.Add('');
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
AReport.Add('Dependent variable: ' + deplabel);
AReport.Add('');
DynVectorPrint(BetaWeights, NoIndep, 'BETA WEIGHTS', RowLabels, NCases, AReport);
AReport.Add('');
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
DynVectorPrint(BStdErrs, NoIndep+1, 'B STD.ERRORS', RowLabels, NCases, AReport);
AReport.Add('');
DynVectorPrint(Bttests, NoIndep+1, 'B t-test VALUES', RowLabels, NCases, AReport);
AReport.Add('');
DynVectorPrint(tprobs, NoIndep+1, 'B t VALUE PROBABILITIES', RowLabels, NCases, AReport);
AReport.Add(DIVIDER);
AReport.Add('');
AReport.Add('SSY: %10.2f', [SSY]);
AReport.Add('SSreg: %10.2f', [SSreg]);
AReport.Add('SSres: %10.2f', [SSres]);
@ -829,6 +852,8 @@ begin
//AReport.Add('Standard Error of Estimate = %8.2f', [stderrest]);
end;
AReport.Add(DIVIDER_SMALL);
AReport.Add('');
RowLabels[N-1] := 'Intercept';
AReport.Add(' Variable Beta B Std.Err. t prob VIF TOL');
AReport.Add('---------- ---------- ---------- ---------- ---------- ---------- --------- ----------');