Java实现混合高斯聚类

用Java重新了混合高斯分类。

写完测试用Vectors.dense( 1.0,2.0,3.0 ), Vectors.dense( 2.0,2.0,3.0 ),Vectors.dense( 3.0,2.0,3.0 )做测试,参数为 TestGaussianMixture gaussian = new TestGaussianMixture( 2, 0.01,2,10);然后看model中的weights。

测试结果为5.5951692130668595E-8, 0.9999999440483078,可是用GaussianMixture计算结果5.5951692130668595E-8,0.9999999440483078

结果不一样,因为我机器不能调试scala代码,直接看,看了一遍又一遍,几天也不知道错在哪里。然后用反射一个一个替换写的方法,还是没有头绪。然后给GaussianMixture设置初始的model(和我们计算的一样),突然GaussianMixture计算结果就是5.5951692130668595E-8, 0.9999999440483078,问题就出在初始化的model上。

初始化就两个方法,都没有问题,但是当用反射的方法替代vectorMean 方法时,得到了正确的值。又仔细看了一遍,代码没有问题,是损失了精度。

原来的代码为

private static Vector vectorMean( List<Vector> list )
{
int size = list.size( );
Vector retValue = Vectors.zeros( list.get( 0 ).size( ) );
for ( Vector v : list )
{
BLAS.axpy( 1.0, v, retValue );
}
BLAS.scal( 1.0 / size, retValue );
return retValue;
}

在计算scal的时候14/5 = 2.8000000003,用反射调用GaussianMixture的这个方法时就是2.8.

然后改成

private static Vector vectorMean( List<Vector> list )
{
int size = list.size( );
Vector retValue = Vectors.zeros( list.get( 0 ).size( ) );
for ( Vector v : list )
{
BLAS.axpy( 1.0, v, retValue );
}
double[] ds = retValue.toArray( );
for (int i=0; i< ds.length; i++)
{
ds[i] = div( ds[i], size, 1 );
}
return retValue;
}

private static double div(double d1,double d2,int scale)
{  
        BigDecimal b1=new BigDecimal(Double.toString(d1));  
        BigDecimal b2=new BigDecimal(Double.toString(d2));  
        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();  
    }


结果就正确了。

过程几乎什么都怀疑了,但是问题就出在这个简单的方法上。


源代码如下


import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


import org.apache.spark.SparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.broadcast.Broadcast;
import org.apache.spark.mllib.linalg.BLAS;
import org.apache.spark.mllib.linalg.DenseMatrix;
import org.apache.spark.mllib.linalg.Matrices;
import org.apache.spark.mllib.linalg.Matrix;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
import org.apache.spark.mllib.stat.distribution.MultivariateGaussian;
import org.apache.spark.mllib.util.MLUtils$;
import org.apache.spark.rdd.RDD;


import scala.Array;
import scala.Tuple2;
import scala.Tuple3;
import scala.collection.JavaConverters;
import scala.reflect.ClassManifestFactory;
import scala.runtime.AbstractFunction0;
import scala.runtime.AbstractFunction1;
import scala.runtime.AbstractFunction2;


/**
 * 
 */


public class GaoGaussianMixture implements Serializable
{


private int k;
private double convergenceTol;
private int maxIterations;
private long seed;
private int nSamples = 5;

public GaoGaussianMixture()
{
this(2, 0.01, 100, new Random().nextInt( ));
}

public GaoGaussianMixture( int k, double convergenceTol, int maxIterations, long seed )
{
super( );
this.k = k;
this.convergenceTol = convergenceTol;
this.maxIterations = maxIterations;
this.seed = seed;
}


public GaoGaussianMixtureModel run( JavaRDD<Vector> data )
{
retur

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值