Hub and Authority scores: networkx vs igraph - python

I computed hub and authority scores of a simple graph using igraph and networkx and they give me the same results. For example, see below
import networkx as nx
from igraph import *
G = nx.DiGraph()
G.add_edges_from([('A', 'D'), ('B', 'C'), ('B', 'E'), ('C', 'A'),
('D', 'C'), ('E', 'D'), ('E', 'B'), ('E', 'F'),
('E', 'C'), ('F', 'C'), ('F', 'H'), ('G', 'A'),
('G', 'C'), ('H', 'A')])
hubs, authorities = nx.hits(G, max_iter = 50, normalized = True)
edges = [('A', 'D'), ('B', 'C'), ('B', 'E'), ('C', 'A'),
('D', 'C'), ('E', 'D'), ('E', 'B'), ('E', 'F'),
('E', 'C'), ('F', 'C'), ('F', 'H'), ('G', 'A'),
('G', 'C'), ('H', 'A')]
g = Graph.TupleList(directed=True,edges=edges)
hub_igraph = [g.hub_score()[i]/sum(g.hub_score()) for i in range(len(g.hub_score()))]
In[1] print(hubs)
Out[1]
{'A': 0.04642540386472174,
'D': 0.133660375232863,
'B': 0.15763599440595596,
'C': 0.037389132480584515,
'E': 0.2588144594158868,
'F': 0.15763599440595596,
'H': 0.037389132480584515,
'G': 0.17104950771344754}
In[2] print(hub_igraph)
Out[2]
[0.04642540403219994,
0.13366037526115376,
0.1576359944296732,
0.03738913224642651,
0.2588144598468665,
0.1576359944296732,
0.037389132246426524,
0.17104950750758036]
However, for large graph (2k nodes) that is sparse and almost tree-like, the result is vastly different. I computed the hub/authority score using HITS algorithm and the output for the large graph matches the one from networkx but not the one from igraph. I cannot find the source-code for igraph and hence I am wondering where is the discrepancy coming from.
Any hint is appreciated. Thanks.

Related

what is optimal solution to get actual two point combinations with given list? [duplicate]

This question already has answers here:
How to find all combinations of two numbers in a list? [duplicate]
(2 answers)
combinations with two elements
(3 answers)
Closed 1 year ago.
I have a list something like this and I want all combinations for two point solution
list1=['a','b','c','d','e','f','g','h']
and I need all 28 combinations from this Expected result:
[['a','b'],['a','c'],['a','d'],['a','e'],['a','f'],['a','g'],['a','h'],
['b','c'],['b','d'],['b','e'],['b','f'],['b','g'],['b','h'],
['c','d'],['c','e'],['c','f'],['c','g'],['c','h'],
['d','e'],['d','f'],['d','g'],['d','h'],
['e','f'],['e','g'],['e','h'],
['f','g'],['f','h'],
['g','h']]
This link is explanation of how 28 combinations.
https://www.calculatorsoup.com/calculators/discretemathematics/combinations.php
I have tried scipy
from scipy.special import comb
comb(8, 2, exact=True)
but it is not giving me the actual combination, It is giving me number of possible combination.
itertools is giving me memory error. as in my list df["ID"] there would be more than 1000 elements.
len(list(combinations(df["ID"].to_list(),5)))
If the I want three point solution then possible combination would be 56
Thanks for your help
Using itertools.combinations returns 28 combinations.
itertools.combinations(list1, 2)
#[('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('a', 'g'), ('a', 'h'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('b', 'g'), ('b', 'h'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('c', 'g'), ('c', 'h'), ('d', 'e'), ('d', 'f'), ('d', 'g'), ('d', 'h'), ('e', 'f'), ('e', 'g'), ('e', 'h'), ('f', 'g'), ('f', 'h'), ('g', 'h')]
len(list(itertools.combinations(list1, 2)))
#28

Markov chain probability calculation - Python

I have a Python dictionary with state transition probabilities of a Markov-chain model.
dict_m = {('E', 'F'): 0.29032258064516131, ('D', 'F'): 0.39726027397260272, ('D', 'D'): 0.30136986301369861, ('E', 'D'): 0.32258064516129031, ('E', 'E'): 0.38709677419354838, ('D', 'E'): 0.30136986301369861, ('F', 'F'): 0.68152866242038213, ('F', 'E'): 0.10191082802547771, ('F', 'D'): 0.19108280254777071, ('F', 'H'): 0.025477707006369428, ('H', 'F'): 1.0}
Suppose I have a data sequence like following. State transitions are from D to E, E to F, F to E..etc.
s = ['D','E','F','E','E','F','H','F']
Now I need to calculate the probability value by multiplying the probabilities in dict_m. In this case probability of all state transition is
probability = 0.301370*0.290323*0.101911*0.387097*0.290323*0.025478*1.000000
Can anybody help me to formulate this.
print zip(s,s[1:])
[('D', 'E'), ('E', 'F'), ('F', 'E'), ('E', 'E'), ('E', 'F'), ('F', 'H'), ('H', 'F')]
You have to use the tuples from the zip to index the dictionary and then multiply all the numbers.
from operator import mul
print reduce(mul, (dict_m[t] for t in zip(s, s[1:])))

