In [4]:
from snpp.utils.data import load_csv_network
from snpp.utils.graph import get_triangles
from itertools import combinations
from collections import Counter
from tqdm import tqdm
import pandas as pd
In [5]:
g = load_csv_network('data/soc-sign-slashdot.txt').to_undirected()
In [6]:
g = g.to_undirected()
In [7]:
tris = get_triangles(g)
In [22]:
freqs = Counter()
for tri in tqdm(tris):
neg_cnt = sum(1 for u, v in combinations(tri, 2)
if g[u][v]['sign'] == -1)
freqs[neg_cnt] += 1
print(freqs)
In [23]:
vals = np.array(list(freqs.values()))
cols = list(map(lambda c: "{} triangle(s)".format(c),
freqs.keys()))
df = pd.DataFrame(data=[vals / np.sum(vals) * 100],
columns=cols)
print(df)
Conclusion
There are very few weakly-balanced triangles (~2.15%).
So weak social balance is not suitable here.
In other words, strong social balance is sufficient.
In [14]:
freqs = Counter()
for u, v in tqdm(g.edges_iter()):
if set(g.adj[u]).intersection(set(g.adj[v])):
freqs['#edge-without-triangle'] += 1
else:
freqs['#edge-with-triangle'] += 1
print(freqs)
vals = np.array(list(freqs.values()))
print(vals / np.sum(vals))
Conclusion
There are quite triangle-free edges (more than half of the edges), thus triangle-based method is not suitable.
This indicates higher order cycles can be considered. However, enumerating length-n cycles is time-consuming.