Я реализовал систему взвешивания TF-IDF на наборе из 42000 изображений, каждая из которых состояла из 784 пикселей. Это в основном матрица 42000 на 784.
В первом методе я попытался использовать явные циклы и занял более 2 часов.
def tfidf(color,img_pix,img_total):
if img_pix==0:
return 0
else:
return color * np.log(img_total/img_pix)
...
result = np.array([])
for img_vec in data_matrix:
double_vec = zip(img_vec,img_pix_vec)
result_row = np.array([tfidf(x[0],x[1],img_total) for x in double_vec])
try:
result = np.vstack((result,result_row))
# first row will throw a ValueError since vstack accepts rows of same len
except ValueError:
result = result_row
Второй метод: я попытался использовать матрицы numpy и занял менее 5 минут. Обратите внимание, что data_matrix, img_pix_mat - это матрицы 42000 на 784, а img_total - скаляр.
result = data_matrix * np.log(np.divide(img_total,img_pix_mat))
Я надеялся, что кто-то сможет объяснить огромную разницу в скорости.
Авторы следующей статьи, озаглавленной "Массив NumPy: структура для численного численного вычисления" (http://arxiv.org/pdf/1102.1523.pdf), указываем в верхней части страницы 4, что они наблюдают 500-кратное увеличение скорости за счет векторизованного вычисления. Я предполагаю, что увеличение скорости, которое я вижу, связано с этим. Тем не менее, я хотел бы сделать еще один шаг и спросить, почему числовые векторизованные вычисления намного быстрее, чем стандартные петли python?
Кроме того, возможно, вы, ребята, знаете другие причины, почему первый метод медленный. Нужно ли пытаться/кроме структур иметь большие накладные расходы? Или, возможно, формирование нового np.array для каждого цикла занимает много времени?
Спасибо.