com.expleague.ml.methods.greedyRegion.GreedyPolynomialExponentRegion Maven / Gradle / Ivy
package com.expleague.ml.methods.greedyRegion;
import com.expleague.commons.math.MathTools;
import com.expleague.commons.math.vectors.Mx;
import com.expleague.commons.math.vectors.MxTools;
import com.expleague.commons.math.vectors.Vec;
import com.expleague.commons.math.vectors.VecTools;
import com.expleague.commons.math.vectors.impl.vectors.ArrayVec;
import com.expleague.ml.data.set.VecDataSet;
import com.expleague.ml.BFGrid;
import com.expleague.ml.impl.BinaryFeatureImpl;
import com.expleague.ml.loss.L2;
import com.expleague.ml.methods.VecOptimization;
import com.expleague.ml.models.Region;
import com.expleague.commons.math.vectors.impl.mx.VecBasedMx;
import com.expleague.ml.models.PolynomialExponentRegion;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
/**
* Created by towelenee on 20.02.14.
*/
public class GreedyPolynomialExponentRegion extends VecOptimization.Stub {
private final GreedyTDRegion greedyTDRegion;
private BFGrid.Feature[] features;
private boolean[] mask;
private final double distCoeffiecent, regulationCoeffiecent;
public GreedyPolynomialExponentRegion(final BFGrid grid, final double distCoeffiecent, final double regulationCoeffiecent) {
this.distCoeffiecent = distCoeffiecent;
this.regulationCoeffiecent = regulationCoeffiecent;
this.greedyTDRegion = new GreedyTDRegion(grid, 0.02, 0.5, 0);
}
double getDistanseFromRegion(final Vec x) {
double distanse = 0;
for (int i = 0; i < features.length; i++) {
if (features[i].value(x) != mask[i])
distanse += MathTools.sqr(features[i].condition() - x.get(features[i].findex()));
}
return distanse;
}
public static boolean validateSolution(final Mx a, final Vec right, final Vec sol) {
final Vec val = MxTools.multiply(a, sol);
final double l2 = VecTools.distance(val, right);
if (l2 > right.dim()) {
/*for (int i = 0; i < right.xdim(); i++)
System.out.format("%f = %f\n", val.at(i), right.at(i));*/
}
//System.out.println(l2);
return l2 < 0.1 * right.dim();
}
public static Vec solveLinearEquationUsingLQ(final Mx mx, final Vec right) {
if (mx.rows() != mx.columns())
throw new IllegalArgumentException("Matrix must be quadratic");
if (right.dim() != mx.rows())
throw new IllegalArgumentException("Vector must be the same size as Matrix");
final int n = mx.rows();
final Mx l = new VecBasedMx(n, n);
final Mx q = new VecBasedMx(n, n);
MxTools.householderLQ(mx, l, q);
//System.out.println(VecTools.inverseLTriangle(l));
//System.out.println(VecTools.multiply(q,VecTools.transpose(q)));
final Vec first = new ArrayVec(n);
for (int i = 0; i < n; i++) {
if (Math.abs(l.get(i, i)) > 1e-5) {
double val = right.get(i);
for (int j = 0; j < i; j++)
val -= first.get(j) * l.get(i, j);
first.set(i, val / l.get(i, i));
} else {
first.set(i, 0);
}
}
final Vec ans = MxTools.multiply(q, first);
if (!validateSolution(mx, right, ans)) {
PrintWriter printWriter = null;
try {
printWriter = new PrintWriter(new File("badMx.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
printWriter.println(mx.rows());
for (int i = 0; i < mx.rows(); i++)
for (int j = i + 1; j < mx.rows(); j++)
if (l.get(i, j) > 1e-5)
System.out.println("bad l" + l.get(i, j));
printWriter.println(mx);
printWriter.println(right);
printWriter.close();
throw new RuntimeException("Not correct work of solveLinearEquationUsingLQ");
}
return ans;
}
double sqr(final double x) {
return x * x;
}
@Override
public PolynomialExponentRegion fit(final VecDataSet learn, final L2 loss) {
final Region base = greedyTDRegion.fit(learn, loss);
features = base.features();
mask = base.masks();
double baseMse = 0;
for (int i = 0; i < learn.length(); i++)
baseMse += sqr(base.value(learn.data().row(i)) - loss.target.get(i));
System.out.println("\nBase_MSE = " + baseMse);
final int numberOfFeatures = features.length + 1;
final int matrixSize = (features.length + 1) * (features.length + 1);
final Mx mx = new VecBasedMx(matrixSize, matrixSize);
final Vec linear = new ArrayVec(matrixSize);
int countIn = 0;
double sum = 0;
for (int i = 0; i < learn.data().rows(); i++) {
final Vec vec = learn.data().row(i);
if (!base.contains(vec))
continue;
final double[] data = new double[numberOfFeatures];
data[0] = 1;
for (int j = 0; j < features.length; j++)
data[j + 1] = vec.get(features[j].findex());
final double f = loss.target.get(i);
sum += f;
countIn++;
final double weight = 1;// Math.exp(-getDistanseFromRegion(vec) * distCoeffiecent);
//System.out.println(weight);
for (int x = 0; x < numberOfFeatures; x++)
for (int y = 0; y < numberOfFeatures; y++)
linear.adjust(x + y * numberOfFeatures, -data[x] * data[y] * weight * f);
for (int x = 0; x < numberOfFeatures; x++)
for (int y = 0; y < numberOfFeatures; y++)
for (int xx = 0; xx < numberOfFeatures; xx++)
for (int yy = 0; yy < numberOfFeatures; yy++)
mx.adjust(x + y * numberOfFeatures, xx + yy * numberOfFeatures, data[x] * data[y] * data[xx] * data[yy] * weight);
}
System.out.println("\n" + countIn + " " + sum);
//for (int i = 0; i < matrixSize; i++)
//mx.adjust(i, i, regulationCoeffiecent);
for (int i = 0; i < matrixSize; i++)
linear.set(i, -linear.get(i));
//System.out.println(mx);
//System.out.println(linear);
//System.out.println(VecTools.inverseCholesky(mx));
final Vec result = solveLinearEquationUsingLQ(mx, linear);
//result.set(0, sum / countIn);
//for (int i = 1; i < result.xdim(); i++)
//result.set(i, 0);
System.out.println(result);
final PolynomialExponentRegion ret = new PolynomialExponentRegion(features, mask, result.toArray(), distCoeffiecent);
double mse = 0;
for (int i = 0; i < learn.length(); i++)
mse += sqr(ret.value(learn.data().row(i)) - loss.target.get(i));
System.out.println("mse = " + mse);
return ret;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy