自迁移出 MediaWiki 以来,本页内容尚未经过审查。如果您愿意帮忙,请查看帮助指南!
一个关于如何使用KDTree开始使用Weka的小知识
Weka似乎是一个非常好的框架,它实现了很多机器学习的东西。它完全基于Java开源。这里我只是想分享一下我开始使用Weka的经历。
###为什么我要使用Weka
就我而言,我在两个3D点云中找到了最近的邻居。
###设置维卡
总部提交on GitHub(2009年12月16日),斐济的主要分支配备了Weka。
使用 Weka 数据结构
Weka 似乎可以处理任何数据结构和类型。它们是使用 weka.core.Attribute 对象定义的,该对象甚至可以保存 weka.core.FastVector 对象。每个 weka.core.Instance 都是一个数据元素,包含 n 个属性各自的值。相同类型的 Instance 对象组使用 weka.core.Instances 进行分组。
下面是一个如何将 3D 点列表存储为 Weka 数据结构的 Java 方法。
/**
* Creates a Weka Datastructure out of a List of 3D Points
* @param points - List of 3D Points
* @param name - Instance name
* @return Instances containing all 3D points
*/
public Instances insertIntoWeka(final List <Point3d> points, final String name)
{
// Create numeric attributes "x" and "y" and "z"
Attribute x = new Attribute("x");
Attribute y = new Attribute("y");
Attribute z = new Attribute("z");
// Create vector of the above attributes
FastVector attributes = new FastVector(3);
attributes.addElement(x);
attributes.addElement(y);
attributes.addElement(z);
// Create the empty datasets "wekaPoints" with above attributes
Instances wekaPoints = new Instances(name, attributes, 0);
for (Iterator<Point3d> i = points.iterator(); i.hasNext();)
{
// Create empty instance with three attribute values
Instance inst = new Instance(3);
// get the point3d
Point3d p = i.next();
// Set instance's values for the attributes "x", "y", and "z"
inst.setValue(x, p.x);
inst.setValue(y, p.y);
inst.setValue(z, p.z);
// Set instance's dataset to be the dataset "wekaPoints"
inst.setDataset(wekaPoints);
// Add the Instance to Instances
wekaPoints.add(inst);
}
return wekaPoints;
}
KD树
设置§§0§§§相当简单。困难的部分是欧几里德距离。非常是,当我们只使用简单的数字属性时,Weka会自动计算出如何计算欧几里德距离。但是,默认情况下,它会独立地对每个维度的数据进行规范化,这可能会导致问题,就像我的情况一样。如果你想阻止他,你必须配置一个新的不标准化的EuclideanDistance对象。
//
// Create the weka datastructure for 3D Points
//
Instances wekaPoints1 = insertIntoWeka(points1, "wekaPoints1");
//
// Set up the KDTree
//
KDTree tree = new KDTree();
try
{
tree.setInstances(wekaPoints1);
EuclideanDistance df = new EuclideanDistance(wekaPoints1);
df.setDontNormalize(true);
tree.setDistanceFunction(df);
}
catch (Exception e) { e.printStackTrace();}
搜索 KDTree
一旦解决了规范化问题,在 KDTree 中搜索 N 最近的邻居就又连接简单了。您创建另一个相同类型的实例,从而 KDTree 询问其最近的邻居。
首先我们创建一个可用于搜索 KDTree 的实例。稍后,只需更新其值而不是为每个查询创建一个新值就非常简单了。
/**
* Create an Instance of the same type as the Instances object you are searching in.
* @param p - a 3D point
* @param dataset - the dataset you are searching in, which was used to build the KDTree
* @return an Instance that the nearest neighbor can be found for
*/
public Instance createInstance(final Point3d p, final Instances dataset)
{
// Create numeric attributes "x" and "y" and "z"
Attribute x = dataset.attribute(0);
Attribute y = dataset.attribute(1);
Attribute z = dataset.attribute(2);
// Create vector of the above attributes
FastVector attributes = new FastVector(3);
attributes.addElement(x);
attributes.addElement(y);
attributes.addElement(z);
// Create empty instance with three attribute values
Instance inst = new Instance(3);
// Set instance's values for the attributes "x", "y", and "z"
inst.setValue(x, p.x);
inst.setValue(y, p.y);
inst.setValue(z, p.z);
// Set instance's dataset to be the dataset "points1"
inst.setDataset(dataset);
return inst;
}
现在我们可以轻松地搜索KDTree。
// let's search for the nearest and second nearest neighbor
Instance nn1, nn2;
final Instance p = createInstance(new Point3d(0,0,0), wekaPoints);
try
{
Instances neighbors = tree.kNearestNeighbours(p, 2);
nn1 = neighbors.instance(0);
nn2 = neighbors.instance(1);
}
catch (Exception e) { nn1 = nn2 = null; }
System.out.println(nn1 + " is the nearest neigbor for " + p);
System.out.println(nn2 + " is the second nearest neigbor for " + p);
// Now we can also easily compute the distances as the KDTree does it
DistanceFunction df = tree.getDistanceFunction();
System.out.println("The distance between" + nn1 + " and " + p + " is " + df.distance(nn1, p));
System.out.println("The distance between" + nn2 + " and " + p + " is " + df.distance(nn2, p));
###另请参阅