Recently, I was writing a fluorescent image analysis software, which requires fitting the equation by myself. The algorithm of the one-dimensional regression formula references Java numerical method. The fitting degree R ^ 2 (absolute coefficient) is self-written. Welcome to discuss it. The calculation result is exactly the same as that in Excel.
A total of three files:
Datapoint. Java
/**
* A data point for interpolation and regression.
*/
Public class datapoint
{
/** The X value */public float X;
/** The Y value */public float y;
/**
* Constructor.
* @ Param x the X value
* @ Param y the Y value
*/
Public datapoint (float X, float y)
{
This. x = X;
This. Y = y;
}
}
/**
* A least-squares regression line function.
*/
Import java. util .*;
Import java. Math. bigdecimal;
Public class regressionline
// Implements evaluatable
{
/** Sum of x */private double sumx;
/** Sum of y */private double Sumy;
/** Sum of x */private double sumxx;
/** Sum of x * y */private double sumxy;
/** Sum of y */private double sumyy;
/** Sum of Yi-y */private double sumdeltay;
/** Sum of sumdeltay ^ 2 */private double sumdel%2;
/** Error */
Private double SSE;
Private double SST;
Private Double E;
Private string [] XY;
Private arraylist listx;
Private arraylist listy;
Private int xmin, xmax, ymin, Ymax;
/** Line coefficient A0 */private float A0;
/** Line coefficient A1 */private float A1;
/** Number of data points */private int PN;
/** True if coefficients valid */private Boolean coefsvalid;
/**
* Constructor.
*/
Public regressionline (){
Xmax = 0;
Ymax = 0;
Pn = 0;
XY = new string [2];
Listx = new arraylist ();
Listy = new arraylist ();
}
/**
* Constructor.
* @ Param data the array of data points
*/
Public regressionline (datapoint data [])
{
Pn = 0;
XY = new string [2];
Listx = new arraylist ();
Listy = new arraylist ();
For (INT I = 0; I <data. length; ++ I ){
Adddatapoint (data [I]);
}
}
/**
* Return the current number of data points.
* @ Return the count
*/
Public int getdatapointcount () {return PN ;}
/**
* Return the coefficient A0.
* @ Return the value of A0
*/
Public float geta0 ()
{
Validatecoefficients ();
Return A0;
}
/**
* Return the coefficient A1.
* @ Return the value of A1
*/
Public float geta1 ()
{
Validatecoefficients ();
Return A1;
}
/**
* Return the sum of the X values.
* @ Return the sum
*/
Public double getsumx () {return sumx ;}
/**
* Return the sum of the y values.
* @ Return the sum
*/
Public double getsumy () {return Sumy ;}
/**
* Return the sum of the X * x values.
* @ Return the sum
*/
Public double getsumxx () {return sumxx ;}
/**
* Return the sum of the X * y values.
* @ Return the sum
*/
Public double getsumxy () {return sumxy ;}
Public double getsumyy () {return sumyy ;}
Public int getxmin (){
Return xmin;
}
Public int getxmax (){
Return xmax;
}
Public int getymin (){
Return ymin;
}
Public int getymax (){
Return Ymax;
}
/**
* Add a new data point: update the sums.
* @ Param datapoint the new data point
*/
Public void adddatapoint (datapoint)
{
Sumx + = datapoint. X;
Sumy + = datapoint. Y;
Sumxx + = datapoint. x * datapoint. X;
Sumxy + = datapoint. x * datapoint. Y;
Sumyy + = datapoint. y * datapoint. Y;
If (datapoint. x> xmax ){
Xmax = (INT) datapoint. X;
}
If (datapoint. Y> Ymax ){
Ymax = (INT) datapoint. Y;
}
// Store the coordinates of each vertex in the arraylist.
XY [0] = (INT) datapoint. x + "";
XY [1] = (INT) datapoint. Y + "";
If (datapoint. X! = 0 & datapoint. y! = 0 ){
System. Out. Print (XY [0] + ",");
System. Out. println (XY [1]);
Try {
// System. Out. println ("N:" + n );
Listx. Add (Pn, XY [0]);
Listy. Add (Pn, XY [1]);
}
Catch (exception e ){
E. printstacktrace ();
}
/*
System. Out. println ("N:" + n );
System. Out. println ("arraylist listx:" + listx. Get (n ));
System. Out. println ("arraylist listy:" + listy. Get (n ));
*/
}
++ PN;
Coefsvalid = false;
}
/**
* Return the value of the regression line function at X.
* (Implementation of evaluatable .)
* @ Param x the value of X
* @ Return the value of the function at x
*/
Public float (int x)
{
If (PN <2) return float. Nan;
Validatecoefficients ();
Return A0 + A1 * X;
}
Public float (float X)
{
If (PN <2) return float. Nan;
Validatecoefficients ();
Return A0 + A1 * X;
}
/**
* Reset.
*/
Public void reset ()
{
Pn = 0;
Sumx = Sumy = sumxx = sumxy = 0;
Coefsvalid = false;
}
/**
* Validate the coefficients.
* Calculate a in equation coefficient y = ax + B
*/
Private void validatecoefficients ()
{
If (coefsvalid) return;
If (PN> = 2 ){
Float xbar = (float) sumx/PN;
Float ybar = (float) Sumy/PN;
A1 = (float) (PN * sumxy-sumx * Sumy)
/(PN * sumxx-sumx * sumx ));
A0 = (float) (ybar-A1 * xbar );
}
Else {
A0 = A1 = float. Nan;
}
Coefsvalid = true;
}
/**
* Return Error
*/
Public double getr (){
// Traverse the list and calculate the denominator
For (INT I = 0; I <PN-1; I ++ ){
Float YI = (float) integer. parseint (listy. Get (I). tostring ());
Float y = at (integer. parseint (listx. Get (I). tostring ()));
Float deltay = Yi-y;
Float deltay 2 = deltay * deltay;
/*
System. Out. println ("Yi:" + yi );
System. Out. println ("Y:" + y );
System. Out. println ("deltay:" + deltay );
System. Out. println ("delemedi2:" + delemedi2 );
*/
Sumdeldomain2 + = deldomain2;
// System. Out. println ("sumdelspon2:" + sumdelspon2 );
}
SST = sumyy-(Sumy * Sumy)/PN;
// System. Out. println ("SST:" + SST );
E = 1-sumdelw.2/SST;
Return round (E, 4 );
}
// Used for precise rounding
Public double round (Double V, int scale ){
If (scale <0 ){
Throw new illegalargumentexception (
"The scale must be a positive integer or zero ");
}
Bigdecimal B = new bigdecimal (double. tostring (V ));
Bigdecimal one = new bigdecimal ("1 ");
Return B. Divide (one, scale, bigdecimal. round_half_up). doublevalue ();
}
Public float round (float V, int scale ){
If (scale <0 ){
Throw new illegalargumentexception (
"The scale must be a positive integer or zero ");
}
Bigdecimal B = new bigdecimal (double. tostring (V ));
Bigdecimal one = new bigdecimal ("1 ");
Return B. Divide (one, scale, bigdecimal. round_half_up). floatvalue ();
}
}
Demo program:
Linearregression. Java
/**
* <P> <B> linear regression </B>
* <Br>
* Demonstrate linear regression by constructing the regression line for a set
* Of data points.
*
* <P> require datapoint. Java, regressionline. Java
*
* <P> to calculate the Minimum Variance return line for a given data point, sumx, Sumy, sumxx, and sumxy must be calculated. (Note: sumxx = sum (x ^ 2 ))
* <P> <B> regression linear equation: f (x) = a1x + a0 </B>
* <P> <B> the formula for calculating the slope and intercept is as follows: </B>
* <Br> N: number of data points
* <P> A1 = (N (sumxy)-sumx * Sumy)/(n * sumxx-(sumx) ^ 2)
* <Br> a0 = (Sumy-Sumy * A1)/n
* <Br> (can also be expressed as a0 = averageY-a1 * averagex)
*
* <P> <B> principle of draw a line: the two points are in a straight line. Only two points can be determined. </B> <br>
* The first point is: (0, a0). Then, take a X1 value and substitute it into the equation. Then, get Y1, Link (0, a0) and (x1, Y1.
* To let the line pass through the entire graph, X1 can take the maximum x max of the X coordinate, that is, the two points are (0, a0), (xmax, Y ). If y = A1 * xmax + a0, Y is greater
* If the ordinate value is Ymax, this point is not used. Use y to obtain the maximum Ymax value, and calculate the value of X at this time. Use (x, Ymax), that is, two points are (0, a0), (X, Ymax)
*
* <P> <B> fitting degree calculation: (R ^ 2 in Excel) </B>
* <P> * r2 = 1-e
* <P> Calculation of error E: E = SSE/SST
* <P> SSE = sum (Yi-y) ^ 2) SST = sumyy-(Sumy * Sumy)/N;
* <P>
*/
Public class linearregression
{
Private Static final int max_points = 10;
Private Double E;
/**
* Main program.
*
* @ Param ARGs
* The array of runtime arguments
*/
Public static void main (string ARGs [])
{
Regressionline = new regressionline ();
Line. adddatapoint (New datapoint (20,136 ));
Line. adddatapoint (New datapoint (40,143 ));
Line. adddatapoint (New datapoint (60,152 ));
Line. adddatapoint (New datapoint (80,162 ));
Line. adddatapoint (New datapoint (100,167 ));
Printsums (line );
Printline (line );
}
/**
* Print the computed sums.
*
* @ Param line
* The regression line
*/
Private Static void printsums (regressionline)
{
System. Out. println ("/n data point count n =" + LINE. getdatapointcount ());
System. Out. println ("/nsum x =" + LINE. getsumx ());
System. Out. println ("sum y =" + LINE. getsumy ());
System. Out. println ("sum xx =" + LINE. getsumxx ());
System. Out. println ("sum xy =" + LINE. getsumxy ());
System. Out. println ("sum YY =" + LINE. getsumyy ());
}
/**
* Print the regression line function.
*
* @ Param line
* The regression line
*/
Private Static void printline (regressionline)
{
System. Out. println ("/n regression formula: Y =" +
Line. geta1 () +
"X +" + LINE. geta0 ());
System. Out. println ("fitting degree: R ^ 2 =" + LINE. getr ());
}
}