clarkson_woodruff_transform#
- scipy.linalg.clarkson_woodruff_transform(input_matrix, sketch_size, rng=None, *, seed=None)[источник]#
Применяет преобразование Кларксона-Вудраффа/скетч к входной матрице.
Для заданной input_matrix
Aразмера(n, d), вычислить матрицуA'размера (sketch_size, d), так что\[\|Ax\| \approx \|A'x\|\]с высокой вероятностью через преобразование Кларксона-Вудраффа, также известное как матрица CountSketch.
- Параметры:
- input_matrixarray_like, shape (…, n, d)
Входная матрица.
- sketch_sizeint
Количество строк для эскиза.
- rng{None, int,
numpy.random.Generator, опционально Если rng передается по ключевому слову, типы, отличные от
numpy.random.Generatorпередаются вnumpy.random.default_rngдля создания экземпляраGenerator. Если rng уже являетсяGeneratorэкземпляр, то предоставленный экземпляр используется. Укажите rng для повторяемого поведения функции.Если этот аргумент передаётся по позиции или seed передается по ключевому слову, устаревшее поведение для аргумента seed применяется:
Если seed равно None (или
numpy.random),numpy.random.RandomStateиспользуется синглтон.Если seed является int, новый
RandomStateиспользуется экземпляр, инициализированный с seed.Если seed уже является
GeneratorилиRandomStateэкземпляр, тогда этот экземпляр используется.
Изменено в версии 1.15.0: В рамках SPEC-007 переход от использования
numpy.random.RandomStatetonumpy.random.Generator, этот ключевое слово было изменено с seed to rng. В переходный период оба ключевых слова будут продолжать работать, хотя только одно может быть указано за раз. После переходного периода вызовы функций, использующие seed ключевое слово будет выдавать предупреждения. Поведение обоих seed и rng описаны выше, но только rng ключевое слово должно использоваться в новом коде.
- Возвращает:
- A’array_like
Эскиз входной матрицы
A, размера(sketch_size, d).
Примечания
Чтобы сделать утверждение
\[\|Ax\| \approx \|A'x\|\]точнее, обратите внимание на следующий результат, адаптированный из доказательства Теоремы 14 [2] через неравенство Маркова. Если у нас есть размер эскиза
sketch_size=kчто составляет не менее\[k \geq \frac{2}{\epsilon^2\delta}\]Тогда для любого фиксированного вектора
x,\[\|Ax\| = (1\pm\epsilon)\|A'x\|\]с вероятностью не менее одного минус дельта.
Эта реализация использует преимущества разреженности: вычисление эскиза занимает время, пропорциональное
A.nnz. ДанныеAкоторый находится вscipy.sparse.csc_matrixформат обеспечивает самое быстрое время вычисления для разреженного ввода.>>> import numpy as np >>> from scipy import linalg >>> from scipy import sparse >>> rng = np.random.default_rng() >>> n_rows, n_columns, density, sketch_n_rows = 15000, 100, 0.01, 200 >>> A = sparse.rand(n_rows, n_columns, density=density, format='csc') >>> B = sparse.rand(n_rows, n_columns, density=density, format='csr') >>> C = sparse.rand(n_rows, n_columns, density=density, format='coo') >>> D = rng.standard_normal((n_rows, n_columns)) >>> SA = linalg.clarkson_woodruff_transform(A, sketch_n_rows) # fastest >>> SB = linalg.clarkson_woodruff_transform(B, sketch_n_rows) # fast >>> SC = linalg.clarkson_woodruff_transform(C, sketch_n_rows) # slower >>> SD = linalg.clarkson_woodruff_transform(D, sketch_n_rows) # slowest
Тем не менее, этот метод хорошо работает на плотных входных данных, просто медленнее в относительном масштабе.
Ссылки
[1]Kenneth L. Clarkson and David P. Woodruff. Low rank approximation and regression in input sparsity time. In STOC, 2013.
[2]David P. Woodruff. Sketching as a tool for numerical linear algebra. In Foundations and Trends in Theoretical Computer Science, 2014.
Примеры
Создать большую плотную матрицу
Aдля примера:>>> import numpy as np >>> from scipy import linalg >>> n_rows, n_columns = 15000, 100 >>> rng = np.random.default_rng() >>> A = rng.standard_normal((n_rows, n_columns))
Примените преобразование для создания новой матрицы с 200 строками:
>>> sketch_n_rows = 200 >>> sketch = linalg.clarkson_woodruff_transform(A, sketch_n_rows, seed=rng) >>> sketch.shape (200, 100)
Теперь с высокой вероятностью истинная норма близка к набросанной норме по абсолютному значению.
>>> linalg.norm(A) 1224.2812927123198 >>> linalg.norm(sketch) 1226.518328407333
Аналогично, применение нашего эскиза сохраняет решение линейной регрессии для \(\min \|Ax - b\|\).
>>> b = rng.standard_normal(n_rows) >>> x = linalg.lstsq(A, b)[0] >>> Ab = np.hstack((A, b.reshape(-1, 1))) >>> SAb = linalg.clarkson_woodruff_transform(Ab, sketch_n_rows, seed=rng) >>> SA, Sb = SAb[:, :-1], SAb[:, -1] >>> x_sketched = linalg.lstsq(SA, Sb)[0]
Как и в примере с матричной нормой,
linalg.norm(A @ x - b)близко кlinalg.norm(A @ x_sketched - b)с высокой вероятностью.>>> linalg.norm(A @ x - b) 122.83242365433877 >>> linalg.norm(A @ x_sketched - b) 166.58473879945151