def documents_by_cluster(features_column,cluster_column, con=None, n_documents = 20,lead_text_len=100): if con is None: con_ = duckdb.connect('wikipedia.duckdb') else: con_ =con df_centroids = get_cluster_centers(con_,features_column=features_column, cluster_column=cluster_column) query=f"""WITH distances AS ( SELECT s."{cluster_column}" AS cluster, s.title, -- Skracamy tekst do 100 znaków LEFT(s.text, {lead_text_len}) AS lead_text, -- Obliczamy kwadrat odległości euklidesowej między wektorem a centroidem sqrt(list_reduce(list_transform( list_zip(s."{features_column}", c.centroid), x -> (x[1] - x[2]) * (x[1] - x[2]) ), (a, b) -> a + b)) AS dist_to_centroid FROM wikipedia_corpus s JOIN df_centroids c ON s."{cluster_column}" = c."{cluster_column}" ), ranked AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY cluster ORDER BY dist_to_centroid ASC) as rank FROM distances ) SELECT cluster, rank, title, lead_text, dist_to_centroid FROM ranked WHERE rank <= {n_documents} ORDER BY cluster, rank;""" df_docs = con_.execute(query).df() if con is None: con_.close() return df_docs def print_documents_by_cluster(df_docs): for cluster_id in sorted(df_docs['cluster'].unique(), key=int): print(f"\n{'='*80}") print(f" KLASTER {cluster_id} - NAJBLIŻEJ CENTROIDU ".center(80, ' ')) print(f"{'='*80}") # Filtrujemy dokumenty dla danego klastra subset = df_docs[df_docs['cluster'] == cluster_id].sort_values('rank') for _, row in subset.iterrows(): print(f"[{row['rank']}] {row['title']}") print(f" {row['lead_text']}...") print("-" * 40)