Skip to content

Commit

Permalink
Fixes to spade modules regarding the integration of an updated versio…
Browse files Browse the repository at this point in the history
…n of fim (#140)

* Fixes to spade modules which integrate an updated version of `fim` and updated corresponding tests
  • Loading branch information
pietroquaglio authored and alperyeg committed Mar 2, 2018
1 parent 87b9d3b commit dbfdde1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 30 deletions.
57 changes: 32 additions & 25 deletions elephant/spade.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
SPADE analysis can be applied as demonstrated in this short toy example of 10
artificial spike trains of exhibiting fully synchronous events of order 10.
This modules relies on the implementation of the fp-growth algorithm contained
in the file fim.so which can be found here (http://www.borgelt.net/pyfim.html)
and should be available in the spade_src folder (elephant/spade_src/).
If the fim.so module is not present in the correct location or cannot be
imported (only available for linux OS) SPADE will make use of a python
implementation of the fast fca algorithm contained in
elephant/spade_src/fast_fca.py, which is about 10 times slower.
import elephant.spade
import elephant.spike_train_generation
import quantities as pq
Expand Down Expand Up @@ -56,6 +65,7 @@
import time
import quantities as pq
import warnings
warnings.simplefilter('once', UserWarning)
try:
from mpi4py import MPI # for parallelized routines
HAVE_MPI = True
Expand All @@ -65,9 +75,11 @@
try:
from elephant.spade_src import fim
HAVE_FIM = True
# raise ImportError
except ImportError: # pragma: no cover
HAVE_FIM = False
warnings.warn(
'fim.so not found in elephant/spade_src folder,' +
'you are using the python implementation of fast fca')
from elephant.spade_src import fast_fca


Expand Down Expand Up @@ -444,7 +456,8 @@ def concepts_mining(data, binsize, winlen, min_spikes=2, min_occ=2,
# By default, set the maximum pattern size to the maximum number of
# spikes in a window
if max_spikes is None:
max_spikes = int(np.max(np.sum(rel_matrix, axis=1)))
max_spikes = np.max((int(np.max(np.sum(rel_matrix, axis=1))),
min_spikes + 1))
# By default, set maximum number of occurrences to number of non-empty
# windows
if max_occ is None:
Expand Down Expand Up @@ -537,7 +550,7 @@ def _build_context(binary_matrix, winlen):
rel_matrix[w, :] = times
# appending to the transactions spike idx (fast_fca input) of the
# current window (fpgrowth input)
transactions.append(attributes[times])
transactions.append(list(attributes[times]))
# Return context and rel_matrix
return context, transactions, rel_matrix

Expand Down Expand Up @@ -624,26 +637,30 @@ def _fpgrowth(transactions, min_c=2, min_z=2, max_z=None,
'''
# By default, set the maximum pattern size to the number of spiketrains
if max_z is None:
max_z = np.max([len(tr) for tr in transactions]) + 1
max_z = np.max((np.max([len(tr) for tr in transactions]), min_z + 1))
# By default set maximum number of data to number of bins
if max_c is None:
max_c = len(transactions) + 1
if report != '#' or min_neu > 1:
max_c = len(transactions)
if min_neu >= 1:
if min_neu < 1:
raise AttributeError('min_neu must be an integer >=1')
# Inizializing outputs
concepts = []
spec_matrix = np.zeros((max_z, max_c))
spectrum = []
# Mining the data with fpgrowth algorithm
fpgrowth_output = fim.fpgrowth(
tracts=transactions,
target=target,
supp=-min_c,
min=min_z,
max=max_z,
report='a',
algo='s')
if np.unique(transactions, return_counts=True)[1][0] == len(
transactions):
fpgrowth_output = [(tuple(transactions[0]), len(transactions))]
else:
fpgrowth_output = fim.fpgrowth(
tracts=transactions,
target=target,
supp=-min_c,
zmin=min_z,
zmax=max_z,
report='a',
algo='s')
# Applying min/max conditions and computing extent (window positions)
fpgrowth_output = list(filter(
lambda c: _fpgrowth_filter(
Expand All @@ -665,16 +682,6 @@ def _fpgrowth(transactions, min_c=2, min_z=2, max_z=None,
return spectrum
else:
return concepts
elif report == '#' and min_neu == 1:
spectrum = fim.fpgrowth(
tracts=transactions,
target=target,
supp=-min_c,
min=min_z,
max=max_z,
report=report,
algo='s')
return spectrum
else:
raise AttributeError('min_neu must be an integer >=1')

Expand All @@ -687,7 +694,7 @@ def _fpgrowth_filter(concept, winlen, max_c, min_neu):
keep_concepts = len(
np.unique(
np.array(
concept[0]) // winlen)) >= min_neu and concept[1][0] <= max_c
concept[0]) // winlen)) >= min_neu and concept[1] <= max_c
return keep_concepts


Expand Down
9 changes: 4 additions & 5 deletions elephant/test/test_spade.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@
"""
from __future__ import division
import unittest
import os
import warnings

import neo
import numpy as np
from numpy.testing.utils import assert_array_almost_equal, assert_array_equal
from numpy.testing.utils import assert_array_equal
import quantities as pq
import elephant.spike_train_generation as stg
import elephant.spade as spade
import elephant.conversion as conv
import elephant.spike_train_generation as stg

try:
import fim
from elephant.spade_src import fim
HAVE_FIM = True
except ImportError:
HAVE_FIM = False


class SpadeTestCase(unittest.TestCase):
def setUp(self):
# Spade parameters
Expand Down

0 comments on commit dbfdde1

Please sign in to comment.