Extract values from list and make tuples

I need a simple thing but I cannot do it:
list = 'SBEDFG'
I need as output:
[(S,B),(B,E),(E,D),(D,F),(F,G)]
This is what I tried:
[(list[ind],list[ind+1]) for ind,i in list]
But it gives me this error:
ValueError: need more than 1 value to unpack
Can you help me? Thanks!
You can simply use zip() function like this:
>>>l = 'SBEDFG'
>>>zip(l,l[1:])
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
With Python 3.X you'll need to convert the zip result to a list:
#Python 3.X
>>>l = 'SBEDFG'
>>>list(zip(l,l[1:]))
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
With list comprehension I would do it with range() function:
>>>[(l[i],l[i+1]) for i in range(len(l)-1)]
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
Hope this helps!
try this
>>> [(list[i-1], list[i]) for i in range(1, len(list))]
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]
>>>b=[]
>>> for ind,i in enumerate(list):
... if ind < len(list)-1:
... b.append((list[ind],list[ind+1]))
...
>>> print b
[('S', 'B'), ('B', 'E'), ('E', 'D'), ('D', 'F'), ('F', 'G')]

Permutation with redundant overlaps? Python

I used itertools to run a permutation on a list that I have.
mylist = [a, b, c, d, e, f]
mypermutations = itertools.permutations(mylist,2)
mypermutations_list = list(mypermutations)
print mypermutations_list
prints:
[(a, b), (a, c), (a, d)...]
However, the permutation list doesn't include (a, a), (b, b), etc. I recognize that's probably because most people don't want such redundant pairings. However, I would like to include such pairings as a control for the program I'm writing.
Is there a way to run a permutation and get these combinations? I have no idea what to use instead of permutations.
You want itertools.product instead:
>>> import itertools
>>> mylist = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list(itertools.product(mylist, repeat=2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ...]
You're looking for itertools.product, it returns the Cartesian product of the iterable:
>>> from itertools import product
>>> list(product('abcdef', repeat=2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'a'), ('c', 'b'), ('c', 'c'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('d', 'a'), ('d', 'b'), ('d', 'c'), ('d', 'd'), ('d', 'e'), ('d', 'f'), ('e', 'a'), ('e', 'b'), ('e', 'c'), ('e', 'd'), ('e', 'e'), ('e', 'f'), ('f', 'a'), ('f', 'b'), ('f', 'c'), ('f', 'd'), ('f', 'e'), ('f', 'f')]

Python permutations of both sequence and subsequences

Question: How do I implement double_permutations(s) below?
>>> s = [('a', 'b'), ('c', 'd'), ('e', 'f')]
>>> for answer in double_permutation(s):
... print(answer) # in some order
[('a', 'b'), ('c', 'd'), ('e', 'f')]
[('a', 'b'), ('d', 'c'), ('e', 'f')]
[('a', 'b'), ('c', 'd'), ('f', 'e')]
[('a', 'b'), ('d', 'c'), ('f', 'e')]
[('a', 'b'), ('e', 'f'), ('c', 'd')]
[('a', 'b'), ('f', 'e'), ('c', 'd')]
[('a', 'b'), ('e', 'f'), ('d', 'c')]
[('a', 'b'), ('f', 'e'), ('d', 'c')]
What I've tried (breaks down once the outer list is longer than 3 elements)
from itertools import permutations
def double_permutation(l):
def double_permutation_recur(s, r):
if not r:
yield s
else:
for permutation in permutations(r):
s1 = s + [permutation[0]]
s2 = s + [(permutation[0][1], permutation[0][0])]
for perm1 in double_permutation_recur(s1, permutation[1:]):
yield perm1
for perm2 in double_permutation_recur(s2, permutation[1:]):
yield perm2
return double_permutation_recur([l[0]], l[1:])
This should yield double_factorial(n-1) answers for a list of length n. This works up through n = 3, but breaks down at n = 4 (which yields 96 instead of 48 answers).
You can build this up from the primitives in the itertools module
import itertools
s = [('a', 'b'), ('c', 'd'), ('e', 'f')]
Is this what you're describing?
def permute(it):
return itertools.product(*(itertools.permutations(i) for i in it))
>>> for i in permute(s):
... print i
(('a', 'b'), ('c', 'd'), ('e', 'f'))
(('a', 'b'), ('c', 'd'), ('f', 'e'))
(('a', 'b'), ('d', 'c'), ('e', 'f'))
(('a', 'b'), ('d', 'c'), ('f', 'e'))
(('b', 'a'), ('c', 'd'), ('e', 'f'))
(('b', 'a'), ('c', 'd'), ('f', 'e'))
(('b', 'a'), ('d', 'c'), ('e', 'f'))
(('b', 'a'), ('d', 'c'), ('f', 'e'))
Or do you want:
def permute2(it):
return itertools.chain.from_iterable(
permute(p)
for p in itertools.permutations(it)
)
>>> for i in permute2(s):
... print i
(('a', 'b'), ('c', 'd'), ('e', 'f'))
(('a', 'b'), ('c', 'd'), ('f', 'e'))
(('a', 'b'), ('d', 'c'), ('e', 'f'))
(('a', 'b'), ('d', 'c'), ('f', 'e'))
(('b', 'a'), ('c', 'd'), ('e', 'f'))
(('b', 'a'), ('c', 'd'), ('f', 'e'))
(('b', 'a'), ('d', 'c'), ('e', 'f'))
(('b', 'a'), ('d', 'c'), ('f', 'e'))
(('a', 'b'), ('e', 'f'), ('c', 'd'))
(('a', 'b'), ('e', 'f'), ('d', 'c'))
(('a', 'b'), ('f', 'e'), ('c', 'd'))
(('a', 'b'), ('f', 'e'), ('d', 'c'))
(('b', 'a'), ('e', 'f'), ('c', 'd'))
(('b', 'a'), ('e', 'f'), ('d', 'c'))
(('b', 'a'), ('f', 'e'), ('c', 'd'))
(('b', 'a'), ('f', 'e'), ('d', 'c'))
(('c', 'd'), ('a', 'b'), ('e', 'f'))
(('c', 'd'), ('a', 'b'), ('f', 'e'))
(('c', 'd'), ('b', 'a'), ('e', 'f'))
(('c', 'd'), ('b', 'a'), ('f', 'e'))
(('d', 'c'), ('a', 'b'), ('e', 'f'))
(('d', 'c'), ('a', 'b'), ('f', 'e'))
(('d', 'c'), ('b', 'a'), ('e', 'f'))
(('d', 'c'), ('b', 'a'), ('f', 'e'))
(('c', 'd'), ('e', 'f'), ('a', 'b'))
(('c', 'd'), ('e', 'f'), ('b', 'a'))
(('c', 'd'), ('f', 'e'), ('a', 'b'))
(('c', 'd'), ('f', 'e'), ('b', 'a'))
(('d', 'c'), ('e', 'f'), ('a', 'b'))
(('d', 'c'), ('e', 'f'), ('b', 'a'))
(('d', 'c'), ('f', 'e'), ('a', 'b'))
(('d', 'c'), ('f', 'e'), ('b', 'a'))
(('e', 'f'), ('a', 'b'), ('c', 'd'))
(('e', 'f'), ('a', 'b'), ('d', 'c'))
(('e', 'f'), ('b', 'a'), ('c', 'd'))
(('e', 'f'), ('b', 'a'), ('d', 'c'))
(('f', 'e'), ('a', 'b'), ('c', 'd'))
(('f', 'e'), ('a', 'b'), ('d', 'c'))
(('f', 'e'), ('b', 'a'), ('c', 'd'))
(('f', 'e'), ('b', 'a'), ('d', 'c'))
(('e', 'f'), ('c', 'd'), ('a', 'b'))
(('e', 'f'), ('c', 'd'), ('b', 'a'))
(('e', 'f'), ('d', 'c'), ('a', 'b'))
(('e', 'f'), ('d', 'c'), ('b', 'a'))
(('f', 'e'), ('c', 'd'), ('a', 'b'))
(('f', 'e'), ('c', 'd'), ('b', 'a'))
(('f', 'e'), ('d', 'c'), ('a', 'b'))
(('f', 'e'), ('d', 'c'), ('b', 'a'))
Or to "anchor" the first element:
def permute3(s):
return s[:1] + list(p) for p in permute2(s[1:])
>>> for i in permute3(s):
... print i
[('a', 'b'), ('c', 'd'), ('e', 'f')]
[('a', 'b'), ('c', 'd'), ('f', 'e')]
[('a', 'b'), ('d', 'c'), ('e', 'f')]
[('a', 'b'), ('d', 'c'), ('f', 'e')]
[('a', 'b'), ('e', 'f'), ('c', 'd')]
[('a', 'b'), ('e', 'f'), ('d', 'c')]
[('a', 'b'), ('f', 'e'), ('c', 'd')]
[('a', 'b'), ('f', 'e'), ('d', 'c')]

Categories

Resources