Это реализация идей, изложенных в ответе CKM: { ссылка }
Сначала удалите знаки препинания - это не важно для вашей цели - используя этот ответ: { ссылка }
Затем мы воспользуемся одним из методов, описанных здесь: https://blog.eduonix.com/artificial-intelligence/clustering-similar-sentences-together-using-machine-learning/, чтобы сгруппировать похожие предложения.
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer(r'\w+') # only alphanumeric characters
lol_tokenized = []
for title in titles:
lol_tokenized.append(tokenizer.tokenize(title))
Затем получите числовое c представление ваших заголовков:
import numpy as np
from gensim.models import Word2Vec
m = Word2Vec(lol_tokenized,size=50,min_count=1,cbow_mean=1)
def vectorizer(sent,m):
vec = []
numw = 0
for w in sent:
try:
if numw == 0:
vec = m[w]
else:
vec = np.add(vec, m[w])
numw += 1
except Exception as e:
print(e)
return np.asarray(vec) / numw
l = []
for i in lol_tokenized:
l.append(vectorizer(i,m))
X = np.array(l)
Ого, это было много.
Теперь вам нужно выполнить кластеризацию.
from sklearn.cluster import KMeans
clf = KMeans(n_clusters=2,init='k-means++',n_init=100,random_state=0)
labels = clf.fit_predict(X)
print(labels)
for index, sentence in enumerate(lol_tokenized):
print(str(labels[index]) + ":" + str(sentence))
[1 1 0 1 0 0 0]
1:['Series', 'Name', 'Part', '1', 'This', 'is', 'the', 'chapter', 'name']
1:['OC', 'Series', 'Name', 'Part', '2', 'Another', 'name', 'with', 'the', 'word', 'chapter', 'and', 'extra', 'oc', 'at', 'the', 'start']
0:['OC', 'Series', 'Name', 'part', '3', 'punctuation', 'could', 'be', 'not', 'matching', 'so', 'we', 'can', 't', 'always', 'trust', 'common', 'substrings']
1:['OC', 'Another', 'cool', 'story', 'Part', 'I', 'This', 'is', 'the', 'chapter', 'name']
0:['OC', 'another', 'cool', 'story', 'part', 'II', 'another', 'post', 'title']
0:['OC', 'another', 'cool', 'story', 'part', 'III', 'but', 'the', 'author', 'forgot', 'delimiters']
0:['this', 'is', 'a', 'one', 'off', 'story', 'so', 'it', 'doesn', 't', 'have', 'any', 'friends']
Потом можно вытащить те, у которых индекс == 1:
for index, sentence in enumerate(lol_tokenized):
if labels[index] == 1:
print(sentence)
['Series', 'Name', 'Part', '1', 'This', 'is', 'the', 'chapter', 'name']
['OC', 'Series', 'Name', 'Part', '2', 'Another', 'name', 'with', 'the', 'word', 'chapter', 'and', 'extra', 'oc', 'at', 'the', 'start']
['OC', 'Another', 'cool', 'story', 'Part', 'I', 'This', 'is', 'the', 'chapter', 'name']