Я думаю, что более естественно думать о проблеме как о графике.
Можно предположить, например, что apple
- это узел 0, а banana
- это узел 1, и первый список указывает, что между 0 и 1 есть грань.
, поэтому сначала преобразуйтеметки в числа:
from sklearn.preprocessing import LabelEncoder
le=LabelEncoder()
le.fit(['apple','banana','orange','rice','potatoes'])
сейчас:
l=[['apple','banana'],
['apple','orange'],
['banana','orange'],
['rice','potatoes'], #I deleted orange as edge is between 2 points, you can transform the triple to 3 pairs or think of different solution
['potatoes','rice']]
конвертируйте метки в числа:
edges=[le.transform(x) for x in l]
>>edges
[array([0, 1], dtype=int64),
array([0, 2], dtype=int64),
array([1, 2], dtype=int64),
array([4, 3], dtype=int64),
array([3, 4], dtype=int64)]
сейчас, начните строить график и добавлять ребра:
import networkx as nx #graphs package
G=nx.Graph() #create the graph and add edges
for e in edges:
G.add_edge(e[0],e[1])
теперь вы можете использовать функцию connected_component_subgraphs
для анализа связанных вершин.
components = nx.connected_component_subgraphs(G) #analyze connected subgraphs
comp_dict = {idx: comp.nodes() for idx, comp in enumerate(components)}
print(comp_dict)
выход:
{0: [0, 1, 2], 1: [3, 4]}
или
print([le.inverse_transform(v) for v in comp_dict.values()])
вывод:
[массив (['яблоко', 'банан', 'апельсин']), массив (['картофель', 'рис'])]
и те,ваши 2 кластера.