实现尺寸和多类型数据的距离功能

时间:2017-10-03 15:07:31

标签: java twitter cluster-analysis elki

我在java中使用ELKI在kmeans算法中聚类推文的文本。在聚类之前,我计算了推文文本与用于聚类的tf-idf度量的相似性。

 public void clustering(String file) throws FileNotFoundException {
    //Distance.calSim("after sorting.txt");
    similarity = MainElki.getSimilarity();
    PrintWriter writer = new PrintWriter(new File(file));
    StringBuilder strBuilder = new StringBuilder();

    for (int k = 0; k < numCorpus; k = k + 20) {
        double[][] subArray = new double[20][20];
        subArray = getSubArray(k, k);

        DatabaseConnection dbc = new ArrayAdapterDatabaseConnection(subArray);
        Database db = new StaticArrayDatabase(dbc, null);
        db.initialize();
        SquaredEuclideanDistanceFunction dist = SquaredEuclideanDistanceFunction.STATIC;
        RandomlyGeneratedInitialMeans init = new RandomlyGeneratedInitialMeans(RandomFactory.DEFAULT);

        KMeansLloyd<NumberVector> km = new KMeansLloyd<>(dist, 3, 0, init);
        Clustering<KMeansModel> c = km.run(db);

        Relation<NumberVector> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
        DBIDRange ids = (DBIDRange) rel.getDBIDs();
        strBuilder.append("\n******** subArray[" + k + "]" + "[" + k + "]");
        int i = 2;
        for (Cluster<KMeansModel> clu : c.getAllClusters()) {
            // K-means will name all clusters "Cluster" in lack of noise support:
            strBuilder.append("\n    #" + i + ": " + clu.getNameAutomatic() + "\n");
            strBuilder.append("    Size: " + clu.size() + "\n");
            strBuilder.append("    Center: " + clu.getModel().getPrototype().toString() + "\n");

            strBuilder.append("  Objects: ");
            for (DBIDIter it = clu.getIDs().iter(); it.valid(); it.advance()) {
                // To get the vector use:
                NumberVector v = rel.get(it);

                // Offset within our DBID range: "line number"
                final int offset = ids.getOffset(it);
                strBuilder.append(" " + (offset + k));
                // Do NOT rely on using "internalGetIndex()" directly!
            }
            i++;
        }
    }//end of for subArray
    writer.write(strBuilder.toString());
    writer.close();
}//end of clustering function

现在我想在群集中使用推文的其他功能(示例主题标签,类似数量,转推数量......)。我知道我可以在ELKI中定义自定义距离函数,但ELKI的所有抽象类距离函数都在一个dataType(例如AbstractNumberVectorDistanceFunction)中,但是推文的特征是不同的:对于推文的文本的加倍,对于like和转发的数量为int,标签的字符串。

 public class CustomizedDistance extends AbstractNumberVectorDistanceFunction    {
 @Override
public double distance(NumberVector arg0, NumberVector arg1) {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

}

有没有办法编写自定义距离函数来计算推文文本的距离,然后通过使用其他功能来计算最终距离?

2 个答案:

答案 0 :(得分:1)

KMeans,顾名思义,需要计算意味着

此算法只能用于R ^ d中的向量。

所以无论如何,如果你真的想要这样做(kmeans在不同规模的属性上运作良好!)你必须转换所有属性都转换为数字。或者使用不同的算法。

答案 1 :(得分:1)

K-means只适用于NumberVector s,没有方式。

对于许多其他算法,这是可能的。你需要:

  1. 使用多种类型的数据实施新数据类型YourDataType
  2. 实施解析器以加载数据
  3. 实施DistanceFunction<YourDataType>
  4. 但正如Anony-Mousse的回答所指出的那样,k-means 只能支持NumberVector。它不接受YourDataType。因为它无法计算此数据的均值。

    我想在ELKI得到支持,但我自己并不需要这个;我没有看到这些数据的任何良好的距离函数(有Gower&#39;但它不是我认为的&#34;好的&#34; - 有用,它需要一个许多手动缩放,加权以及对每个数据集的这种修改都是如此),并且不清楚如何优化这种情况的实现。所以我的优先级列表实现自己太低了,但我很欣赏精心设计的拉取请求。