Векторизация в Python

Опубликовано: 30 Ноября, 2021

Мы знаем, что большая часть приложения имеет дело с большим количеством наборов данных. Следовательно, неоптимальная с вычислительной точки зрения функция может стать огромным узким местом в вашем алгоритме и привести к модели, выполнение которой требует времени. Чтобы убедиться, что код эффективен с вычислительной точки зрения, мы будем использовать векторизацию.

Сложность по времени при выполнении любого алгоритма очень важна при принятии решения о том, является ли приложение надежным или нет. Когда дело доходит до применения вывода в реальном времени, очень важно запустить большой алгоритм в максимально оптимальное время. Для этого в Python есть несколько стандартных математических функций для быстрых операций с целыми массивами данных без необходимости писать циклы. Одна из таких библиотек, которая содержит такую функцию, - numpy . Давайте посмотрим, как мы можем использовать эту стандартную функцию в случае векторизации.

Что такое векторизация?
Векторизация используется для ускорения кода Python без использования цикла. Использование такой функции может помочь эффективно минимизировать время выполнения кода. Над вектором выполняются различные операции, такие как скалярное произведение векторов, которое также известно как скалярное произведение, поскольку оно производит единичный вывод, внешние произведения, которые приводят к квадратной матрице размерности, равной длине X длины векторов, поэлементное умножение, которое производит произведение элемент тех же индексов и размерность матрицы остаются неизменными.

Мы увидим, что классические методы занимают больше времени, чем использование некоторых стандартных функций, посчитав время их обработки.

outer(a, b): Compute the outer product of two vectors.
multiply(a, b): Matrix product of two arrays.
dot(a, b): Dot product of two arrays.
zeros((n, m)): Return a matrix of given shape and type, filled with zeros.
process_time(): Return the value (in fractional seconds) of the sum of the system and user CPU time of the current process. It does not include time elapsed during sleep.

Скалярное произведение:
Точечное произведение - это алгебраическая операция, при которой два вектора равной длины умножаются так, что получается одно число. Точечный продукт часто называют внутренним продуктом . Этот продукт дает скалярное число. Давайте рассмотрим две матрицы a и b одинаковой длины, скалярное произведение выполняется путем транспонирования первой матрицы, а затем выполняется математическое матричное умножение a ' (транспонирование a) и b, как показано на рисунке ниже.

Графическое изображение скалярного продукта -

Ниже представлен код Python:

# Dot product
time import
import numpy
import array
# 8 bytes size int
a = array.array( 'q' )
for i in range ( 100000 ):
a.append(i);
b = array.array( 'q' )
for i in range ( 100000 , 200000 ):
b.append(i)
# classic dot product of vectors implementation
tic = time.process_time()
dot = 0.0 ;
for i in range ( len (a)):
dot + = a[i] * b[i]
toc = time.process_time()
print ( "dot_product = " + str (dot));
print ( "Computation time = " + str ( 1000 * (toc - tic )) + "ms" )
n_tic = time.process_time()
n_dot_product = numpy.dot(a, b)
n_toc = time.process_time()
print ( " n_dot_product = " + str (n_dot_product))
print ( "Computation time = " + str ( 1000 * (n_toc - n_tic )) + "ms" )

Выход:

dot_product = 833323333350000.0
Время вычисления = 35,59449199999999 мс

n_dot_product = 833323333350000
Время вычисления = 0,1559900000000225 мс


Внешний продукт:
Тензорное произведение двух координатных векторов называется Внешним произведением . Рассмотрим два вектора a и b с размерностями nx 1 и mx 1 тогда внешнее произведение вектора дает прямоугольную матрицу nxm . Если два вектора имеют одинаковую размерность, то результирующая матрица будет квадратной матрицей, как показано на рисунке.

Графическое изображение внешнего продукта -

Ниже представлен код Python:

# Outer product
time import
import numpy
import array
a = array.array( 'i' )
for i in range ( 200 ):
a.append(i);
b = array.array( 'i' )
for i in range ( 200 , 400 ):
b.append(i)
# classic outer product of vectors implementation
tic = time.process_time()
outer_product = numpy.zeros(( 200 , 200 ))
for i in range ( len (a)):
for j in range ( len (b)):
outer_product[i][j] = a[i] * b[j]
toc = time.process_time()
print ( "outer_product = " + str (outer_product));
print ( "Computation time = " + str ( 1000 * (toc - tic )) + "ms" )
n_tic = time.process_time()
outer_product = numpy.outer(a, b)
n_toc = time.process_time()
print ( "outer_product = " + str (outer_product));
print ( " Computation time = " + str ( 1000 * (n_toc - n_tic )) + "ms" )

Выход:

external_product = [[0. 0. 0. ..., 0. 0. 0.]
 [200. 201. 202. ..., 397. 398. 399.]
 [400. 402. 404. ..., 794. 796. 798.]
 ..., 
 [39400. 39597. 39794. ..., 78209. 78406. 78603.]
 [39600. 39798. 39996. ..., 78606. 78804. 79002.]
 [39800. 39999. 40198. ..., 79003. 79202. 79401.]]

Время вычисления = 39,821617 мс

external_product = [[0 0 0 ..., 0 0 0]
 [200 201 202 ..., 397 398 399]
 [400 402 404 ..., 794 796 798]
 ..., 
 [39400 39597 39794 ..., 78209 78406 78603]
 [39600 39798 39996 ..., 78606 78804 79002]
 [39800 39999 40198 ..., 79003 79202 79401]]

Время вычисления = 0,2809480000000031 мс.


Элементный продукт:
Поэлементное умножение двух матриц - это алгебраическая операция, в которой каждый элемент первой матрицы умножается на соответствующий ему элемент в более поздней матрице. Размеры матриц должны быть одинаковыми.
Рассмотрим две матрицы a и b , индекс элемента в a равен i и j, затем a (i, j) умножается на b (i, j) соответственно, как показано на рисунке ниже.

Иллюстрированное изображение продукта, основанного на элементах -

Ниже представлен код Python:

# Element-wise multiplication
time import
import numpy
import array
a = array.array( 'i' )
for i in range ( 50000 ):
a.append(i);
b = array.array( 'i' )
for i in range ( 50000 , 100000 ):
b.append(i)
# classic element wise product of vectors implementation
vector = numpy.zeros(( 50000 ))
tic = time.process_time()
for i in range ( len (a)):
vector[i] = a[i] * b[i]
toc = time.process_time()
print ( "Element wise Product = " + str (vector));
print ( " Computation time = " + str ( 1000 * (toc - tic )) + "ms" )
n_tic = time.process_time()
vector = numpy.multiply(a, b)
n_toc = time.process_time()
print ( "Element wise Product = " + str (vector));
print ( " Computation time = " + str ( 1000 * (n_toc - n_tic )) + "ms" )

Выход:

Поэлементный продукт = [0.00000000e + 00 5.00010000e + 04 1.00004000e + 05 ..., 4.99955001e + 09
   4.99970000e + 09 4.99985000e + 09]

Время вычисления = 23,516678000000013 мс

Поэлементный продукт = [0 50001 100004 ..., 704582713 704732708 704882705]
Время вычисления = 0,2250640000000248 мс.

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.