igraph / python-igraph

Python interface for igraph
GNU General Public License v2.0
1.31k stars 249 forks source link

return FittedPowerLaw(*_power_law_fit(data, xmin, force_continuous)) TypeError: __init__() missing 1 required positional argument: 'p' #580

Closed dange-academic closed 2 years ago

dange-academic commented 2 years ago

Describe the bug

power_law_fit() throws exception in version 0.10.1. It works correctly in version 0.9.11.

To reproduce

The example code:

from igraph import *

g = Graph.Barabasi(n=5000,m=1)
result = power_law_fit(g.degree())

print(result)
print(result.alpha)

igraph==0.9.11, the output results as follows:

Exponent (alpha)  = 3.146555
Cutoff (xmin)     = 5.000000

Log-likelihood    = -805.694601

H0: data was drawn from the fitted distribution

KS test statistic = 0.022472
p-value           = 0.993125

H0 could not be rejected at significance level 0.05
3.146555236456355

igraph ==0.10.1, an error appears as follows:

Traceback (most recent call last):
  File "c:\Users\dange\Desktop\power_law_fit\test.py", line 6, in <module>
    result = power_law_fit(g.degree())
  File "D:\python39\lib\site-packages\igraph\statistics.py", line 554, in power_law_fit
    return FittedPowerLaw(*_power_law_fit(data, xmin, force_continuous))
TypeError: __init__() missing 1 required positional argument: 'p'

Version information

szhorvat commented 2 years ago

Can you please edit this report and fill out all sections of the bug report template?

dange-academic commented 2 years ago

The following error occurred using igraph=0.10.1:

*return FittedPowerLaw(_power_law_fit(data, xmin, force_continuous)) TypeError: init() missing 1 required positional argument: 'p'**

But this error does not occur when igraph==0.9.11

szhorvat commented 2 years ago

Can you please include steps to reproduce the issue? A simple but complete code example would be useful.

dange-academic commented 2 years ago

The example code:

from igraph import *

g = Graph.Barabasi(n=5000,m=1)
result = power_law_fit(g.degree())

print(result)
print(result.alpha)

igraph==0.9.11, the output results as follows:

Exponent (alpha)  = 3.146555
Cutoff (xmin)     = 5.000000

Log-likelihood    = -805.694601

H0: data was drawn from the fitted distribution

KS test statistic = 0.022472
p-value           = 0.993125

H0 could not be rejected at significance level 0.05
3.146555236456355

igraph ==0.10.1, an error appears as follows:

Traceback (most recent call last):
  File "c:\Users\dange\Desktop\power_law_fit\test.py", line 6, in <module>
    result = power_law_fit(g.degree())
  File "D:\python39\lib\site-packages\igraph\statistics.py", line 554, in power_law_fit
    return FittedPowerLaw(*_power_law_fit(data, xmin, force_continuous))
TypeError: __init__() missing 1 required positional argument: 'p'
szhorvat commented 2 years ago

Thank you for providing the example. This is helpful. I moved the example to the top post and hid the comments above to avoid duplication. We will look into the problem.

dange-academic commented 2 years ago

Thank you very much

ntamas commented 2 years ago

Phew, this is going to be tricky.

igraph 0.9 and earlier contained a slightly flawed version of the p-value estimation. It was quite fast, but it was less rigorous than the original approach proposed in the Clauset-Shalizi-Newman paper, and it did not yield the same results on the same set of inputs. igraph 0.10 updated its vendored plfit library to a newer version, which now contains the correct estimation method, but as the new method is significantly slower than the previous one, the calculation of the p-value was deferred to a separate function. We need to follow this change up in the Python interface because right now the lower-level _power_law_fit() function does not provide a p-value, but the high-level FittedPowerLaw class requires one in the constructor.

The easiest change would be to restore the earlier behaviour of the Python interface by simply calculating the p-value proactively when a FittedPowerLaw instance is constructed, but this would be significantly slower than in igraph 0.9. The alternative is to implement lazy calculation of the p-value in FittedPowerLaw so it is calculated only when you retrieve the p property of the result or you explicitly print / format the FittedPowerLaw object.

dange-academic commented 2 years ago

Thank you very much for your answers.