Итак, это сложнее, чем я, из-за некоторых проблем вещания разреженных матриц. Кроме того, за короткий период времени я не смог полностью векторизовать его.
Я добавил дополнительную строку текста во фрейм:
df = pd.DataFrame(columns=["id","text"],index=None)
df.loc[0] = ["1","this is a sample text"]
df.loc[1] = ["2","this is a second sample text"]
import collections
sample_dict = collections.defaultdict()
sample_dict["r1"] = "this is sample 1"
sample_dict["r2"] = "is sample"
sample_dict["r3"] = "sample text 2"
Мы будем использовать следующие модули / функции / классы:
from sklearn.feature_extraction.text import CountVectorizer
from scipy.sparse import csr_matrix
import numpy as np
и определим CountVectorizer длясоздавать символьные n_grams
ngram_vectorizer = CountVectorizer(ngram_range=(2, 2), analyzer="char")
не стесняйтесь выбирать n-граммы, которые вам нужны. Я бы посоветовал взять существующий токенизатор и создатель n-грамм. Вы должны найти много таких. Кроме того, CountVectorizer можно настраивать (например, преобразовывать в нижний регистр, избавляться от пробелов и т. Д.)
Мы объединяем все данные:
all_data = np.concatenate((df.text.to_numpy(),np.array(list(sample_dict.values()))))
мы делаем это, так как наш векторизатор должениметь общую схему индексации для всех появляющихся токенов.
Теперь давайте установим векторизатор Count и соответствующим образом преобразуем данные:
ngrammed = ngram_vectorizer.fit_transform(all_data) >0
ngrammed
теперь является разреженной матрицей, содержащей идентификаторы длятокены появляются в соответствующих строках, а не в счетчиках, как раньше. Вы можете проверить ngram_vecotrizer
и найти отображение из токенов в идентификаторы столбцов.
Далее мы хотим сравнить каждую запись в граммах из образца dict с каждой строкой наших текстовых данных ngrammed. Нам нужно немного магии:
texts = ngrammed[:len(df)]
samples = ngrammed[len(df):]
text_rows = len(df)
jaccard_similarities = []
for key, ngram_sample in zip(sample_dict.keys(), samples):
repeated_row_matrix = (csr_matrix(np.ones([text_rows,1])) * ngram_sample).astype(bool)
support = texts.maximum(repeated_row_matrix)
intersection = texts.multiply(repeated_row_matrix).todense()
jaccard_similarities.append(pd.Series((intersection.sum(axis=1)/support.sum(axis=1)).A1, name=key))
support
- это логический массив, который измеряет объединение n-грамм для обоих сопоставимых. intersection
только True, если токен присутствует в обоих сопоставимых. Обратите внимание, что .A1
представляет matrix
-объект в качестве базового базового массива.
Теперь
pd.concat(jaccard_similarities, axis=1)
дает
r1 r2 r3
0 0.631579 0.444444 0.500000
1 0.480000 0.333333 0.384615
, которые вы можете использовать такжедо df
и получить с
pd.concat([df, pd.concat(jaccard_similarities, axis=1)], axis=1)
id text r1 r2 r3
0 1 this is a sample text 0.631579 0.444444 0.500000
1 2 this is a second sample text 0.480000 0.333333 0.384615