首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ELKI的WeightedCorePredicate实现-示例

ELKI的WeightedCorePredicate实现-示例
EN

Stack Overflow用户
提问于 2020-12-09 01:42:52
回答 1查看 35关注 0票数 0

我最近试图通过修改CorePredicate (例如,使用MinPointCorePredicate作为构建的基础)在ELKI中实现加权数据库扫描的一个示例,我想知道在这种情况下,是否有人可以批评一下这是否是正确的实现:

代码语言:javascript
复制
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.*;
import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.KMeansLloyd;
import de.lmu.ifi.dbs.elki.data.Cluster;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.model.KMeansModel;
import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.database.StaticArrayDatabase;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.datasource.ArrayAdapterDatabaseConnection;
import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
import de.lmu.ifi.dbs.elki.datasource.DatabaseConnection;
import de.lmu.ifi.dbs.elki.distance.distancefunction.minkowski.SquaredEuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.algorithm.clustering.kmeans.initialization.RandomlyChosenInitialMeans;
//import de.lmu.ifi.dbs.elki.math.random.RandomFactory;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.database.Database;
import de.lmu.ifi.dbs.elki.distance.similarityfunction.kernel.RadialBasisFunctionKernelFunction;
import de.lmu.ifi.dbs.elki.data.Clustering;
import de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm;
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.EpsilonNeighborPredicate;
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.MinPtsCorePredicate;
import de.lmu.ifi.dbs.elki.database.datastore.WritableIntegerDataStore;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDoubleDataStore;

// Imports for generalized dbscan
import de.lmu.ifi.dbs.elki.algorithm.clustering.gdbscan.CorePredicate;
import de.lmu.ifi.dbs.elki.data.model.Model;
import de.lmu.ifi.dbs.elki.utilities.ELKIServiceLoader;



public class SampleELKI2 {

    public static void main(String[] args) {

        double[][] data = new double[1000][3]; // The third column refers to the weights
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                data[i][j] = Math.random();
                //System.out.println(i + " and " + j + " and " + data[i][j]);
            }
            //System.out.println(i + " and " + data[i][0] + " " + data[i][1] + " " + data[i][2]);
        }

        // Adapter to load data from an existing array
        DatabaseConnection dbc = new ArrayAdapterDatabaseConnection(data);
        //  Create a database (which may contain multiple relations
        Database db = new StaticArrayDatabase(dbc, null);
        // Load the data into the database (do NOT forget to initialize)
        db.initialize();
        // Relation containing the number vectors
        Relation<NumberVector> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD);
        // We know that the ids must be a continuous range
        DBIDRange ids = (DBIDRange) rel.getDBIDs();
        SquaredEuclideanDistanceFunction dist = SquaredEuclideanDistanceFunction.STATIC;
        // Default initialization, using global random:
        // To fix the random seed, use: new RandomFactory(seed);
        // Compute the neighbourhood and core predicates here for generalized gdbscan
        // --------------------------------------------------------------------- //
        EpsilonNeighborPredicate ENP = new EpsilonNeighborPredicate(0.3, dist); // Generic Neighbourhoodpredicate
        WeightedCorePredicate WCP = new WeightedCorePredicate(330, db, 2); // WeightedCorePredicate with the db  (db) and column index variable containing the weights (2)
        // The Implementation of the predicates in the GDBSCAN - predicates can be replaced for conditionals
        Clustering<Model> result = new GeneralizedDBSCAN(ENP, WCP, false).run(db);
        int i = 0;

        for (Cluster<Model> clu : result.getAllClusters()) {
            for (DBIDIter it = clu.getIDs().iter(); it.valid(); it.advance()) {
                NumberVector v = rel.get(it);
                final int offset = ids.getOffset(it);
            }
            ++i;
        }
    }
}

新的WeightedCorePredicate看起来像这样,它对ELKI源文件中的MinPtCorePredicate类进行了轻微的修改。

代码语言:javascript
复制
public class WeightedCorePredicate implements CorePredicate<DBIDs> {

