I have a matrix of ~4.5 million vector [4.5mil, 300] and I want to calculate the distance between a vector of length 300 against all the entries in the matrix.
I got some great performance time using the answers from the following post: Efficient numpy cosine distance calculation.
from scipy import spatial
def cos_matrix_multiplication(vector, matrix):
v = vector.reshape(1, -1)
scores=spatial.distance.cdist(matrix_1, v, 'cosine').reshape(-1)
return scores
Here, vector
is a NumPy array [300,1] and matrix_1
is a NumPy matrix [4.5mil, 300]
Using this I can calculate scores for the entire matrix (4.5 mil records) in about 19secs. I have been trying to optimize it even further but don't seem to make any progress.
I want to know if it is feasible to convert this code into a cython code or use Process/Thread pool to speed up even more.
I split my matrix into smaller chunks (500K each) and used ThreadPoolExecutor
as follows:
matrix_list=[mat_small1,mat_small2,....,mat_small9]
import concurrent.futures
def cos_thread():
neighbors=[]
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
future_to_list = {executor.submit(cos_matrix_multiplication,vec,mat_col): mat_col for mat_col in matrix_list}
for future in concurrent.futures.as_completed(future_to_list):
data = future.result()
neighbors.extend(data)
return neighbors
I can currently compute the entire ~4.5 million cosines
in ~5 seconds.
cython
tutorials. And study the internals ofcdist
You can't just throw your code atcython
. \$\endgroup\$