You've already forked lazarus-ccr
LazStats: More refactoring of WLSUnit.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7776 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -142,44 +142,38 @@ inherited WLSFrm: TWLSFrm
|
|||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label2: TLabel[7]
|
object Label2: TLabel[7]
|
||||||
AnchorSideLeft.Control = DepInBtn
|
AnchorSideLeft.Control = DepVarEdit
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = DepVarEdit
|
AnchorSideBottom.Control = DepVarEdit
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 21
|
Top = 21
|
||||||
Width = 102
|
Width = 102
|
||||||
Anchors = [akLeft, akBottom]
|
Anchors = [akLeft, akBottom]
|
||||||
BorderSpacing.Left = 4
|
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
BorderSpacing.Bottom = 2
|
BorderSpacing.Bottom = 2
|
||||||
Caption = 'Dependent Variable'
|
Caption = 'Dependent Variable'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label3: TLabel[8]
|
object Label3: TLabel[8]
|
||||||
AnchorSideLeft.Control = IndInBtn
|
AnchorSideLeft.Control = IndVarList
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideTop.Control = IndInBtn
|
AnchorSideTop.Control = IndInBtn
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 105
|
Top = 105
|
||||||
Width = 116
|
Width = 116
|
||||||
BorderSpacing.Left = 4
|
|
||||||
Caption = 'Independent Variables'
|
Caption = 'Independent Variables'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label4: TLabel[9]
|
object Label4: TLabel[9]
|
||||||
AnchorSideLeft.Control = WeightInBtn
|
AnchorSideLeft.Control = WeightVarEdit
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = WeightVarEdit
|
AnchorSideBottom.Control = WeightVarEdit
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 15
|
Height = 15
|
||||||
Top = 205
|
Top = 205
|
||||||
Width = 134
|
Width = 77
|
||||||
Anchors = [akLeft, akBottom]
|
Anchors = [akLeft, akBottom]
|
||||||
BorderSpacing.Left = 4
|
|
||||||
BorderSpacing.Bottom = 2
|
BorderSpacing.Bottom = 2
|
||||||
Caption = 'User''s Weights (Optional)'
|
Caption = 'User''s Weights'
|
||||||
Enabled = False
|
Enabled = False
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
@ -192,10 +186,10 @@ inherited WLSFrm: TWLSFrm
|
|||||||
Left = 0
|
Left = 0
|
||||||
Height = 240
|
Height = 240
|
||||||
Top = 17
|
Top = 17
|
||||||
Width = 123
|
Width = 119
|
||||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Top = 2
|
BorderSpacing.Top = 2
|
||||||
BorderSpacing.Right = 4
|
BorderSpacing.Right = 8
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
Constraints.MinHeight = 220
|
Constraints.MinHeight = 220
|
||||||
ItemHeight = 0
|
ItemHeight = 0
|
||||||
@ -306,12 +300,12 @@ inherited WLSFrm: TWLSFrm
|
|||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
AnchorSideBottom.Control = DepOutBtn
|
AnchorSideBottom.Control = DepOutBtn
|
||||||
AnchorSideBottom.Side = asrBottom
|
AnchorSideBottom.Side = asrBottom
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 23
|
Height = 23
|
||||||
Top = 38
|
Top = 38
|
||||||
Width = 123
|
Width = 119
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Left = 4
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Bottom = 12
|
BorderSpacing.Bottom = 12
|
||||||
ReadOnly = True
|
ReadOnly = True
|
||||||
TabOrder = 3
|
TabOrder = 3
|
||||||
@ -325,12 +319,12 @@ inherited WLSFrm: TWLSFrm
|
|||||||
AnchorSideRight.Control = ParamsPanel
|
AnchorSideRight.Control = ParamsPanel
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
AnchorSideBottom.Control = WeightInBtn
|
AnchorSideBottom.Control = WeightInBtn
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 63
|
Height = 63
|
||||||
Top = 122
|
Top = 122
|
||||||
Width = 123
|
Width = 119
|
||||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Left = 4
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 2
|
BorderSpacing.Top = 2
|
||||||
BorderSpacing.Bottom = 16
|
BorderSpacing.Bottom = 16
|
||||||
ItemHeight = 0
|
ItemHeight = 0
|
||||||
@ -346,12 +340,12 @@ inherited WLSFrm: TWLSFrm
|
|||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
AnchorSideBottom.Control = WeightOutBtn
|
AnchorSideBottom.Control = WeightOutBtn
|
||||||
AnchorSideBottom.Side = asrBottom
|
AnchorSideBottom.Side = asrBottom
|
||||||
Left = 157
|
Left = 161
|
||||||
Height = 23
|
Height = 23
|
||||||
Top = 222
|
Top = 222
|
||||||
Width = 123
|
Width = 119
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Left = 4
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Bottom = 12
|
BorderSpacing.Bottom = 12
|
||||||
Enabled = False
|
Enabled = False
|
||||||
ReadOnly = True
|
ReadOnly = True
|
||||||
|
@ -58,6 +58,9 @@ type
|
|||||||
ResidualsRegReportFrame: TReportFrame;
|
ResidualsRegReportFrame: TReportFrame;
|
||||||
WLSReportFrame: TReportFrame;
|
WLSReportFrame: TReportFrame;
|
||||||
|
|
||||||
|
procedure AddPredictedStuffToGrid(AIndepCols: IntDyneVec; ANumIndepCols: Integer;
|
||||||
|
BWeights: DblDyneVec);
|
||||||
|
|
||||||
procedure CreateOrGetChartFrame(AColIndex: Integer; AVarName: String;
|
procedure CreateOrGetChartFrame(AColIndex: Integer; AVarName: String;
|
||||||
out AMemo: TMemo; out AChartFrame: TChartFrame);
|
out AMemo: TMemo; out AChartFrame: TChartFrame);
|
||||||
|
|
||||||
@ -77,6 +80,13 @@ type
|
|||||||
out AIndepCols: IntDyneVec; out AWeightCol: Integer;
|
out AIndepCols: IntDyneVec; out AWeightCol: Integer;
|
||||||
out ARowLabels: StrDyneVec): Boolean;
|
out ARowLabels: StrDyneVec): Boolean;
|
||||||
|
|
||||||
|
function Process_OLSRegression(AIndepCols: IntDyneVec; ANumIndepCols, ADepCol: Integer;
|
||||||
|
ARowLabels: StrDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
|
||||||
|
|
||||||
|
function Process_SquaredResidualsRegression(AIndepCols: IntDyneVec;
|
||||||
|
ANumIndepCols, ADepCol: Integer; ARowLabels: StrDyneVec;
|
||||||
|
BWeights: DblDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
|
||||||
|
|
||||||
procedure WriteDescriptiveReport(AMemo: TMemo;
|
procedure WriteDescriptiveReport(AMemo: TMemo;
|
||||||
const ARegressionResults: TBivariateRegressionResults;
|
const ARegressionResults: TBivariateRegressionResults;
|
||||||
const XLabel, YLabel: String);
|
const XLabel, YLabel: String);
|
||||||
@ -145,6 +155,50 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ Get predicted squared residuals and save recipricols to grid as weights }
|
||||||
|
procedure TWLSFrm.AddPredictedStuffToGrid(AIndepCols: IntDyneVec;
|
||||||
|
ANumIndepCols: Integer; BWeights: DblDyneVec);
|
||||||
|
var
|
||||||
|
col: Integer;
|
||||||
|
i, j: Integer;
|
||||||
|
X, predicted: Double;
|
||||||
|
begin
|
||||||
|
col := NoVariables + 1;
|
||||||
|
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
||||||
|
DictionaryFrm.NewVar(col);
|
||||||
|
DictionaryFrm.DictGrid.Cells[1, col] := 'PredResid2';
|
||||||
|
OS3MainFrm.DataGrid.Cells[col, 0] := 'PredResid2';
|
||||||
|
|
||||||
|
col := NoVariables + 1;
|
||||||
|
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
||||||
|
DictionaryFrm.NewVar(col);
|
||||||
|
DictionaryFrm.DictGrid.Cells[1, col] := 'WEIGHT';
|
||||||
|
OS3MainFrm.DataGrid.Cells[col, 0] := 'WEIGHT';
|
||||||
|
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
||||||
|
|
||||||
|
for i := 1 to NoCases do
|
||||||
|
begin
|
||||||
|
if (DataProcs.ValidValue(i, col-2)) then // do we have a valid squared OLS residual?
|
||||||
|
begin
|
||||||
|
predicted := 0.0;
|
||||||
|
for j := 0 to ANumIndepCols - 1 do
|
||||||
|
begin
|
||||||
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[AIndepCols[j], i]);
|
||||||
|
predicted := predicted + BWeights[j] * X;
|
||||||
|
end;
|
||||||
|
predicted := predicted + BWeights[ANumIndepCols];
|
||||||
|
predicted := abs(predicted);
|
||||||
|
OS3MainFrm.DataGrid.Cells[col-1, i] := Format('%.3f', [predicted]);
|
||||||
|
if (predicted > 0.0) then
|
||||||
|
predicted := 1.0 / sqrt(predicted)
|
||||||
|
else
|
||||||
|
predicted := 0.0;
|
||||||
|
OS3MainFrm.DataGrid.Cells[col, i] := Format('%.3f', [predicted]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TWLSFrm.AdjustConstraints;
|
procedure TWLSFrm.AdjustConstraints;
|
||||||
begin
|
begin
|
||||||
ParamsPanel.Constraints.MinHeight := DepInBtn.Top + (IndOutBtn.Top - DepInBtn.Top)*2 + DepInBtn.Top +
|
ParamsPanel.Constraints.MinHeight := DepInBtn.Top + (IndOutBtn.Top - DepInBtn.Top)*2 + DepInBtn.Top +
|
||||||
@ -158,7 +212,7 @@ end;
|
|||||||
|
|
||||||
procedure TWLSFrm.Compute;
|
procedure TWLSFrm.Compute;
|
||||||
var
|
var
|
||||||
i, j, Noindep, DepCol, WghtCol, olddepcol, NCases, pos, col: integer;
|
i, j, noIndep, depCol, weightCol, oldDepCol, NCases, pos, col: integer;
|
||||||
IndepCols: IntDyneVec = nil;
|
IndepCols: IntDyneVec = nil;
|
||||||
RowLabels: StrDyneVec = nil;
|
RowLabels: StrDyneVec = nil;
|
||||||
X, Y: double;
|
X, Y: double;
|
||||||
@ -170,136 +224,49 @@ var
|
|||||||
BStdErrs: DblDyneVec = nil;
|
BStdErrs: DblDyneVec = nil;
|
||||||
BtTests: DblDyneVec = nil;
|
BtTests: DblDyneVec = nil;
|
||||||
tProbs: DblDyneVec = nil;
|
tProbs: DblDyneVec = nil;
|
||||||
PrintDesc: boolean = true;
|
|
||||||
predicted: Double;
|
predicted: Double;
|
||||||
lReport: TStrings;
|
lReport: TStrings;
|
||||||
StdErrEst: Double = 0.0;
|
StdErrEst: Double = 0.0;
|
||||||
R2: Double = 0.0;
|
R2: Double = 0.0;
|
||||||
errorcode: Boolean = false;
|
errorcode: Boolean = false;
|
||||||
|
PrintDesc: boolean = true;
|
||||||
begin
|
begin
|
||||||
PrintDesc := true;
|
|
||||||
|
|
||||||
SetLength(Means, NoVariables + 2);
|
SetLength(Means, NoVariables + 2);
|
||||||
SetLength(Variances, NoVariables + 2);
|
SetLength(Variances, NoVariables + 2);
|
||||||
SetLength(StdDevs, NoVariables + 2);
|
SetLength(StdDevs, NoVariables + 2);
|
||||||
SetLength(BWeights, NoVariables + 2);
|
SetLength(BWeights, NoVariables + 2); // do not remove!
|
||||||
SetLength(BetaWeights, NoVariables + 2);
|
SetLength(BetaWeights, NoVariables + 2);
|
||||||
SetLength(BStdErrs, NoVariables + 2);
|
SetLength(BStdErrs, NoVariables + 2);
|
||||||
SetLength(Bttests, NoVariables + 2);
|
SetLength(Bttests, NoVariables + 2);
|
||||||
SetLength(tprobs, NoVariables + 2);
|
SetLength(tprobs, NoVariables + 2);
|
||||||
// SetLength(RowLabels, NoVariables + 2);
|
|
||||||
// SetLength(IndepCols, NoVariables + 2);
|
|
||||||
// SetLength(ColNoSelected, 2);
|
|
||||||
|
|
||||||
lReport := TStringList.Create;
|
lReport := TStringList.Create;
|
||||||
try
|
try
|
||||||
NCases := NoCases;
|
NCases := NoCases;
|
||||||
// NoIndep := IndVarList.Items.Count;
|
|
||||||
|
|
||||||
if not PrepareData(depCol, NoIndep, indepCols, wghtCol, RowLabels) then
|
// Get column indexes and do some validation checks.
|
||||||
|
// NOTE that the Length(indepCols) is different from NoIndep.
|
||||||
|
if not PrepareData(depCol, noIndep, indepCols, weightCol, RowLabels) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ wp: I think this is not correct: The column index is the last one in this
|
// Save dependent column so we can re-use DepCol
|
||||||
call. And why is row 0 checked?
|
oldDepCol := depCol;
|
||||||
// check variable types
|
|
||||||
if not ValidValue(OS3MainFrm.DataGrid, DepCol, 0) then
|
|
||||||
begin
|
|
||||||
ErrorMsg('Incorrect dependent variable type.');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (WghtCol > -1) then
|
|
||||||
begin
|
|
||||||
if not ValidValue(OS3MainFrm.DataGrid, WghtCol, 0) then
|
|
||||||
begin
|
|
||||||
ErrorMsg('Incorrect weight variable type.');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
for j := 0 to Noindep - 1 do
|
|
||||||
begin
|
|
||||||
if not ValidValue(OS3MainFrm.DataGrid, IndepCols[j],0) then
|
|
||||||
begin
|
|
||||||
ErrorMsg('Incorrect dependent variable type.');
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndepCols[NoIndep] := depCol;
|
|
||||||
oldDepCol := DepCol; // save dependent column so we can reuse DepCol
|
|
||||||
|
|
||||||
// *** Get OLS regression ***
|
// *** Get OLS regression ***
|
||||||
lReport.Clear;
|
Process_OLSRegression(indepCols, noIndep, depCol, RowLabels, nCases, printDesc);
|
||||||
lReport.Add('ORDINARY LEAST SQUARES (OLS) REGRESSION RESULTS');
|
|
||||||
lReport.Add('');
|
|
||||||
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
|
||||||
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
|
|
||||||
NCases, errorcode, PrintDesc, lReport);
|
|
||||||
|
|
||||||
// Get predicted z score, residual z score, predicted raw score,
|
|
||||||
// residual raw score and squared raw residual score. Place in the DataGrid
|
|
||||||
PredictIt(IndepCols, Noindep+1, Means, StdDevs, BetaWeights, stderrest, NoIndep);
|
|
||||||
|
|
||||||
OLSReportFrame.DisplayReport(lReport);
|
|
||||||
lReport.Clear;
|
|
||||||
|
|
||||||
// *** Regress the squared residuals on the predictors ***
|
// *** Regress the squared residuals on the predictors ***
|
||||||
depCol := NoVariables;
|
depCol := NoVariables;
|
||||||
lReport.Clear;
|
Process_SquaredResidualsRegression(indepCols, noIndep, depCol, RowLabels,
|
||||||
lReport.Add('REGRESSION OF SQUARED RESIDUALS ON INDEPENDENT VARIABLES');
|
BWeights, nCases, printDesc);
|
||||||
lReport.Add('');
|
|
||||||
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
|
||||||
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
|
|
||||||
NCases, errorcode, PrintDesc, lReport);
|
|
||||||
|
|
||||||
ResidualsRegReportFrame.DisplayReport(lReport);
|
|
||||||
lReport.Clear;
|
|
||||||
|
|
||||||
if WeightChk.Checked then
|
if WeightChk.Checked then
|
||||||
begin
|
AddPredictedStuffToGrid(indepCols, noIndep, BWeights);
|
||||||
// Get predicted squared residuals and save recipricols as weights
|
|
||||||
col := NoVariables + 1;
|
|
||||||
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
|
||||||
DictionaryFrm.NewVar(col);
|
|
||||||
DictionaryFrm.DictGrid.Cells[1,col] := 'PredResid2';
|
|
||||||
OS3MainFrm.DataGrid.Cells[col,0] := 'PredResid2';
|
|
||||||
|
|
||||||
col := NoVariables + 1;
|
|
||||||
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
|
||||||
DictionaryFrm.NewVar(col);
|
|
||||||
DictionaryFrm.DictGrid.Cells[1,col] := 'WEIGHT';
|
|
||||||
OS3MainFrm.DataGrid.Cells[col,0] := 'WEIGHT';
|
|
||||||
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
|
||||||
|
|
||||||
for i := 1 to NoCases do
|
|
||||||
begin
|
|
||||||
if (DataProcs.ValidValue(i, col-2)) then // do we have a valid squared OLS residual?
|
|
||||||
begin
|
|
||||||
predicted := 0.0;
|
|
||||||
for j := 0 to NoIndep - 1 do
|
|
||||||
begin
|
|
||||||
pos := IndepCols[j];
|
|
||||||
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
|
|
||||||
predicted := predicted + BWeights[j] * X;
|
|
||||||
end;
|
|
||||||
predicted := predicted + BWeights[Noindep];
|
|
||||||
predicted := abs(predicted);
|
|
||||||
OS3MainFrm.DataGrid.Cells[col-1,i] := Format('%.3f', [predicted]);
|
|
||||||
if (predicted > 0.0) then
|
|
||||||
predicted := 1.0 / sqrt(predicted)
|
|
||||||
else
|
|
||||||
predicted := 0.0;
|
|
||||||
OS3MainFrm.DataGrid.Cells[col,i] := Format('%.3f', [predicted]);
|
|
||||||
end; // if valid case
|
|
||||||
end; // next i
|
|
||||||
end; // if regresChk
|
|
||||||
|
|
||||||
// *** Display squared residuals for each independent variable ***
|
// *** Display squared residuals for each independent variable ***
|
||||||
PlotSquaredResiduals(IndepCols, NoIndep, DepCol, 0.95);
|
// NOTE: depCol points to the squared residuals column here
|
||||||
|
PlotSquaredResiduals(IndepCols, NoIndep, depCol, 0.95);
|
||||||
|
|
||||||
if not UserWeightsChk.Checked then
|
if WeightChk.Checked then
|
||||||
begin
|
begin
|
||||||
// Weight variables and do OLS regression on weighted variables
|
// Weight variables and do OLS regression on weighted variables
|
||||||
DepCol := olddepcol;
|
DepCol := olddepcol;
|
||||||
@ -312,7 +279,7 @@ begin
|
|||||||
pos := IndepCols[j];
|
pos := IndepCols[j];
|
||||||
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
|
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
|
||||||
X := X * Y;
|
X := X * Y;
|
||||||
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
|
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID CELLS
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -339,7 +306,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
|
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[pos,i]));
|
||||||
X := X - Means[j];
|
X := X - Means[j];
|
||||||
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
|
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID DATA!
|
||||||
end;
|
end;
|
||||||
end; // next i
|
end; // next i
|
||||||
end; // next j
|
end; // next j
|
||||||
@ -349,25 +316,25 @@ begin
|
|||||||
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
|
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
|
||||||
lReport.Add('');
|
lReport.Add('');
|
||||||
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
||||||
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
|
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
|
||||||
NCases, errorcode, PrintDesc, lReport);
|
NCases, errorcode, PrintDesc, lReport);
|
||||||
|
|
||||||
WLSReportFrame.DisplayReport(lReport);
|
WLSReportFrame.DisplayReport(lReport);
|
||||||
lReport.Clear;
|
lReport.Clear;
|
||||||
end // if useweightschk checked
|
end; // if weightschk checked
|
||||||
else
|
|
||||||
// use the weights entered by the user
|
// use the weights entered by the user
|
||||||
if (UserWeightsChk.Checked) then
|
if UserWeightsChk.Checked then
|
||||||
begin
|
begin
|
||||||
// Weight variables and do OLS regression on weighted variables
|
// Weight variables and do OLS regression on weighted variables
|
||||||
DepCol := olddepcol;
|
depCol := olddepcol;
|
||||||
IndepCols[Noindep] := DepCol;
|
indepCols[Noindep] := depCol; // wp: CALCULATION SHOULD NORMALIZE USER WEIGHTS HERE !!!
|
||||||
for i := 1 to NoCases do
|
for i := 1 to NoCases do
|
||||||
begin
|
begin
|
||||||
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[WghtCol,i])); // weight
|
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[weightCol,i])); // weight
|
||||||
for j := 0 to Noindep do
|
for j := 0 to Noindep do
|
||||||
begin
|
begin
|
||||||
pos := IndepCols[j];
|
pos := indepCols[j];
|
||||||
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
|
||||||
X := X * Y;
|
X := X * Y;
|
||||||
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
|
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
|
||||||
@ -395,7 +362,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[pos,i]);
|
||||||
X := X - Means[j];
|
X := X - Means[j];
|
||||||
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X);
|
OS3MainFrm.DataGrid.Cells[pos,i] := FloatToStr(X); // wp: DON'T OVERWRITE GRID DATA!
|
||||||
end;
|
end;
|
||||||
end; // next i
|
end; // next i
|
||||||
end; // next j
|
end; // next j
|
||||||
@ -405,7 +372,7 @@ begin
|
|||||||
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
|
lReport.Add('WEIGHTED LEAST SQUARES (WLS) REGRESSION RESULTS');
|
||||||
lReport.Add('');
|
lReport.Add('');
|
||||||
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
MReg(Noindep, IndepCols, DepCol, RowLabels, Means, Variances, StdDevs,
|
||||||
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stderrest,
|
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
|
||||||
NCases, errorcode, PrintDesc, lReport);
|
NCases, errorcode, PrintDesc, lReport);
|
||||||
|
|
||||||
WLSReportFrame.DisplayReport(lReport);
|
WLSReportFrame.DisplayReport(lReport);
|
||||||
@ -689,7 +656,6 @@ var
|
|||||||
predicted, zpredicted, z1, z2, resid, residsqr: double;
|
predicted, zpredicted, z1, z2, resid, residsqr: double;
|
||||||
begin
|
begin
|
||||||
col := NoVariables + 1;
|
col := NoVariables + 1;
|
||||||
// NoVariables := col;
|
|
||||||
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
||||||
DictionaryFrm.DictGrid.ColCount := 8;
|
DictionaryFrm.DictGrid.ColCount := 8;
|
||||||
DictionaryFrm.NewVar(col);
|
DictionaryFrm.NewVar(col);
|
||||||
@ -697,7 +663,6 @@ begin
|
|||||||
DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.z';
|
DictionaryFrm.DictGrid.Cells[1,col] := 'Pred.z';
|
||||||
|
|
||||||
col := NoVariables + 1;
|
col := NoVariables + 1;
|
||||||
// NoVariables := col;
|
|
||||||
DictionaryFrm.NewVar(col);
|
DictionaryFrm.NewVar(col);
|
||||||
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
OS3MainFrm.NoVarsEdit.Text := IntToStr(NoVariables);
|
||||||
OS3MainFrm.DataGrid.Cells[col,0] := 'z Resid.';
|
OS3MainFrm.DataGrid.Cells[col,0] := 'z Resid.';
|
||||||
@ -761,7 +726,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
residsqr := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]);
|
residsqr := StrToFloat(OS3MainFrm.DataGrid.Cells[col-1,i]);
|
||||||
residsqr := residsqr * residsqr;
|
residsqr := residsqr * residsqr;
|
||||||
OS3MainFrm.DataGrid.Cells[col,i] := Format('%8.3f',[residsqr]);
|
OS3MainFrm.DataGrid.Cells[col,i] := Format('%.3f',[residsqr]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -807,10 +772,124 @@ begin
|
|||||||
ARowLabels[i] := IndVarList.Items[i];
|
ARowLabels[i] := IndVarList.Items[i];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Append dependent column index to the independent columns vector.
|
||||||
|
AIndepCols[ANumIndepCols] := ADepCol;
|
||||||
|
|
||||||
|
// Check variable types: all of them must be numeric (float or integer)
|
||||||
|
if not IsNumericCol(ADepCol) then
|
||||||
|
begin
|
||||||
|
ErrorMsg('Incorrect data type of dependent variable.');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i := 0 to ANumIndepCols-1 do
|
||||||
|
if not IsNumericCol(AIndepCols[i]) then
|
||||||
|
begin
|
||||||
|
ErrorMsg('Incorrect data type of independent variable "%s"', [ARowLabels[i]]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (AWeightCol > -1) and (not IsNumericCol(AWeightCol)) then
|
||||||
|
begin
|
||||||
|
ErrorMsg('Incorrect data type of weight variable.');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
Result := true;
|
Result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ Runs the ordinary least squares regression on the grid data }
|
||||||
|
function TWLSFrm.Process_OLSRegression(AIndepCols: IntDyneVec; ANumIndepCols, ADepCol: Integer;
|
||||||
|
ARowLabels: StrDyneVec; ANumCases: Integer; PrintAll: Boolean): Boolean;
|
||||||
|
var
|
||||||
|
lReport: TStrings;
|
||||||
|
means: DblDyneVec = nil;
|
||||||
|
variances: DblDyneVec = nil;
|
||||||
|
stdDevs: DblDyneVec = nil;
|
||||||
|
BWeights: DblDyneVec = nil;
|
||||||
|
BetaWeights: DblDyneVec = nil;
|
||||||
|
BStdErrs: DblDyneVec = nil;
|
||||||
|
BtTests: DblDyneVec = nil;
|
||||||
|
tProbs: DblDyneVec = nil;
|
||||||
|
R2, stdErrEst: Double;
|
||||||
|
error: Boolean;
|
||||||
|
begin
|
||||||
|
Result := false;
|
||||||
|
|
||||||
|
lReport := TStringList.Create;
|
||||||
|
try
|
||||||
|
lReport.Add('ORDINARY LEAST SQUARES (OLS) REGRESSION RESULTS');
|
||||||
|
lReport.Add('');
|
||||||
|
|
||||||
|
SetLength(means, NoVariables + 2);
|
||||||
|
SetLength(variances, NoVariables + 2);
|
||||||
|
SetLength(stdDevs, NoVariables + 2);
|
||||||
|
SetLength(BWeights, NoVariables + 2);
|
||||||
|
SetLength(BetaWeights, NoVariables + 2);
|
||||||
|
SetLength(BStdErrs, NoVariables + 2);
|
||||||
|
SetLength(Bttests, NoVariables + 2);
|
||||||
|
SetLength(tprobs, NoVariables + 2);
|
||||||
|
|
||||||
|
MReg(ANumIndepCols, AIndepCols, ADepCol, ARowLabels, Means, Variances, StdDevs,
|
||||||
|
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
|
||||||
|
ANumCases, error, PrintAll, lReport);
|
||||||
|
|
||||||
|
// if error then // wp: Why does MReg exit with error???
|
||||||
|
// exit;
|
||||||
|
|
||||||
|
// Get predicted z score, residual z score, predicted raw score,
|
||||||
|
// residual raw score and squared raw residual score. Place in the DataGrid
|
||||||
|
PredictIt(AIndepCols, ANumIndepCols+1, means, stdDevs, BetaWeights, stdErrEst, ANumIndepCols);
|
||||||
|
|
||||||
|
OLSReportFrame.DisplayReport(lReport);
|
||||||
|
|
||||||
|
Result := true;
|
||||||
|
finally
|
||||||
|
lReport.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TWLSFrm.Process_SquaredResidualsRegression(AIndepCols: IntDyneVec;
|
||||||
|
ANumIndepCols, ADepCol: Integer; ARowLabels: StrDyneVec; BWeights: DblDyneVec;
|
||||||
|
ANumCases: Integer; PrintAll: Boolean): Boolean;
|
||||||
|
var
|
||||||
|
lReport: TStrings;
|
||||||
|
means: DblDyneVec = nil;
|
||||||
|
variances: DblDyneVec = nil;
|
||||||
|
stdDevs: DblDyneVec = nil;
|
||||||
|
BetaWeights: DblDyneVec = nil;
|
||||||
|
BStdErrs: DblDyneVec = nil;
|
||||||
|
BtTests: DblDyneVec = nil;
|
||||||
|
tProbs: DblDyneVec = nil;
|
||||||
|
R2, stdErrEst: Double;
|
||||||
|
error: Boolean;
|
||||||
|
begin
|
||||||
|
lReport := TStringList.Create;
|
||||||
|
try
|
||||||
|
lReport.Add('REGRESSION OF SQUARED RESIDUALS ON INDEPENDENT VARIABLES');
|
||||||
|
lReport.Add('');
|
||||||
|
|
||||||
|
SetLength(means, NoVariables + 2);
|
||||||
|
SetLength(variances, NoVariables + 2);
|
||||||
|
SetLength(stdDevs, NoVariables + 2);
|
||||||
|
SetLength(BetaWeights, NoVariables + 2);
|
||||||
|
SetLength(BStdErrs, NoVariables + 2);
|
||||||
|
SetLength(Bttests, NoVariables + 2);
|
||||||
|
SetLength(tprobs, NoVariables + 2);
|
||||||
|
|
||||||
|
MReg(ANumIndepCols, AIndepCols, ADepCol, ARowLabels, Means, Variances, StdDevs,
|
||||||
|
BWeights, BetaWeights, BStdErrs, Bttests, tprobs, R2, stdErrEst,
|
||||||
|
ANumCases, error, PrintAll, lReport);
|
||||||
|
|
||||||
|
ResidualsRegReportFrame.DisplayReport(lReport);
|
||||||
|
finally
|
||||||
|
lReport.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TWLSFrm.Reset;
|
procedure TWLSFrm.Reset;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
|
@ -25,6 +25,8 @@ function IsFiltered(AGrid: TStringGrid; ARow: integer): boolean;
|
|||||||
|
|
||||||
function IsMissingValueCode(AGrid: TStringGrid; ARow, ACol: Integer): Boolean;
|
function IsMissingValueCode(AGrid: TStringGrid; ARow, ACol: Integer): Boolean;
|
||||||
|
|
||||||
|
function IsNumericCol(AColIndex: Integer): Boolean;
|
||||||
|
|
||||||
function ValidValue(AGrid: TStringGrid; ARow, ACol: integer): boolean;
|
function ValidValue(AGrid: TStringGrid; ARow, ACol: integer): boolean;
|
||||||
|
|
||||||
|
|
||||||
@ -155,6 +157,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ Checks in the dictionary whether the variable in the specified grid column has
|
||||||
|
either data type float or integer. }
|
||||||
|
function IsNumericCol(AColIndex: Integer): Boolean;
|
||||||
|
var
|
||||||
|
typeCode: String;
|
||||||
|
begin
|
||||||
|
typeCode := Trim(DictionaryFrm.DictGrid.Cells[4, AColIndex]);
|
||||||
|
Result := (typeCode = 'F') or (typeCode = 'I');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Checks wheter the value in cell at the given column and row is a not-filtered,
|
{ Checks wheter the value in cell at the given column and row is a not-filtered,
|
||||||
non-empty number.
|
non-empty number.
|
||||||
NOTE: non-numeric characters in a numeric field are not taken into account! }
|
NOTE: non-numeric characters in a numeric field are not taken into account! }
|
||||||
|
@ -53,7 +53,7 @@ procedure EffectCode(GridCol, min, max : integer;
|
|||||||
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
|
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
|
||||||
const RowLabels: StrDyneVec;
|
const RowLabels: StrDyneVec;
|
||||||
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
|
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
|
||||||
out R2, StdErrEst: double; out NCases: integer; out ErrorCode: boolean;
|
out R2, StdErrEst: double; NCases: integer; out ErrorCode: boolean;
|
||||||
PrintAll: boolean; AReport: TStrings);
|
PrintAll: boolean; AReport: TStrings);
|
||||||
|
|
||||||
procedure Dynnonsymroots(var a : DblDyneMat; nv : integer;
|
procedure Dynnonsymroots(var a : DblDyneMat; nv : integer;
|
||||||
@ -347,16 +347,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
// Product of matrix b times c with results returned in a
|
// Product of matrix B times C with results returned in a: A = B C
|
||||||
procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
|
procedure MatAxB(const A, B, C: DblDyneMat; BRows, BCols, CRows, CCols: Integer;
|
||||||
out ErrorCode: boolean);
|
out ErrorCode: boolean);
|
||||||
var
|
var
|
||||||
i, j, k: integer;
|
i, j, k: integer;
|
||||||
begin
|
begin
|
||||||
ErrorCode := false;
|
ErrorCode := BCols <> CRows;
|
||||||
if (BCols <> CRows) then
|
if not ErrorCode then
|
||||||
ErrorCode := true
|
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
for i := 0 to BRows-1 do
|
for i := 0 to BRows-1 do
|
||||||
begin
|
begin
|
||||||
@ -633,7 +631,7 @@ end;
|
|||||||
Variances ... Variance of each independent variable
|
Variances ... Variance of each independent variable
|
||||||
StdDevs ..... Standard deviations of each independent variable
|
StdDevs ..... Standard deviations of each independent variable
|
||||||
|
|
||||||
NCases ...... Count of valid cases found in the grid
|
NCases ...... Count valid cases in the grid
|
||||||
ErrorCode ... if true, an error has occured during the calculations
|
ErrorCode ... if true, an error has occured during the calculations
|
||||||
PrintAll .... if true, intermediate matrices and vectors are written to the report
|
PrintAll .... if true, intermediate matrices and vectors are written to the report
|
||||||
AReport ..... a string list to which the report is written.
|
AReport ..... a string list to which the report is written.
|
||||||
@ -641,7 +639,7 @@ end;
|
|||||||
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
|
procedure MReg(NoIndep: integer; const IndepCols: IntDyneVec; DepCol: integer;
|
||||||
const RowLabels: StrDyneVec;
|
const RowLabels: StrDyneVec;
|
||||||
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
|
const Means, Variances, StdDevs, BWeights, BetaWeights, BStdErrs, Bttests, tProbs: DblDyneVec;
|
||||||
out R2, StdErrEst: double; out NCases: integer; out ErrorCode: boolean;
|
out R2, StdErrEst: double; NCases: integer; out ErrorCode: boolean;
|
||||||
PrintAll: boolean; AReport: TStrings);
|
PrintAll: boolean; AReport: TStrings);
|
||||||
var
|
var
|
||||||
i, j, N: integer;
|
i, j, N: integer;
|
||||||
@ -751,6 +749,9 @@ begin
|
|||||||
|
|
||||||
// get product of the augmented X transpose times augmented X
|
// get product of the augmented X transpose times augmented X
|
||||||
MatAXB(XTX, XT, X, NoIndep+1, NCases, NCases, NoIndep+1, errorcode);
|
MatAXB(XTX, XT, X, NoIndep+1, NCases, NCases, NoIndep+1, errorcode);
|
||||||
|
if errorCode then
|
||||||
|
exit;
|
||||||
|
|
||||||
if PrintAll then
|
if PrintAll then
|
||||||
begin
|
begin
|
||||||
title := 'XTX MATRIX';
|
title := 'XTX MATRIX';
|
||||||
|
Reference in New Issue
Block a user