如何使用带字符串类型字段的自定义POJO使用ELKI Java API在数据库中添加索引

时间:2018-07-20 01:06:42

标签: java cluster-analysis java-api dbscan elki

我正在使用DBSCAN通过POJO聚类一些分类数据。我的课看起来像这样

public class Dimension {
    private String app;
    private String node;
    private String cluster;
 .............

我所有的字段都是String而不是integer或Float,因为它们是离散/分类值。我其余的代码如下。

    final SimpleTypeInformation<Dimension> dimensionTypeInformation = new SimpleTypeInformation<>(Dimension.class);
    PrimitiveDistanceFunction<Dimension> dimensionPrimitiveDistanceFunction = new PrimitiveDistanceFunction<Dimension>() {
        public double distance(Dimension d1, Dimension d2) {
            return simpleMatchingCoefficient(d1, d2);
        }
        public SimpleTypeInformation<? super Dimension> getInputTypeRestriction() {
            return dimensionTypeInformation;
        }
        public boolean isSymmetric() {
            return true;
        }
        public boolean isMetric() {
            return true;
        }
        public <T extends Dimension> DistanceQuery<T> instantiate(Relation<T> relation) {
            return new PrimitiveDistanceQuery<>(relation, this);
        }
    };
    DatabaseConnection dbc = new DimensionDatabaseConnection(dimensionList);
    Database db = new StaticArrayDatabase(dbc, null);
    db.initialize();
    DBSCAN<Dimension> dbscan = new DBSCAN<>(dimensionPrimitiveDistanceFunction, 0.6, 20);
    Result result = dbscan.run(db);

现在,正如预期的那样,此代码对于小型数据集可以正常工作,但是当我的数据集变大时,它变得非常慢。因此,我想添加一个索引以加快该过程。但是我能想到的所有索引都要求我实现NumberVector。但是我的班级只有字串,没有数字。 在这种情况下可以使用什么索引?我可以使用距离函数,double simpleMatchingCoefficient(Dimension d1,Dimension d2)来创建IndexFactory吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

(至少)有三大类索引:

  1. 基于坐标的索引,例如k-d树和R树。这些可以很好地处理密集的连续变量
  2. 指标索引,需要距离函数以满足三角形不等式。它们可以处理任何类型的数据,但可能仍需要距离值的相当平滑的分布(例如,它们将对离散度量无济于事,即x = y为0,否则为1)。
  3. 反向查找索引。它们主要用于文本搜索,并利用每个属性的一小部分数据是相关的。这些对于高基数离散属性非常有效。

就您而言,我将考虑使用倒排索引。如果您有很多属性,则指标索引可能会起作用,但是我怀疑这种说法是否成立,因为您将POJO与字符串一起使用来存储数据。

当然,还要分析代码并检查是否可以改善距离功能的实现!例如。字符串实习可能会有所帮助,它可以减少字符串用于相等性测试的匹配时间,而不是比较每个字符...

答案 1 :(得分:1)

首先,请注意,SMC通常定义为相似性函数,而不是 distance 函数,但是1-SMC是常见的转换。只是不要混淆这两个。

对于简单的匹配系数,您可能希望针对特定的POJO数据类型构建自己的倒排索引。由于您的POJO设计(Dimension听起来像是一个很坏的名字,顺便说一句),因此无法以通用的,可重用的 方式轻松实现。那将需要昂贵的自省,并且仍然需要自定义:字符串匹配是否区分大小写?他们需要修剪吗?应该对它们进行标记吗?

您的倒排索引可能会包含一系列特定于您的POJO的地图:

Map<String, DBIDs> by_app;
Map<String, DBIDs> by_node;
Map<String, DBIDs> by_cluster;
...

,对于每个属性,您将获得匹配的DBID,并计算它们出现的频率。返回次数最多的DBIDs的SMC最高(因此距离也最低)。 在某些时候,您可能会忘记计算不再可以纳入结果集中的候选者。只需查找一本信息检索书,该搜索的工作原理。

如果每个属性的平均匹配数很低,那么这样的索引将是有益的。您可以通过位图索引压缩和类似技术进一步加快此过程,但这可能不是必需的(在某些时候,可以利用现有工具(例如Apache Lucene)来处理搜索会很有吸引力)。