Как рассчитать значение прироста информации, чтобы уменьшить ошибки аппроксимации с плавающей точкой?

У меня есть набор данных, содержащий некоторые функции, которые принадлежат двум меткам классов, обозначенным 1 а также 2. Этот набор данных обрабатывается для построения дерева решений: во время построения дерева мне нужно вычислить информационный прирост, чтобы найти лучшее разбиение набора данных.

Пусть будет N1 функции, связанные с этикеткой 1, а также N2 функции, связанные с этикеткой 2, тогда энтропия можно рассчитать по следующей формуле:

Entropy = - (N1/N)*log2(N1/N) - (N2/N)*log2(N2/N), где N = N1 + N2

Мне нужно рассчитать три значения энтропии, чтобы получить прирост информации:

  • entropyBefore, то есть энтропия перед разделением текущего набора данных;
  • entropyLeftэто энтропия левого расщепления после разбиения;
  • entropyRightэто энтропия правого разбиения после разбиения.

Итак, прирост информации равен entropyBefore - (S1/N)*entropyLeft - (S2/N)*entropyRight, где S1 количество функций класса 1 принадлежность к расколу 1, и S2 количество функций класса 2 принадлежность к расколу 2.

Как рассчитать значение прироста информации, чтобы уменьшить ошибки аппроксимации с плавающей точкой? Когда я применяю приведенные выше формулы в тех случаях, когда прирост информации должен быть равен нулю, однако вычисленное значение равно очень малому отрицательному значению.

ОБНОВИТЬ (образец кода)

double N = static_cast<double>(this->rows());   // rows count of the dataset

double entropyBefore = this->entropy();   // current entropy (before performing the split)

bool firstCheck = true;
double bestSplitIg;

for each possible split
{
// ...

pair<Dataset,Dataset> splitPair = split(...,...);
double S1 = splitPair.first.rows();
double S2 = splitPair.second.rows();

double entropyLeft = splitPair.first.entropy();
double entropyRight = splitPair.second.entropy();

double splitIg = entropyBefore - (S1/N*entropyLeft + S2/N*entropyRight);
if (firstCheck || splitIg > bestSplitIg)
{
bestSplitIg = splitIg;
// ...

firstCheck = false;
}
}

2

Решение

Если вы используете только энтропию, чтобы определить, какая альтернатива лучше, и вам нужен только результат сравнения двух энтропий, а не их фактические значения, тогда вы можете отменить некоторые вычисления.

У вас есть эта функция: Энтропия (N1, N2, N) -> — N1 / N * log2 (N1 / N) — N2 / N * log2 (N2 / N).

Предположим, что N является константой на протяжении вашей задачи, умножим выражение на N:

  • N1 * log2 (N 1 / N) -N2 * log2 (N 2 / N)

Затем отделите «/ N» от логарифмов:

  • N1 * (log2 (N1) -log2 (N)) — N2 * (log2 (N2) -log2 (N))

и расширить:

  • N1 * log2 (N1) — N2 * log2 (N2) — (N1 + N2) * log2 (N)

и упростить:

  • N1 * log2 (N1) — N2 * log2 (N2) — N * log2 (N)

Ясно, что N * log2 (N) является константой и не влияет на то, является ли одна энтропия больше другой, поэтому мы можем отбросить ее.

Кроме того, умножьте на ln (2), что также не меняет, является ли одна энтропия больше другой. Это приводит к изменению функций log2 на ln-функции, и математическая библиотека может немного более точно вычислить ln (есть причина, по которой это «естественный» логарифм):

E (N1, N2, N) -> — N1 * ln (N1) — N2 * ln (N2)

Эта функция имеет меньше операций, поэтому она может быть вычислена более точно, чем функция энтропии, и обладает свойством (при точном расчете) E (N1, N2, N) < E (M1, M2, N), если энтропия (N1, N2, N) < Энтропия (М1, М2, Н).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]