From 4152d504b3d576836dca44041a0057f1ede7301c Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Wed, 3 Apr 2013 14:44:35 -0400 Subject: added readme --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index b6b4d42..e2222a7 100644 --- a/README.markdown +++ b/README.markdown @@ -1,5 +1,5 @@ # PyFeast -Python bindings to the FEAST Feature Selection Toolbox. +Python bindings to the FEAST Feature Selection Toolbox.. ## About PyFeast PyFeast is a interface for the FEAST feature selection toolbox, which was -- cgit v1.2.3 From 918a14ff6e9adec5bfd279e43de2a027eefdfd4f Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Tue, 10 Jun 2014 16:06:09 -0400 Subject: updated MIM, and selected_feature outputs --- feast.py | 139 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 54 insertions(+), 85 deletions(-) diff --git a/feast.py b/feast.py index 5c3c3ee..3d53245 100644 --- a/feast.py +++ b/feast.py @@ -1,4 +1,4 @@ -''' +""" The FEAST module provides an interface between the C-library for feature selection to Python. @@ -8,7 +8,7 @@ theoretic feature selection," Journal of Machine Learning Research, vol. 13, pp. 27-66, 2012. -''' +""" __author__ = "Calvin Morrison" __copyright__ = "Copyright 2013, EESI Laboratory" __credits__ = ["Calvin Morrison", "Gregory Ditzler"] @@ -28,7 +28,7 @@ except: def BetaGamma(data, labels, n_select, beta=1.0, gamma=1.0): - ''' + """ This algorithm implements conditional mutual information feature select, such that beta and gamma control the weight attached to the redundant mutual and conditional @@ -52,7 +52,7 @@ def BetaGamma(data, labels, n_select, beta=1.0, gamma=1.0): @type gamma: float between 0 and 1.0 @return: features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -77,20 +77,14 @@ def BetaGamma(data, labels, n_select, beta=1.0, gamma=1.0): c_gamma ) - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) - + selected_features.append(i) return selected_features - def CIFE(data, labels, n_select): - ''' + """ This function implements the Condred feature selection algorithm. beta = 1; gamma = 1; @@ -105,15 +99,11 @@ def CIFE(data, labels, n_select): @type n_select: integer @return selected_features: features in the order they were selected. @rtype: list - ''' - + """ return BetaGamma(data, labels, n_select, beta=1.0, gamma=1.0) - - - def CMIM(data, labels, n_select): - ''' + """ This function implements the conditional mutual information maximization feature selection algorithm. Note that this implementation does not allow for the weighting of the @@ -130,7 +120,7 @@ def CMIM(data, labels, n_select): @type n_select: integer @return: features in the order that they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -151,21 +141,16 @@ def CMIM(data, labels, n_select): output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) + selected_features.append(i) return selected_features def CondMI(data, labels, n_select): - ''' + """ This function implements the conditional mutual information maximization feature selection algorithm. @@ -180,7 +165,7 @@ def CondMI(data, labels, n_select): @type n_select: integer @return: features in the order they were selected. @rtype list - ''' + """ data, labels = check_data(data, labels) # python values @@ -200,21 +185,16 @@ def CondMI(data, labels, n_select): labels.ctypes.data_as(c.POINTER(c.c_double)), output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) + selected_features.append(i) return selected_features def Condred(data, labels, n_select): - ''' + """ This function implements the Condred feature selection algorithm. beta = 0; gamma = 1; @@ -229,15 +209,14 @@ def Condred(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) - return BetaGamma(data, labels, n_select, beta=0.0, gamma=1.0) def DISR(data, labels, n_select): - ''' + """ This function implements the double input symmetrical relevance feature selection algorithm. @@ -252,7 +231,7 @@ def DISR(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -272,23 +251,15 @@ def DISR(data, labels, n_select): labels.ctypes.data_as(c.POINTER(c.c_double)), output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) + selected_features.append(i) return selected_features - - - def ICAP(data, labels, n_select): - ''' + """ This function implements the interaction capping feature selection algorithm. @@ -303,7 +274,7 @@ def ICAP(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -323,24 +294,15 @@ def ICAP(data, labels, n_select): labels.ctypes.data_as(c.POINTER(c.c_double)), output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) + selected_features.append(i) return selected_features - - - - def JMI(data, labels, n_select): - ''' + """ This function implements the joint mutual information feature selection algorithm. @@ -355,7 +317,7 @@ def JMI(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -376,21 +338,15 @@ def JMI(data, labels, n_select): output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) - + selected_features.append(i) return selected_features def MIFS(data, labels, n_select): - ''' + """ This function implements the MIFS algorithm. beta = 1; gamma = 0; @@ -405,13 +361,12 @@ def MIFS(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' - + """ return BetaGamma(data, labels, n_select, beta=0.0, gamma=0.0) def MIM(data, labels, n_select): - ''' + """ This function implements the MIM algorithm. beta = 0; gamma = 0; @@ -426,15 +381,35 @@ def MIM(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) + + # python values + n_observations, n_features = data.shape + output = np.zeros(n_select) - return BetaGamma(data, labels, n_select, beta=0.0, gamma=0.0) + # cast as C types + c_n_observations = c.c_int(n_observations) + c_n_select = c.c_int(n_select) + c_n_features = c.c_int(n_features) + libFSToolbox.MIM.restype = c.POINTER(c.c_double * n_select) + features = libFSToolbox.MIM(c_n_select, + c_n_observations, + c_n_features, + data.ctypes.data_as(c.POINTER(c.c_double)), + labels.ctypes.data_as(c.POINTER(c.c_double)), + output.ctypes.data_as(c.POINTER(c.c_double)) + ) + + selected_features = [] + for i in features.contents: + selected_features.append(i) + return selected_features def mRMR(data, labels, n_select): - ''' + """ This funciton implements the max-relevance min-redundancy feature selection algorithm. @@ -449,7 +424,7 @@ def mRMR(data, labels, n_select): @type n_select: integer @return: the features in the order they were selected. @rtype: list - ''' + """ data, labels = check_data(data, labels) # python values @@ -470,19 +445,13 @@ def mRMR(data, labels, n_select): output.ctypes.data_as(c.POINTER(c.c_double)) ) - - # turn our output into a list selected_features = [] for i in features.contents: - # recall that feast was implemented with Matlab in mind, so the - # authors assumed the indexing started a one; however, in Python - # the indexing starts at zero. - selected_features.append(i - 1) - + selected_features.append(i) return selected_features def check_data(data, labels): - ''' + """ Check dimensions of the data and the labels. Raise and exception if there is a problem. @@ -493,7 +462,7 @@ def check_data(data, labels): @param labels: the labels @return (data, labels): ndarray of floats @rtype: tuple - ''' + """ if isinstance(data, np.ndarray) is False: raise Exception("data must be an numpy ndarray.") -- cgit v1.2.3 From b06c71421fc6d90581b6e6f5369c9db4f1840b36 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Tue, 10 Jun 2014 17:11:56 -0400 Subject: added instructions for making sure MIM is compiled --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 86aa0f2..f9f128a 100644 --- a/README.markdown +++ b/README.markdown @@ -19,8 +19,8 @@ In order to use the feast module, you will need the following dependencies * Python 2.7 * Numpy * Linux or OS X -* [FEAST](https://github.com/Craigacp/FEAST) * [MIToolbox](https://github.com/Craigacp/MIToolbox) +* [FEAST](https://github.com/Craigacp/FEAST) - Make sure that `MIM.o` is compilde in the `Makefile`. ## Installation -- cgit v1.2.3 From a658df724eb5e26f030be36a2035b6c2be0e2c87 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Tue, 10 Jun 2014 17:40:47 -0400 Subject: added MIM test --- test/test.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/test.py b/test/test.py index b5e16d1..caa3874 100644 --- a/test/test.py +++ b/test/test.py @@ -66,7 +66,7 @@ elif data_source == 'digits': n_observations = len(data) # number of samples in the data set n_features = len(data.transpose()) # number of features in the data set n_select = 15 # how many features to select -method = 'JMI' # feature selection algorithm +method = 'MIM' # feature selection algorithm print '---> Information' @@ -147,6 +147,16 @@ if check_result(sf, n_relevant) == True: else: print ' mRMR failed!' +################################################################# +################################################################# +print ' Running MIM...' +sf = MIM(data, labels, n_select) +if check_result(sf, n_relevant) == True: + print ' MIM passed!' +else: + print ' MIM failed!' + +p print '---> Done unit tests!' -- cgit v1.2.3 From 2e399a6e9cc60b6dc9e3758e7428e433a9c35b91 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Tue, 10 Jun 2014 18:20:40 -0400 Subject: fixed type --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f9f128a..c6e268c 100644 --- a/README.markdown +++ b/README.markdown @@ -20,7 +20,7 @@ In order to use the feast module, you will need the following dependencies * Numpy * Linux or OS X * [MIToolbox](https://github.com/Craigacp/MIToolbox) -* [FEAST](https://github.com/Craigacp/FEAST) - Make sure that `MIM.o` is compilde in the `Makefile`. +* [FEAST](https://github.com/Craigacp/FEAST) - Make sure that `MIM.o` is compiled in the `Makefile`. ## Installation -- cgit v1.2.3 From 8d5a2d3ce1763e25eeb36af082a66efd1dfc061f Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Thu, 12 Jun 2014 11:45:35 -0400 Subject: Change comment for MIM let users know they need above v1.1.1 instead of forcing them to compile MIM.o --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index c6e268c..bdc8c37 100644 --- a/README.markdown +++ b/README.markdown @@ -20,7 +20,7 @@ In order to use the feast module, you will need the following dependencies * Numpy * Linux or OS X * [MIToolbox](https://github.com/Craigacp/MIToolbox) -* [FEAST](https://github.com/Craigacp/FEAST) - Make sure that `MIM.o` is compiled in the `Makefile`. +* [FEAST](https://github.com/Craigacp/FEAST) v1.1.1 or higher ## Installation -- cgit v1.2.3 From a97f22845bf13c8954b991b2fafd30b02e94752d Mon Sep 17 00:00:00 2001 From: Calvin Date: Thu, 9 Oct 2014 16:18:11 -0400 Subject: let CDLL raise its own errors --- feast.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/feast.py b/feast.py index 3d53245..06b6782 100644 --- a/feast.py +++ b/feast.py @@ -21,11 +21,7 @@ __status__ = "Release" import numpy as np import ctypes as c -try: - libFSToolbox = c.CDLL("libFSToolbox.so"); -except: - raise Exception("Error: could not load libFSToolbox.so") - +libFSToolbox = c.CDLL("libFSToolbox.so"); def BetaGamma(data, labels, n_select, beta=1.0, gamma=1.0): """ -- cgit v1.2.3 From 3312d31b3b3bfbd17db8d4ec88222bd9b667c7ef Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Mon, 13 Oct 2014 06:13:40 -0400 Subject: fixed digit demo --- test/test.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/test.py b/test/test.py index caa3874..7baf1f5 100644 --- a/test/test.py +++ b/test/test.py @@ -25,7 +25,7 @@ def read_digits(fname='digit.txt'): data = [] for line in fw: data.append( [float(x) for x in line] ) - data = np.array(data) + data = np.array(data, order="F") labels = data[:,len(data.transpose())-1] data = data[:,:len(data.transpose())-1] return data, labels @@ -47,7 +47,6 @@ def uniform_data(n_observations = 1000, n_features = 50, n_relevant = 5): else: labels[m] = 2 data = data.transpose() - return data, labels @@ -86,7 +85,7 @@ if check_result(sf, n_relevant) == True: print ' BetaGamma passed!' else: print ' BetaGamma failed!' - +print sf ################################################################# ################################################################# @@ -156,7 +155,6 @@ if check_result(sf, n_relevant) == True: else: print ' MIM failed!' -p print '---> Done unit tests!' -- cgit v1.2.3 From dc90a9f24710f9bfcec2fa7cdb291c0de8ed3992 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Mon, 13 Oct 2014 06:14:08 -0400 Subject: removed debug print --- test/test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test.py b/test/test.py index 7baf1f5..7b90b3b 100644 --- a/test/test.py +++ b/test/test.py @@ -85,7 +85,6 @@ if check_result(sf, n_relevant) == True: print ' BetaGamma passed!' else: print ' BetaGamma failed!' -print sf ################################################################# ################################################################# -- cgit v1.2.3 From a38c40a2c63a011f0c53599489a723a874a0ebf0 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Mon, 13 Oct 2014 08:09:41 -0400 Subject: updated readme --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 4464794..2004fb8 100644 --- a/README.markdown +++ b/README.markdown @@ -33,7 +33,7 @@ In order to use the feast module, you will need the following dependencies ## Demonstration See test/test.py for an example with uniform data and an image data set. The image data set was collected from the digits example in -the Scikits-Learn toolbox. +the Scikits-Learn toolbox. Make sure that if you are loading the data from a file and converting the data to a `numpy` array that you set `order="F"`. This is *very* important. ## Documentation We have documentation for each of the functions available [here](http://mutantturkey.github.com/PyFeast/feast-module.html) -- cgit v1.2.3 From 719281d5f02872ad83bf1a6f206e10622a383976 Mon Sep 17 00:00:00 2001 From: Gregory Ditzler Date: Mon, 20 Oct 2014 04:13:30 -0700 Subject: force col major --- feast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feast.py b/feast.py index 06b6782..ca8ce4a 100644 --- a/feast.py +++ b/feast.py @@ -467,5 +467,5 @@ def check_data(data, labels): if len(data) != len(labels): raise Exception("data and labels must be the same length") - - return 1.0*data, 1.0*labels + + return 1.0*np.array(data, order="F"), 1.0*np.array(labels, order="F") -- cgit v1.2.3