Как сделать классификацию текста с Accord.Net?

Я пытаюсь использовать Accord.net для классификации текстов. Но я не могу найти способ представления разреженных векторов и матриц. Например, у нас есть много текстов, и после токенизации с помощью ngrams и хеширования каждый текст представлен в виде индекса функции (данного featureHasher) с весом (tf). И невозможно загрузить все данные в виде неразреженной матрицы в память. Есть ли способ выполнить инкрементную обработку или представить разреженную матрицу или уменьшить количество функций с разреженными данными?


person Hodza    schedule 15.06.2015    source источник


Ответы (1)


К сожалению, в настоящее время не все модели и методы поддерживают разреженные матрицы. Однако, если вы пытаетесь выполнить категоризацию текста, вы можете сделать это с помощью машины опорных векторов с разреженным ядром.

Разреженные ядра можно найти в пространстве имен Accord.Statistics.Kernels.Sparse, например, в SparseLinear и SparseGaussian. Эти ядра ожидают, что данные будут предоставлены в формате LibSVM Sparse. Спецификацию этого формата можно найти в часто задаваемых вопросах по LibSVM на вопрос Почему иногда не все атрибуты данных появляются в файлы обучения/модели?.

По сути, в этом формате вектор признаков, который будет представлен как

1 0 2 0

представлен как

1:1 3:2

или, другими словами, в виде списка пар position:value, где position начинается с 1.

Вот пример того, как использовать SVM с ядром SparseLinear, используя разреженный линейный формат LibSVM:

// Example AND problem
double[][] inputs =
{
    new double[] {          }, // 0 and 0: 0 (label -1)
    new double[] {      2,1 }, // 0 and 1: 0 (label -1)
    new double[] { 1,1      }, // 1 and 0: 0 (label -1)
    new double[] { 1,1, 2,1 }  // 1 and 1: 1 (label +1)
};

// Dichotomy SVM outputs should be given as [-1;+1]
int[] labels =
{
    // 0,  0,  0, 1
        -1, -1, -1, 1
};

// Create a Support Vector Machine for the given inputs
// (sparse machines should use 0 as the number of inputs)
var machine = new KernelSupportVectorMachine(new SparseLinear(), inputs: 0); 

// Instantiate a new learning algorithm for SVMs
var smo = new SequentialMinimalOptimization(machine, inputs, labels);

// Set up the learning algorithm
smo.Complexity = 100000.0;

// Run
double error = smo.Run(); // should be zero

double[] predicted = inputs.Apply(machine.Compute).Sign();

// Outputs should be -1, -1, -1, +1
Assert.AreEqual(-1, predicted[0]);
Assert.AreEqual(-1, predicted[1]);
Assert.AreEqual(-1, predicted[2]);
Assert.AreEqual(+1, predicted[3]);
person Cesar    schedule 18.06.2015
comment
С разреженными векторами вам все еще нужны входы и выходы в памяти во время обучения или вы можете тренироваться партиями? - person Telavian; 26.08.2015
comment
Вы все еще нуждаетесь в них в памяти. К сожалению, с SVM очень сложно обучать в пакетном режиме. Однако если вы используете 64-разрядную версию Windows, вы можете выделить массивы, общий размер которых превышает 2 ГБ, с помощью msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx и пусть ОС позаботится об этом и выходит по мере необходимости - person Cesar; 26.08.2015
comment
Это работает в зависимости от размера матрицы. Однако разреженная матрица типа double размерами 50 000x500 000, что вполне возможно, потребует около 1500 ГБ места. Это также, вероятно, заняло бы целую вечность, если бы постоянно использовалось пространство подкачки. - person Telavian; 13.09.2015
comment
В этом случае можно изменить стратегию: вместо использования SVM вы можете использовать стохастический градиентный спуск для изучения линейной модели в пакетах. К сожалению, сгенерированная модель не будет иметь таких хороших гарантий оптимальности, как SVM, но с большими наборами данных это может быть единственным приемлемым вариантом. - person Cesar; 13.09.2015