Это почти наверняка поправка на числовую ошибку. Чтобы понять, почему это может быть необходимо, посмотрите, что происходит, когда вы берете svd
матрицы 2x2 ранга один. Мы можем создать матрицу ранга один, взяв внешнее произведение вектора следующим образом:
>>> a = numpy.arange(2) + 1
>>> A = a[:, None] * a[None, :]
>>> A
array([[1, 2],
[2, 4]])
Несмотря на то, что это матрица 2x2, она имеет только один линейно независимый столбец, поэтому ее ранг один вместо двух. Поэтому следует ожидать, что когда мы передадим его в svd
, одно из сингулярных значений будет равно нулю. Но посмотрите, что происходит:
>>> U, s, V = numpy.linalg.svd(A)
>>> s
array([5.00000000e+00, 1.98602732e-16])
На самом деле мы получаем единственное значение, которое не совсем ноль. Этот результат неизбежен во многих случаях, учитывая, что мы работаем с числами с плавающей запятой конечной точности. Таким образом, хотя проблема, которую вы определили, является реальной, мы не сможем на практике определить разницу между матрицей, которая действительно имеет очень маленькое сингулярное значение, и матрицей, которая должна иметь нулевое сингулярное значение, но не имеет. Установка небольших значений на ноль - самый безопасный практический способ решения этой проблемы.