   /**
   * Class logger.
   */
  public static final Logging LOG = Logging.getLogger(MinPtsCorePredicate.class);

  /**
   * The minpts parameter.
   */
  protected int minpts;
  static Database db;
  static int WeightColumn;
  static int WeightSum;
    /**
   * Default constructor.
   *
   * @param minpts Minimum number of neighbors to be a core point.
   */
  public WeightedCorePredicate(int minpts, Database db, int WeightColumn) {
    super();
    this.minpts = minpts;
    this.db = db;
    this.WeightColumn = WeightColumn;
  }

  @Override
  public Instance instantiate(Database database) {
      return new Instance(minpts, db, WeightColumn);
  }

  @Override
  public boolean acceptsType(SimpleTypeInformation<? extends DBIDs> type) {
    return TypeUtil.DBIDS.isAssignableFromType(type) //
        || TypeUtil.NEIGHBORLIST.isAssignableFromType(type);
  }

  /**
   * Instance for a particular data set.
   *
   * @author Erich Schubert
   */
  public static class Instance implements CorePredicate.Instance<DBIDs> {
    /**
     * The minpts parameter.
     */
    protected int minpts;
    protected Database db;
    protected int WeightColumn;
    protected double WeightSum;
    /**
     * Constructor for this predicate.
     *
     * @param minpts MinPts parameter
     */
    public Instance(int minpts, Database db, int WeightColumn) {
      super();
      this.minpts = minpts;
      this.db = db;
      this.WeightColumn = WeightColumn;
    }

    @Override
    public boolean isCorePoint(DBIDRef point, DBIDs neighbors) {
    db.initialize(); // Initialize database 
    Relation<NumberVector> rel = db.getRelation(TypeUtil.NUMBER_VECTOR_FIELD); // db relation to get to the datapoints 
    WeightSum = 0; // Make sure to initialize the weights as 0 
    // DBIDS contain the indices of the points - so just need a database relation to access the points at the index 

    for (DBIDIter it = neighbors.iter(); it.valid(); it.advance()) {
        //    System.out.print("The weights are " + rel.get(it).doubleValue(WeightColumn) + "\n");
        WeightSum += rel.get(it).doubleValue(WeightColumn); // Sum the weights 
    }

    return WeightSum >= minpts;
    }
  }
    
  /**
   * Parameterization class
   *
   * @author Erich Schubert
   */
  public static class Parameterizer extends AbstractParameterizer {
    /**
     * Minpts value
     */
    protected int minpts;

    @Override
    protected void makeOptions(Parameterization config) {
      super.makeOptions(config);
      // Get the minpts parameter
      IntParameter minptsP = new IntParameter(DBSCAN.Parameterizer.MINPTS_ID) //
          .addConstraint(CommonConstraints.GREATER_EQUAL_ONE_INT);
      if(config.grab(minptsP)) {
        minpts = minptsP.intValue();
        if(minpts <= 2) {
          LOG.warning("DBSCAN with minPts <= 2 is equivalent to single-link clustering at a single height. Consider using larger values of minPts.");
        }
      }
    }

    @Override
    protected WeightedCorePredicate makeInstance() {
    return new WeightedCorePredicate(minpts, db, WeightColumn);
    }
  }
}

本质上,我在WeightedCorePredicate中添加了输入,它引用数据库,我可以使用索引从rel和this.WeightColumn中挑选出数据库的元素,以便挑选出权重与X/Y列一起列出的列。这是本文讨论的后续内容:Elki GDBSCAN Java/Scala - how to modify the CorePredicatesample_weight option in the ELKI implementation of DBSCAN

任何关于这方面的反馈都将非常感谢。我没有Java背景,主要来自Python/Scala,所以我完全知道它不是最优雅的Java代码。

谢谢

EN

回答 1

Stack Overflow用户

发布于 2021-01-09 02:56:05

对于应该是局部变量或实例变量的内容,不要使用static变量!

在99.99%的情况下,他们做错了事情。

C.f.,Why are static variables considered evil?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65204069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档