Как работать с разреженными данными с помощью ELKI?
Я пытаюсь использовать разреженную матрицу в качестве входных данных в алгоритме ELKI SOD для обнаружения выбросов. Я искал справку на странице с практическими рекомендациями и часто задаваемыми вопросами о разреженных данных, поэтому я попытался использовать SparseNumberVectorLabelParser и SparseVectorFieldFilter, например:
//data is a mxn matrix
ArrayAdapterDatabaseConnection dataArray = new ArrayAdapterDatabaseConnection(data);
SparseDoubleVector.Factory sparseVector = new SparseDoubleVector.Factory();
SparseNumberVectorLabelParser<SparseDoubleVector> parser = new SparseNumberVectorLabelParser<SparseDoubleVector>(Pattern.compile("s*[,;s]s*")," \" ",Pattern.compile("^s*(#|//|;).*$"),null, sparseVector);
SparseVectorFieldFilter<SparseDoubleVector> sparseFilter = new SparseVectorFieldFilter<SparseDoubleVector>();
ListParameterization params = new ListParameterization();
params.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, dataArray);
params.addParameter(AbstractDatabaseConnection.Parameterizer.PARSER_ID, parser);
params.addParameter(AbstractDatabaseConnection.Parameterizer.FILTERS_ID, sparseFilter);
Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, params);
db.initialize();
params = new ListParameterization();
params.addParameter(SOD.Parameterizer.KNN_ID, 25);
params.addParameter(SharedNearestNeighborPreprocessor.Factory.NUMBER_OF_NEIGHBORS_ID, 10);
SOD<DoubleVector> sodAlg = ClassGenericsUtil.parameterizeOrAbort(SOD.class, params);
OutlierResult result = sodAlg.run(db);
Но у меня есть это исключение во время выполнения:
Exception in thread "main" de.lmu.ifi.dbs.elki.data.type.NoSupportedDataTypeException: No data type found satisfying: NumberVector,field
Available types: DBID DoubleVector,field,mindim=7606,maxdim=12968
at de.lmu.ifi.dbs.elki.database.AbstractDatabase.getRelation(AbstractDatabase.java:154)
at de.lmu.ifi.dbs.elki.algorithm.AbstractAlgorithm.run(AbstractAlgorithm.java:80)
Это правильный способ использовать SparseNumberVectorLabelParser и SparseVectorFieldFilter в коде Java?
1 ответ
ArrayAdapterDatabaseConnection
предназначен для плотных данных. Для разреженных данных не имеет большого смысла сначала кодировать их в плотный массив, а затем перекодировать их в разреженные векторы. Рассмотрите возможность считывания данных в виде разреженных векторов напрямую, чтобы избежать накладных расходов.
Однако ошибка, которую вы видите, имеет другую причину:
SOD указывается для векторного поля фиксированной размерности, но разреженные векторы дают отношение, которое имеет переменную размерность. Таким образом, он не находит запрошенный тип данных (следовательно, NoSupportedDataTypeException
).
Вы можете заставить данные иметь фиксированную размерность, используя SparseVectorFieldFilter
,
Но я не уверен, является ли SOD подходящим алгоритмом для разреженных данных. Хотя это должно работать тогда, время выполнения и производительность могут быть плохими; потому что алгоритм не работает с данными, которые удовлетворяют предположениям, для которых он был разработан. Разреженные данные обычно лучше всего обрабатывать с помощью алгоритмов, которые используют и обрабатывают разреженность данных. (Как и вы, вы также можете вычислить общих ближайших соседей, используя евклидово расстояние, которое может не сработать для разреженных данных. Если SNN плох, SOD тоже не будет работать хорошо)