-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hawkes cumulants - Tensorflow v1 #505
Hawkes cumulants - Tensorflow v1 #505
Conversation
Hi @Mbompr I am trying to adapt the code of |
If I remember correctly, these values have been obtained by making the algorithm run. |
Understood. So, they are not ground truth. From a first run with v2 I get somewhat similar values, but the precision of 6 decimal places is certainly lost. |
I think it makes sense to change the values in the test within the PR then |
I am thinking whether it would be more appropriate to design a test as follows:
|
I agree that makes more sense. But I find it hard to suggest something big when I had been lazy before 😬 |
np.random.seed(320982) | ||
|
||
@staticmethod | ||
def get_simulated_model(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mbompr This is the idea that I was suggesting in the conversation of this PR. I simulate a hawkes process with exponential kernels and I train HawkesCumulantMatching
on five samples. Loading pickled data would be replaced by this, if you agree.
More importantly, the assertion of almost equality now are between the exact theoretical values from the simulated hawkes process and the calibrated coefficients of HawkesCumulantMatching
. When these assertion succeed, they should guarantee approximate exactness of algorithm.
np.allclose( | ||
learner.solution, | ||
expected_R_pred, | ||
atol=0.1, # TODO: explain why estimation is not so accurate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mbompr Unfortunately, accuracy is not so good here. Are you familiar with the tuning of hyperparameters of HawkesCumulantMatching
? If yes, can you please see if a better choice of step
, max_iter
etc... gives more accurate estimations? I can see from the paper that the accuracy was really good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Mbompr
Could you look into this please?
@@ -35,4 +33,29 @@ class DLL_PUBLIC HawkesCumulant : public ModelHawkesList { | |||
} | |||
}; | |||
|
|||
class DLL_PUBLIC HawkesTheoreticalCumulant { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a new c++ class that implements the theoretical formulae for mean intensity, covariance and skewness of hawkes processes. These are the formulae (7), (8), and (9) in the paper.
Currently, the class is only used to test the accuracy of the estimation of HawkesCumulantMatching
. However, the formulae have intrinsic values beside such testing, and we might include these calculations in a more general Hawkes class in the future.
|
||
np.testing.assert_array_almost_equal( | ||
learner.objective(R=learner.solution), 149232.94041039888) | ||
@unittest.skipIf(SKIP_TF, "Tensorflow not available") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PhilipDeegan I have defined a global boolean variable SKIP_TF
and used it with unitest.skipIf
np.allclose( | ||
learner.solution, | ||
expected_R_pred, | ||
atol=0.1, # TODO: explain why estimation is not so accurate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Mbompr
Could you look into this please?
Hi @PhilipDeegan , Do you think we can merge this? |
@@ -126,3 +124,66 @@ double HawkesCumulant::compute_E_ijk(ulong r, ulong i, ulong j, ulong k, | |||
res /= (*end_times)[r]; | |||
return res; | |||
} | |||
|
|||
HawkesTheoreticalCumulant::HawkesTheoreticalCumulant(int dim) : d(dim) { | |||
Lambda = SArrayDouble::new_ptr(dim); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can these be part of the constuctor setup arguments like : d(dim)
?
@@ -126,3 +124,66 @@ double HawkesCumulant::compute_E_ijk(ulong r, ulong i, ulong j, ulong k, | |||
res /= (*end_times)[r]; | |||
return res; | |||
} | |||
|
|||
HawkesTheoreticalCumulant::HawkesTheoreticalCumulant(int dim) : d(dim) { | |||
Lambda = SArrayDouble::new_ptr(dim); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- is
Lambda
the best name? - variables names don't typically start with upper case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variables Lambda
, C
, Kc
, and R
represent first integrated cumulant, second integrated cumulant, (reduced) third integrated cumulant, and inverse of
I agree that the upper case is uncommon. I can change the name as follows:
Lambda
-> first_cumulant
C
-> second_cumulant
Kc
-> third_cumulant
R
-> g_geometric
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done here: 11353f4
@@ -56,15 +53,13 @@ bool Hawkes::update_time_shift_(double delay, ArrayDouble &intensity, | |||
void Hawkes::reset() { | |||
for (unsigned int i = 0; i < n_nodes; i++) { | |||
for (unsigned int j = 0; j < n_nodes; j++) { | |||
if (kernels[i * n_nodes + j] != nullptr) | |||
kernels[i * n_nodes + j]->rewind(); | |||
if (kernels[i * n_nodes + j] != nullptr) kernels[i * n_nodes + j]->rewind(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it was unsigned int
before, I would generally prefer std::uint32_t
or similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood...
I will open a new PR about that because it is not related to HawkesCumulant
or tensorflow
public: | ||
HawkesTheoreticalCumulant(int); | ||
int get_dimension() { return d; } | ||
void set_baseline(const SArrayDoublePtr mu) { this->mu = mu; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might not have it everywhere, but T const[&] n
is the preferred order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed: fa43f6d
On branch tensorflow-v1-hawkes-cumulants Your branch is up-to-date with 'origin/tensorflow-v1-hawkes-cumulants'. Changes to be committed: modified: lib/cpp/hawkes/inference/hawkes_cumulant.cpp modified: lib/include/tick/hawkes/inference/hawkes_cumulant.h modified: lib/swig/tick/hawkes/inference/hawkes_cumulant.i modified: tick/hawkes/inference/hawkes_cumulant_matching.py
Conflicts: .github/workflows/build_nix.yml tick/hawkes/inference/hawkes_cumulant_matching.py
@PhilipDeegan |
'tensorflow-v1-hawkes-cumulants' into 'pytorch-hawkes-cumulant'
This PR proposes to break the class
HawkesCumulantMatching
in a base class with the general interface, and a derived class that implements the methods of the interface using tensorflow. A second derived class that will implement the same methods with pytorch is also prototyped.Moreover, this PR tries to migrate
HawkesCumulantMatching
to tensorflow v2 minimising the required changes: I usedtf.compat.v1
. Tests of the inference methodology are re-activated (no longer skipped by default).