Как кластеризовать и строить предложения на основе сходства предложений? - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь группировать предложения на основе их сходства друг с другом.Я генерирую вложение предложения, используя ELMo (где оно генерирует вложение для каждого слова, и я суммирую все из них и делю его на количество слов).

Сначала я пытался уместить эти данные в tsne , с вложениями, сгенерированными ELMo (512 измерений), я смог сформировать кластеры, но проблема здесь в том, что в tsne размеры должны быть уменьшены, где он может вместить максимум 3 измерения.Следовательно, результат был не таким точным.Затем я попытался с DBSCAN , где я не вижу каких-либо ограничений на размер входного сигнала, подаваемого на него (пожалуйста, исправьте меня, если я ошибаюсь).

Теперь я поражен составлением графиков прогнозов, сделанных с помощью DBSCAN.Кроме того, когда я попытался напечатать предсказанные этикетки, все они были «-1».Есть ли другой способ кластеризации предложений или как эффективно использовать размерность 512, встроенную в кластеризацию предложения с помощью tsne или dbscan?

def tsnescatterplot(sentences):
    arr = np.empty((0, 512), dtype='f')
    word_labels = []
    for sentence in sentences:
        wrd_vector = get_elmo_embeddings(sentence)
        print(sentence)
        word_labels.append(sentence)
        arr = np.append(arr, np.array([wrd_vector]), axis=0)
    print('Printing array')
    print(arr)

    # find tsne coords for 2 dimensions
    tsne = TSNE(n_components=2, random_state=0)
    np.set_printoptions(suppress=True)
    Y = tsne.fit_transform(arr)

    x_coords = Y[:, 0]
    y_coords = Y[:, 1]
    # display scatter plot
    plt.scatter(x_coords, y_coords)

    for label, x, y in zip(word_labels, x_coords, y_coords):
        plt.annotate(label, xy=(x, y), xytext=(0, 0), textcoords='offset points')
    plt.xlim(x_coords.min() + 0.5, x_coords.max() + 0.5)
    plt.ylim(y_coords.min() + 0.5, y_coords.max() + 0.5)
    plt.show()

def dbscan_scatterplot(sentences):
    arr = np.empty((0, 512), dtype='f')
    for sentence in sentences:
        wrd_vector = get_elmo_embeddings(sentence)
        arr = np.append(arr, np.array([wrd_vector]), axis=0)
    dbscan = DBSCAN()
    np.set_printoptions(suppress=True)
    Y = dbscan.fit(arr)

1 Ответ

0 голосов
/ 21 декабря 2018

Выбор параметров для DBSCAN имеет большое значение.

Глупо из sklearn (и здесь неоднократно возникает проблема), что он предоставляет значения по умолчанию - потому что они просто не работаютдля всего, кроме данных низкоразмерных игрушекВместо этого они должны потребовать, чтобы пользователь указал значение.

Вам нужно выбрать соответствующий эпсилон соответственно.Но это будет трудно выбрать хорошо для многомерных данных.Вы обнаружите, что результаты внезапно переходят от всех -1 (ничего не кластеризовано) ко всем 0 (все, что связано), и выбрать правильное значение сложно.В литературе есть некоторые эвристические подходы, которые вам необходимо изучить.

И последнее, но не менее важное: усреднение векторов слов имеет тенденцию давать довольно плохие результаты .Потому что все они движутся к среднему.Более длинные документы приближаются к среднему, более короткие документы остаются дальше снаружи.Но это не то, что вы хотите иметь для кластеризации ... Этого дополнительного искажения может быть достаточно, чтобы испортить любой сигнал, который у вас был раньше.

...