[Frontmatter] (пропустите это, если вы просто хотите задать вопрос) :
В настоящее время я рассматриваю использование Взаимной информации Шеннона-Уивера и нормализованной избыточности для измерения степени маскирования информации между пакетами дискретных и непрерывных значений признаков, упорядоченных по функциям. Используя этот метод, моей целью является создание алгоритма, который будет очень похож на ID3 , но вместо использования энтропии Шеннона алгоритм будет искать (в качестве ограничения цикла), чтобы максимизировать или свести к минимуму общую информацию между отдельным объектом и коллекцией объектов на основе полного пространства входных объектов, добавляя новые функции в последнюю коллекцию, если (и только если) они увеличивают или уменьшают взаимную информацию соответственно. Это, по сути, перемещает алгоритм принятия решения ID3 в парное пространство, объединяя ансамблевый подход со всеми ожидаемыми временными и пространственными сложностями обоих методов.
[/ Frontmatter]
К вопросу: я пытаюсь получить непрерывный интегратор , работающий в Python с использованием SciPy . Поскольку я работаю со сравнениями дискретных и непрерывных переменных, моя текущая стратегия для каждого сравнения для пары признак-объект выглядит следующим образом:
Дискретная функция по сравнению с дискретной: используйте дискретную форму взаимной информации. Это приводит к двойному суммированию вероятностей, которое мой код обрабатывает без проблем.
Все остальные случаи (дискретный по сравнению с непрерывным, обратный и непрерывный по сравнению с непрерывным): используйте непрерывную форму, используя гауссовскую оценку , чтобы сгладить функции плотности вероятности .
Для меня возможно выполнить некоторую дискретизацию для последних случаев, но поскольку мои наборы входных данных не являются линейными по своей природе, это потенциально излишне сложно.
Вот характерный код:
import math
import numpy
import scipy
from scipy.stats import gaussian_kde
from scipy.integrate import dblquad
# Constants
MIN_DOUBLE = 4.9406564584124654e-324
# The minimum size of a Float64; used here to prevent the
# logarithmic function from hitting its undefined region
# at its asymptote of 0.
INF = float('inf') # The floating-point representation for "infinity"
# x and y are previously defined as collections of
# floating point values with the same length
# Kernel estimation
gkde_x = gaussian_kde(x)
gkde_y = gaussian_kde(y)
if len(binned_x) != len(binned_y) and len(binned_x) != len(x):
x.append(x[0])
y.append(y[0])
gkde_xy = gaussian_kde([x,y])
mutual_info = lambda a,b: gkde_xy([a,b]) * \
math.log((gkde_xy([a,b]) / (gkde_x(a) * gkde_y(b))) + MIN_DOUBLE)
# Compute MI(X,Y)
(minfo_xy, err_xy) = \
dblquad(mutual_info, -INF, INF, lambda a: 0, lambda a: INF)
print 'minfo_xy = ', minfo_xy
Обратите внимание, что пересчет ровно одной точки сделан специально для предотвращения сингулярности в классе gaussian_kde SciPy. Когда размеры x и y взаимно приближаются к бесконечности, этот эффект становится незначительным.
* *
тысяча сорок-девять
Моя текущая проблема заключается в попытке получить множественную интеграцию , работающую против оценки плотности ядра Гаусса в SciPy. Я пытался использовать SciPy dblquad для выполнения интеграции, но в последнем случае я получаю поразительные выпады следующих сообщений.
Когда я установил numpy.seterr ( all='ignore' )
:
Внимание! Обнаружено возникновение ошибки округления, которая предотвращает
Запрашиваемая терпимость от достижения. Ошибка может быть
занижены.
И когда я установил его на 'call'
, используя обработчик ошибок:
Ошибка с плавающей точкой (недостаточное значение), с флагом 4
Ошибка с плавающей запятой (недопустимое значение), с флагом 8
Довольно легко понять, что происходит, верно? Ну, почти: IEEE 754-2008 и SciPy только говорят мне, что здесь происходит, а не почему или как обойти это .
Результат: minfo_xy
обычно разрешается до nan
; его выборка недостаточна для предотвращения потери или недействительности информации при выполнении математических вычислений Float64.
Существует ли общий способ решения этой проблемы при использовании SciPy?
Еще лучше: Если существует надежная постоянная реализация непрерывной взаимной информации для Python с интерфейсом, который принимает две коллекции значений с плавающей запятой или объединенную коллекцию пар, это решило бы эту полную проблему. Пожалуйста, свяжите его, если вы знаете, что существует.
Заранее спасибо.
Редактировать: это решает проблему распространения nan
в приведенном выше примере:
mutual_info = lambda a,b: gkde_xy([a,b]) * \
math.log((gkde_xy([a,b]) / ((gkde_x(a) * gkde_y(b)) + MIN_DOUBLE)) \
+ MIN_DOUBLE)
Однако остается вопрос об исправлении округления, равно как и запрос о более надежной реализации.Любая помощь в любой области будет принята с благодарностью.