Ответ 1
В частности, ваша трассировка:
rvs использует обратный cdf, ppf для создания случайных чисел. Поскольку вы не указываете ppf, он вычисляется с помощью алгоритма поиска корней, brentq
. brentq
использует нижнюю и верхнюю границы на том, где он должен искать значение at, при этом функция равна нулю (найдите x, так что cdf (x) = q, q является квантильным).
По умолчанию для пределов, xa
и xb
, слишком малы в вашем примере. Следующие работы для меня с scipy 0.9.0, xa
, xb
могут быть установлены при создании экземпляра функции
def getDistribution(data):
kernel = stats.gaussian_kde(data)
class rv(stats.rv_continuous):
def _cdf(self, x):
return kernel.integrate_box_1d(-numpy.Inf, x)
return rv(name='kdedist', xa=-200, xb=200)
В настоящее время существует запрос на pull для scipy, чтобы улучшить это, поэтому в следующей версии xa
и xb
будут автоматически расширены, чтобы избежать исключения f(a) and f(b) must have different signs
.
В этом документе мало документации, проще всего следовать некоторым примерам (и спросить в списке рассылки).
edit: дополнение
pdf. Поскольку у вас есть функция плотности, также заданная gaussian_kde, я бы добавил метод _pdf
, который сделает некоторые вычисления более эффективными.
edit2: дополнение
rvs: если вы заинтересованы в генерации случайных чисел, gaussian_kde имеет метод resample. Случайные образцы могут быть сгенерированы путем выборки из данных и добавления гауссовского шума. Таким образом, это будет быстрее, чем общие rvs, используя метод ppf. Я бы написал метод._rvs, который просто вызывает метод resample gaussian_kde.
precomputing ppf: я не знаю какого-либо общего способа прекомполяции ppf. Тем не менее, как я думал о том, чтобы делать это (но до сих пор не пробовал), нужно прекомпретировать ppf во многих точках, а затем использовать линейную интерполяцию для аппроксимации функции ppf.
edit3: about _rvs
, чтобы ответить на вопрос Шривацана в комментарии
_rvs
- это специальный метод распределения, который вызывается публичным методом rvs
. rvs
- это общий метод, который выполняет некоторую проверку аргументов, добавляет местоположение и масштаб и устанавливает атрибут self._size
, который является размером запрашиваемого массива случайных величин, а затем вызывает метод, специфичный для распределения ._rvs
, или его общий коллега. Дополнительные аргументы в ._rvs
являются параметрами формы, но поскольку в этом случае их нет, *x
и **y
являются избыточными и неиспользуемыми.
Я не знаю, насколько хорошо size
или форма метода .rvs
работает в многомерном случае. Эти дистрибутивы предназначены для одномерных распределений и могут не полностью работать для многомерного случая или могут потребоваться некоторые изменения.