Comunidades temáticas

La detección de comunidades identifica grupos de keywords que co-ocurren entre sí más de lo esperado por azar. Cada comunidad representa un subcampo temático o metodológico coherente. Se usó el algoritmo Louvain sobre el grafo de co-ocurrencia bruto (sin normalización de pesos).

Detección de comunidades

Ver código
from co_occurrence.io.loader import load_wos_data
from co_occurrence.config import DATA_FILE
from co_occurrence.graphs.cooccurrence import build_cooccurrence_graph
import ast
import pandas as pd
from pathlib import Path

OUTPUT = Path("../output")
comm_df = pd.read_csv(OUTPUT / "communities_labeled.csv")

# Reconstruir partition dict desde CSV (fuente de verdad)
df = load_wos_data(DATA_FILE)
G = build_cooccurrence_graph(df, column="Author Keywords", min_weight=1, min_frequency=2)

partition = {}
for _, row in comm_df.iterrows():
    kws = ast.literal_eval(row["keywords"]) if isinstance(row["keywords"], str) else []
    for kw in kws:
        if kw in G.nodes:
            partition[kw] = row["community"]

print(f"Comunidades detectadas: {len(comm_df)}")
for _, row in comm_df.iterrows():
    print(f"  Comunidad {row['community']} ({row['size']} nodos): {row['label']}")
Comunidades detectadas: 8
  Comunidad 0 (14 nodos): segmentation / tourism demand forecasting / gastronomy / sustainable tourism / climate change (+9 más)
  Comunidad 1 (14 nodos): tourism / economic growth / granger causality / well-being / panel data (+9 más)
  Comunidad 2 (25 nodos): multivariate analysis / cluster analysis / competitiveness / perception / water quality (+20 más)
  Comunidad 3 (9 nodos): discriminant analysis / fuzzy-set qualitative comparative analysis / exploratory factor analysis / qualitative comparative analysis / time series (+4 más)
  Comunidad 4 (18 nodos): multiple regression / hospitality / principal component analysis / social media / hotels (+13 más)
  Comunidad 5 (7 nodos): environmental management / consumer behavior / heavy metals / brand personality / tourism management (+2 más)
  Comunidad 6 (17 nodos): satisfaction / motivation / destination image / structural equation modeling / loyalty (+12 más)
  Comunidad 7 (20 nodos): covid-19 / sustainability / behavioral intention / ecotourism / medical tourism (+15 más)

Tabla de comunidades

Ver código
OUTPUT = Path("../output")
comm_df = pd.read_csv(OUTPUT / "communities_labeled.csv")

# Parse keywords list stored as string
import ast

comm_df["n_keywords"] = comm_df["keywords"].apply(
    lambda x: len(ast.literal_eval(x)) if isinstance(x, str) else 0
)

display_df = comm_df[["community", "label", "n_keywords"]].copy()
display_df.columns = ["ID", "Etiqueta", "N Keywords"]

try:
    from itables import show
    show(
        display_df,
        caption="Comunidades temáticas detectadas por Louvain",
        lengthMenu=[10, 20],
    )
except ImportError:
    display(display_df)
Loading ITables v2.7.3 from the internet... (need help?)

Tamaño de comunidades (treemap)

Ver código
import plotly.express as px
import ast

# Rebuild a flat dataframe: one row per keyword
rows = []
for _, row in comm_df.iterrows():
    kws = ast.literal_eval(row["keywords"]) if isinstance(row["keywords"], str) else []
    for kw in kws:
        rows.append({"community": str(row["community"]), "label": row["label"], "keyword": kw})

flat_df = pd.DataFrame(rows)

fig = px.treemap(
    flat_df,
    path=["label", "keyword"],
    title="Comunidades temáticas — tamaño proporcional al número de keywords",
    height=600,
)
fig.update_traces(textinfo="label+value")
fig.show()

Distribución del tamaño de las comunidades Louvain

Interpretación de comunidades

NoteComunidad 0 — Segmentación y demanda turística

Agrupa técnicas de segmentación (cluster analysis, self-organizing maps) junto con keywords de demanda turística y turismo sostenible. Representa el subcampo de segmentación de mercados y gestión de destinos.

NoteComunidad 1 — Econometría del turismo

Concentra keywords de series temporales y econometría (Granger causality, VAR, panel data, economic growth). Es el subcampo de modelización económica del turismo con técnicas de series temporales multivariadas.

NoteComunidad 2 — Análisis multivariado clásico

El grupo más amplio: cluster analysis, multivariate analysis, competitiveness, logistic regression. Corresponde al uso clásico de técnicas multivariadas descriptivas e inferenciales en estudios de destinos y competitividad.

NoteComunidad 3 — Métodos cualitativos comparativos

Reúne fsQCA, discriminant analysis, DEA y PLS. Es un subcampo metodológico heterogéneo que agrupa técnicas de comparación y clasificación menos frecuentes en el corpus.

NoteComunidad 4 — Regresión y análisis multivariado aplicado

Multiple regression, PCA, hospitality, hotels, social media. Representa la aplicación de técnicas de reducción dimensional y regresión al sector hotelero y la gestión de la reputación online.

NoteComunidad 5 — Indicadores ambientales y de consumo

Consumer behavior, environmental management, conservation. Subcampo menor centrado en indicadores de gestión ambiental con técnicas multivariadas.

NoteComunidad 6 — SEM y comportamiento del turista

structural equation modeling, satisfaction, motivation, destination image, loyalty. El subcampo más cohesionado: SEM/PLS aplicado al comportamiento del turista y la imagen de destino.

NoteComunidad 7 — COVID-19, sostenibilidad y comportamiento reciente

covid-19, sustainability, behavioral intention, ecotourism, medical tourism. Agrupa la producción reciente post-2020 que combina sostenibilidad con técnicas de análisis de comportamiento (SEM, correspondence analysis).

Modularidad

Ver código
import networkx.algorithms.community as nx_comm

# Convert partition dict to list of sets for networkx
community_sets = {}
for node, cid in partition.items():
    community_sets.setdefault(cid, set()).add(node)

communities_list = list(community_sets.values())
modularity = nx_comm.modularity(G, communities_list)
print(f"Modularidad Q = {modularity:.4f}")
print("(Q > 0.3 indica estructura de comunidades significativa)")
Modularidad Q = 0.4547
(Q > 0.3 indica estructura de comunidades significativa)