ValueError: Input contains NaN, infinity or a value too large for dtype('float32')

Помогите разобраться. Что-то совсем туплю и не знаю в чем причина...

Выполняю следующую задачу: Задача поиска схожих по смыслу предложений для StackOverflow.

(архив для данных https://drive.google.com/file/d/1QqT4D0EoqJTy7v9VrNCYD-m964XZFR7_/edit)

!unzip stackoverflow_similar_questions.zip

def read_corpus(filename):
    data = []
    for line in open(filename, encoding='utf-8'):
        data.append(line.strip().split('\t'))
    return data

validation_data = read_corpus('./data/validation.tsv')

!wget https://zenodo.org/record/1199620/files/SO_vectors_200.bin?download=1

from gensim.models.keyedvectors import KeyedVectors
wv_embeddings = KeyedVectors.load_word2vec_format("SO_vectors_200.bin?download=1", binary=True)

def question_to_vec(question, embeddings, tokenizer, dim=200):
    """
        question: строка
        embeddings: наше векторное представление
        dim: размер любого вектора в нашем представлении
        
        return: векторное представление для вопроса
    """      
    
    sentence_embedding = np.zeros((dim,), dtype=np.float32)
    
    if question == "":
        return sentence_embedding
    
    count = 0
    words = tokenizer.tokenize(question)    

    for word in words:
        if word in embeddings.wv.vocab:
          sentence_embedding += embeddings.wv[word]
          count +=1
    
    if len(words) > 1:
        sentence_embedding = sentence_embedding / count
    
    return sentence_embedding

from sklearn.metrics.pairwise import cosine_similarity
from copy import deepcopy

def rank_candidates(question, candidates, embeddings, tokenizer, dim=200):
    """
        question: строка
        candidates: массив строк(кандидатов) [a, b, c]
        result: пары (начальная позиция, кандидат) [(2, c), (0, a), (1, b)]
    """
    question_vec = [question_to_vec(question, embeddings, tokenizer, dim)]
    cand_vec = [question_to_vec(x, embeddings, tokenizer, dim) for x in candidates]
    ranks = np.argsort(cosine_similarity(question_vec, cand_vec).ravel())[::-1]

    result = [(x, candidates[x]) for x in ranks]
    
    return result


from tqdm.notebook import tqdm
wv_ranking = []
max_validation_examples = 1
for i, line in enumerate(tqdm(validation_data)):
    if i == max_validation_examples:
        break
    q, *ex = line
    ranks = rank_candidates(q, ex, wv_embeddings, tokenizer)
    wv_ranking.append([r[0] for r in ranks].index('0') + 1)

И получаю ошибку:

ValueError                                Traceback (most recent call last)
<ipython-input-79-29e03c28958a> in <module>()
      5         break
      6     q, *ex = line
----> 7     ranks = rank_candidates(q, ex, wv_embeddings, tokenizer)
      8     wv_ranking.append([r[0] for r in ranks].index('0') + 1)

4 frames
<ipython-input-64-ebf0339ab3c8> in rank_candidates(question, candidates, embeddings, tokenizer, dim)
      7     question_vec = [question_to_vec(question, embeddings, tokenizer, dim)]
      8     cand_vec = [question_to_vec(x, embeddings, tokenizer, dim) for x in candidates]
----> 9     ranks = np.argsort(cosine_similarity(question_vec, cand_vec).ravel())[::-1]
     10 
     11     result = [(x, candidates[x]) for x in ranks]

/usr/local/lib/python3.6/dist-packages/sklearn/metrics/pairwise.py in cosine_similarity(X, Y, dense_output)
   1165     # to avoid recursive import
   1166 
-> 1167     X, Y = check_pairwise_arrays(X, Y)
   1168 
   1169     X_normalized = normalize(X, copy=True)

/usr/local/lib/python3.6/dist-packages/sklearn/metrics/pairwise.py in check_pairwise_arrays(X, Y, precomputed, dtype, accept_sparse, force_all_finite, copy)
    142         Y = check_array(Y, accept_sparse=accept_sparse, dtype=dtype,
    143                         copy=copy, force_all_finite=force_all_finite,
--> 144                         estimator=estimator)
    145 
    146     if precomputed:

/usr/local/lib/python3.6/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
    576         if force_all_finite:
    577             _assert_all_finite(array,
--> 578                                allow_nan=force_all_finite == 'allow-nan')
    579 
    580     if ensure_min_samples > 0:

/usr/local/lib/python3.6/dist-packages/sklearn/utils/validation.py in _assert_all_finite(X, allow_nan, msg_dtype)
     58                     msg_err.format
     59                     (type_err,
---> 60                      msg_dtype if msg_dtype is not None else X.dtype)
     61             )
     62     # for object dtype data, we only check for NaNs (GH-13254)

ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

Ответы (1 шт):

Автор решения: Viktor Andriichuk

Получилось решить после правки:

def question_to_vec(question, embeddings, tokenizer, dim=200):
    """
        question: строка
        embeddings: наше векторное представление
        dim: размер любого вектора в нашем представлении
        
        return: векторное представление для вопроса
    """      
    
    sentence_embedding = np.zeros((dim,), dtype=np.float32)
    
    if question == "":
        return sentence_embedding
    
    count = 0
    words = tokenizer.tokenize(question)    

    for word in words:
        if word in embeddings.wv.vocab:
          sentence_embedding += embeddings.wv[word]
          count +=1
    
    if count > 1:
        sentence_embedding = sentence_embedding / count
    
    return sentence_embedding

Там, где идет проверка if len(words) > 1 я делаю на count. А count может быть 0. Например, у нас вопрос состоит из пары слов, которых нет с словаре. Условие выполняется, а count равняется нулю, поэтому получаются nanы.

→ Ссылка