Error de dominio matemático al usar PCA

Estoy usando el paquete scikit-learn de python para implementar PCA. Estoy obteniendo matemáticas

domain error : C:\Users\Akshenndra\Anaconda2\lib\site-packages\sklearn\decomposition\pca.pyc in _assess_dimension_(spectrum, rank, n_samples, n_features) 78 for j in range(i + 1, len(spectrum)): 79 pa += log((spectrum[i] - spectrum[j]) * ---> 80 (1. / spectrum_[j] - 1. / spectrum_[i])) + log(n_samples) 81 82 ll = pu + pl + pv + pp - pa / 2. - rank * log(n_samples) / 2. ValueError: math domain error 

Ya sé que el error en el dominio matemático se produce cuando tomamos el logaritmo de un número negativo, pero no entiendo aquí, ¿cómo puede haber un número negativo dentro del logaritmo? porque este código funciona bien para otros conjuntos de datos. tal vez esto esté relacionado con lo que está escrito en el sitio web de sci-kitlearn: “Esta implementación utiliza la implementación scipy.linalg de la descomposición del valor singular. Solo funciona para matrices densas y no es escalable a datos de grandes dimensiones”. número de valores 0)

Creo que deberías agregar 1 en su lugar, como la página de descripción numpy log1p . Dado que log (p + 1) = 0 cuando p = 0 (while log (e-99) = -99), y como la cita en el enlace

Para entradas de valor real, log1p es exacto también para x tan pequeño que 1 + x == 1 en precisión de punto flotante

El código se puede modificar de la siguiente manera para hacer más razonable lo que intenta resolver:

 for i in range(rank): for j in range(i + 1, len(spectrum)): pa += log((spectrum[i] - spectrum[j]) * (1. / spectrum_[j] - 1. / spectrum_[i]) + 1) + log(n_samples + 1) ll = pu + pl + pv + pp - pa / 2. - rank * log(n_samples + 1) / 2 

No sé si tengo razón o no, pero realmente encuentro la manera de resolverlo.

Acabo de imprimir alguna información de error (el valor de spectrum_ [i] y spectrum_ [j]), y encuentro:

A veces, son iguales !!!

(Quizás no sean los mismos pero son demasiado cercanos, supongo)

entonces aqui

 pa += log((spectrum[i] - spectrum[j]) * (1. / spectrum_[j] - 1. / spectrum_[i])) + log(n_samples) 

se informará de error al calcular el registro (0).

Mi manera de resolverlo es agregar un número muy pequeño 1e-99 a 0, para que se convierta en log (0 + 1e-99)

así que puedes cambiarlo a

  pa += log((spectrum[i] - spectrum[j]) * (1. / spectrum_[j] - 1. / spectrum_[i]) + 1e-99) + log(n_samples)