mirror of
https://github.com/Doctorado-ML/mufs.git
synced 2025-08-17 16:45:53 +00:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
0fdd754050
|
|||
7035cc4edc
|
|||
edc8816041
|
|||
20db8c5745
|
|||
a9384685fe
|
|||
86aaf23dd9
|
|||
9395e8cc23
|
|||
5723da9535
|
|||
fb4ed468b0
|
|||
57334a0b74
|
|||
c47f69847e
|
|||
4532309309
|
|||
aa53e3dbc0
|
|||
2861e22c57
|
|||
e0acd6d239
|
|||
3d98a39d4b
|
|||
1a4de38328
|
|||
a9c40f1fb7
|
|||
81da48ec31
|
|||
2548ab8533
|
|||
08cade5dec
|
|||
0a13f5e5eb
|
|||
a0f172ac13
|
|||
|
cfb37d2f6c | ||
5d1720c9ae
|
|||
1c5f1977e5
|
|||
27f8a370c5
|
|||
|
9d74bc8a70 |
39
.github/workflows/main.yml
vendored
39
.github/workflows/main.yml
vendored
@@ -12,11 +12,13 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
python: [3.8]
|
python: ["3.10"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- name: Set up Python ${{ matrix.python }}
|
- name: Set up Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
@@ -26,14 +28,37 @@ jobs:
|
|||||||
pip install -q --upgrade pip
|
pip install -q --upgrade pip
|
||||||
pip install -q cython
|
pip install -q cython
|
||||||
pip install -q numpy
|
pip install -q numpy
|
||||||
pip install -q git+git://github.com/doctorado-ml/mdlp
|
pip install -q git+https://github.com/doctorado-ml/mdlp
|
||||||
pip install -q -r requirements.txt
|
pip install -q -r requirements/dev.txt
|
||||||
pip install -q --upgrade codecov coverage black flake8 codacy-coverage
|
pip install -q --upgrade codecov coverage black flake8 codacy-coverage unittest-xml-reporting
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: |
|
run: |
|
||||||
black --check --diff mufs
|
black --check --diff mufs
|
||||||
flake8 --count mufs
|
flake8 --count mufs
|
||||||
- name: Tests & coverage
|
- name: Tests & coverage
|
||||||
run: |
|
run: |
|
||||||
coverage run -m unittest -v mufs.tests
|
mkdir .report
|
||||||
|
coverage run -m xmlrunner -v mufs.tests -o .report
|
||||||
|
coverage xml -i -o .report/coverage.xml
|
||||||
coverage report -m --fail-under=100
|
coverage report -m --fail-under=100
|
||||||
|
- name: Get project version
|
||||||
|
run: echo "project_version=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
|
||||||
|
- name: Override Coverage Source Path for Sonar
|
||||||
|
run: sed -i 's/\/home\/runner\/work\/mufs\/mufs\//\/github\/workspace\//g' .report/coverage.xml
|
||||||
|
- name: SonarQube scanner
|
||||||
|
uses: sonarsource/sonarqube-scan-action@master
|
||||||
|
env:
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
|
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||||
|
with:
|
||||||
|
args: >
|
||||||
|
-Dsonar.projectVersion=${{ env.project_version }}
|
||||||
|
-Dsonar.python.coverage.reportPaths=.report/coverage.xml
|
||||||
|
-Dsonar.python.xunit.reportPath=.report/TEST*
|
||||||
|
# If you wish to fail your job when the Quality Gate is red, uncomment the
|
||||||
|
# following lines. This would typically be used to fail a deployment.
|
||||||
|
- name: Quality Gate
|
||||||
|
uses: sonarsource/sonarqube-quality-gate-action@master
|
||||||
|
timeout-minutes: 5
|
||||||
|
env:
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/ambv/black
|
- repo: https://github.com/ambv/black
|
||||||
rev: 20.8b1
|
rev: 22.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
exclude: ".virtual_documents"
|
exclude: ".virtual_documents"
|
||||||
language_version: python3.8
|
language_version: python3.8
|
||||||
- repo: https://gitlab.com/pycqa/flake8
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
rev: 3.8.4
|
rev: 3.9.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
exclude: ".virtual_documents"
|
exclude: ".virtual_documents"
|
||||||
@@ -16,7 +16,7 @@ repos:
|
|||||||
# - id: mypy
|
# - id: mypy
|
||||||
# # args: [--strict, --ignore-missing-imports]
|
# # args: [--strict, --ignore-missing-imports]
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v3.4.0
|
rev: v4.2.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
|
5
Makefile
5
Makefile
@@ -1,6 +1,6 @@
|
|||||||
SHELL := /bin/bash
|
SHELL := /bin/bash
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
.PHONY: coverage deps help lint push test doc build
|
.PHONY: coverage deps help lint push test build
|
||||||
|
|
||||||
coverage: ## Run tests with coverage
|
coverage: ## Run tests with coverage
|
||||||
coverage erase
|
coverage erase
|
||||||
@@ -26,9 +26,6 @@ build: ## Build package
|
|||||||
rm -fr build/*
|
rm -fr build/*
|
||||||
python setup.py sdist bdist_wheel
|
python setup.py sdist bdist_wheel
|
||||||
|
|
||||||
doc-clean: ## Update documentation
|
|
||||||
make -C docs --makefile=Makefile clean
|
|
||||||
|
|
||||||
help: ## Show help message
|
help: ## Show help message
|
||||||
@IFS=$$'\n' ; \
|
@IFS=$$'\n' ; \
|
||||||
help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \
|
help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||

|

|
||||||
[](https://www.codacy.com/gh/Doctorado-ML/mufs/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Doctorado-ML/mufs&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/gh/Doctorado-ML/mufs/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Doctorado-ML/mufs&utm_campaign=Badge_Grade)
|
||||||
[](https://lgtm.com/projects/g/Doctorado-ML/mufs/context:python)
|
[](https://lgtm.com/projects/g/Doctorado-ML/mufs/context:python)
|
||||||
|
[](https://badge.fury.io/py/MUFS)
|
||||||
|
[](https://haystack.rmontanana.es:25000/dashboard?id=mufs)
|
||||||
|
[](https://haystack.rmontanana.es:25000/dashboard?id=mufs)
|
||||||
|

|
||||||
|
|
||||||
# MUFS
|
# MUFS
|
||||||
|
|
||||||
@@ -15,3 +19,7 @@ Proceedings, Twentieth International Conference on Machine Learning. ed. / T. Fa
|
|||||||
### Correlation-based Feature Selection
|
### Correlation-based Feature Selection
|
||||||
|
|
||||||
Hall, M. A. (1999), 'Correlation-based Feature Selection for Machine Learning'.
|
Hall, M. A. (1999), 'Correlation-based Feature Selection for Machine Learning'.
|
||||||
|
|
||||||
|
### IWSS
|
||||||
|
|
||||||
|
Based on: P. Bermejo, J. A. Gamez and J. M. Puerta, "Incremental Wrapper-based subset Selection with replacement: An advantageous alternative to sequential forward selection," 2009 IEEE Symposium on Computational Intelligence and Data Mining, 2009, pp. 367-374, doi: 10.1109/CIDM.2009.4938673.
|
||||||
|
@@ -3,6 +3,7 @@ from sys import float_info
|
|||||||
from itertools import combinations
|
from itertools import combinations
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from .Metrics import Metrics
|
from .Metrics import Metrics
|
||||||
|
from ._version import __version__
|
||||||
|
|
||||||
|
|
||||||
class MUFS:
|
class MUFS:
|
||||||
@@ -26,7 +27,7 @@ class MUFS:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, max_features=None, discrete=True):
|
def __init__(self, max_features=None, discrete=True):
|
||||||
self._max_features = max_features
|
self.max_features = max_features
|
||||||
self._discrete = discrete
|
self._discrete = discrete
|
||||||
self.symmetrical_uncertainty = (
|
self.symmetrical_uncertainty = (
|
||||||
Metrics.symmetrical_uncertainty
|
Metrics.symmetrical_uncertainty
|
||||||
@@ -40,6 +41,11 @@ class MUFS:
|
|||||||
)
|
)
|
||||||
self._fitted = False
|
self._fitted = False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def version() -> str:
|
||||||
|
"""Return the version of the package."""
|
||||||
|
return __version__
|
||||||
|
|
||||||
def _initialize(self, X, y):
|
def _initialize(self, X, y):
|
||||||
"""Initialize the attributes so support multiple calls using same
|
"""Initialize the attributes so support multiple calls using same
|
||||||
object
|
object
|
||||||
@@ -53,8 +59,10 @@ class MUFS:
|
|||||||
"""
|
"""
|
||||||
self.X_ = X
|
self.X_ = X
|
||||||
self.y_ = y
|
self.y_ = y
|
||||||
if self._max_features is None:
|
if self.max_features is None:
|
||||||
self._max_features = X.shape[1]
|
self._max_features = X.shape[1]
|
||||||
|
else:
|
||||||
|
self._max_features = self.max_features
|
||||||
self._result = None
|
self._result = None
|
||||||
self._scores = []
|
self._scores = []
|
||||||
self._su_labels = None
|
self._su_labels = None
|
||||||
@@ -105,7 +113,9 @@ class MUFS:
|
|||||||
|
|
||||||
def _compute_merit(self, features):
|
def _compute_merit(self, features):
|
||||||
"""Compute the merit function for cfs algorithms
|
"""Compute the merit function for cfs algorithms
|
||||||
|
"Good feature subsets contain features highly correlated with
|
||||||
|
(predictive of) the class, yet uncorrelated with (not predictive of)
|
||||||
|
each other"
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
features : list
|
features : list
|
||||||
@@ -124,7 +134,7 @@ class MUFS:
|
|||||||
k = len(features)
|
k = len(features)
|
||||||
for pair in list(combinations(features, 2)):
|
for pair in list(combinations(features, 2)):
|
||||||
rff += self._compute_su_features(*pair)
|
rff += self._compute_su_features(*pair)
|
||||||
return rcf / sqrt(k + (k ** 2 - k) * rff)
|
return rcf / sqrt(k + (k**2 - k) * rff)
|
||||||
|
|
||||||
def cfs(self, X, y):
|
def cfs(self, X, y):
|
||||||
"""Correlation-based Feature Selection
|
"""Correlation-based Feature Selection
|
||||||
@@ -162,6 +172,10 @@ class MUFS:
|
|||||||
id_selected = idx
|
id_selected = idx
|
||||||
merit = merit_new
|
merit = merit_new
|
||||||
candidates.pop()
|
candidates.pop()
|
||||||
|
if id_selected is None:
|
||||||
|
# No more features to add all merits are nan because of
|
||||||
|
# constant features
|
||||||
|
break
|
||||||
candidates.append(feature_order[id_selected])
|
candidates.append(feature_order[id_selected])
|
||||||
self._scores.append(merit)
|
self._scores.append(merit)
|
||||||
del feature_order[id_selected]
|
del feature_order[id_selected]
|
||||||
@@ -264,3 +278,58 @@ class MUFS:
|
|||||||
list of scores of the features selected
|
list of scores of the features selected
|
||||||
"""
|
"""
|
||||||
return self._scores if self._fitted else []
|
return self._scores if self._fitted else []
|
||||||
|
|
||||||
|
def iwss(self, X, y, threshold):
|
||||||
|
"""Incremental Wrapper Subset Selection
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
X : np.array
|
||||||
|
array of features
|
||||||
|
y : np.array
|
||||||
|
vector of labels
|
||||||
|
threshold : float
|
||||||
|
threshold to select relevant features
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
self
|
||||||
|
self
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
ValueError
|
||||||
|
if the threshold is less than a selected value of 1e-7
|
||||||
|
or greater than .5
|
||||||
|
|
||||||
|
"""
|
||||||
|
if threshold < 0 or threshold > 0.5:
|
||||||
|
raise ValueError(
|
||||||
|
"Threshold cannot be less than 0 or greater than 0.5"
|
||||||
|
)
|
||||||
|
self._initialize(X, y)
|
||||||
|
s_list = self._compute_su_labels()
|
||||||
|
feature_order = (-s_list).argsort()
|
||||||
|
features = feature_order.copy().tolist()
|
||||||
|
candidates = []
|
||||||
|
# Add first and second features to result
|
||||||
|
first_feature = features.pop(0)
|
||||||
|
candidates.append(first_feature)
|
||||||
|
self._scores.append(s_list[first_feature])
|
||||||
|
candidates.append(features.pop(0))
|
||||||
|
merit = self._compute_merit(candidates)
|
||||||
|
self._scores.append(merit)
|
||||||
|
for feature in features:
|
||||||
|
candidates.append(feature)
|
||||||
|
merit_new = self._compute_merit(candidates)
|
||||||
|
delta = abs(merit - merit_new) / merit if merit != 0.0 else 0.0
|
||||||
|
if merit_new > merit or delta < threshold:
|
||||||
|
if merit_new > merit:
|
||||||
|
merit = merit_new
|
||||||
|
self._scores.append(merit_new)
|
||||||
|
else:
|
||||||
|
candidates.pop()
|
||||||
|
break
|
||||||
|
if len(candidates) == self._max_features:
|
||||||
|
break
|
||||||
|
self._result = candidates
|
||||||
|
return self
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
from .Selection import MUFS
|
from .Selection import MUFS
|
||||||
|
|
||||||
__version__ = "0.1.1"
|
|
||||||
__author__ = "Ricardo Montañana Gómez"
|
__author__ = "Ricardo Montañana Gómez"
|
||||||
__author_email__ = "Ricardo.Montanana@alu.uclm.es"
|
__author_email__ = "Ricardo.Montanana@alu.uclm.es"
|
||||||
__copyright__ = "Copyright 2021, Ricardo Montañana Gómez"
|
__copyright__ = "Copyright 2021-2022, Ricardo Montañana Gómez"
|
||||||
__license__ = "MIT License"
|
__license__ = "MIT License"
|
||||||
|
|
||||||
__all__ = ["MUFS"]
|
__all__ = ["MUFS"]
|
||||||
|
1
mufs/_version.py
Normal file
1
mufs/_version.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
__version__ = "0.1.3"
|
@@ -1,11 +1,14 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
from mdlp import MDLP
|
from mdlp import MDLP
|
||||||
from sklearn.datasets import load_wine, load_iris
|
from sklearn.datasets import load_wine, load_iris
|
||||||
|
|
||||||
from ..Selection import MUFS
|
from ..Selection import MUFS
|
||||||
|
from .._version import __version__
|
||||||
|
|
||||||
|
|
||||||
class MUFS_test(unittest.TestCase):
|
class MUFSTest(unittest.TestCase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
mdlp = MDLP(random_state=1)
|
mdlp = MDLP(random_state=1)
|
||||||
@@ -15,6 +18,11 @@ class MUFS_test(unittest.TestCase):
|
|||||||
mdlp = MDLP(random_state=1)
|
mdlp = MDLP(random_state=1)
|
||||||
self.X_i = mdlp.fit_transform(self.X_ic, self.y_i).astype("int64")
|
self.X_i = mdlp.fit_transform(self.X_ic, self.y_i).astype("int64")
|
||||||
|
|
||||||
|
def test_version(self):
|
||||||
|
"""Check package version."""
|
||||||
|
mufs = MUFS()
|
||||||
|
self.assertEqual(__version__, mufs.version())
|
||||||
|
|
||||||
def assertListAlmostEqual(self, list1, list2, tol=7):
|
def assertListAlmostEqual(self, list1, list2, tol=7):
|
||||||
self.assertEqual(len(list1), len(list2))
|
self.assertEqual(len(list1), len(list2))
|
||||||
for a, b in zip(list1, list2):
|
for a, b in zip(list1, list2):
|
||||||
@@ -32,7 +40,7 @@ class MUFS_test(unittest.TestCase):
|
|||||||
def test_csf_wine(self):
|
def test_csf_wine(self):
|
||||||
mufs = MUFS()
|
mufs = MUFS()
|
||||||
expected = [6, 12, 9, 4, 10, 0]
|
expected = [6, 12, 9, 4, 10, 0]
|
||||||
self.assertListAlmostEqual(
|
self.assertListEqual(
|
||||||
expected, mufs.cfs(self.X_w, self.y_w).get_results()
|
expected, mufs.cfs(self.X_w, self.y_w).get_results()
|
||||||
)
|
)
|
||||||
expected = [
|
expected = [
|
||||||
@@ -78,7 +86,7 @@ class MUFS_test(unittest.TestCase):
|
|||||||
mufs = MUFS()
|
mufs = MUFS()
|
||||||
expected = [3, 2, 0, 1]
|
expected = [3, 2, 0, 1]
|
||||||
computed = mufs.cfs(self.X_i, self.y_i).get_results()
|
computed = mufs.cfs(self.X_i, self.y_i).get_results()
|
||||||
self.assertListAlmostEqual(expected, computed)
|
self.assertListEqual(expected, computed)
|
||||||
expected = [
|
expected = [
|
||||||
0.870521418179061,
|
0.870521418179061,
|
||||||
0.8968651482682227,
|
0.8968651482682227,
|
||||||
@@ -148,3 +156,46 @@ class MUFS_test(unittest.TestCase):
|
|||||||
0.44518278979085646,
|
0.44518278979085646,
|
||||||
]
|
]
|
||||||
self.assertListAlmostEqual(expected, mufs.get_scores())
|
self.assertListAlmostEqual(expected, mufs.get_scores())
|
||||||
|
|
||||||
|
def test_iwss_wine(self):
|
||||||
|
mufs = MUFS()
|
||||||
|
expected = [6, 9, 12]
|
||||||
|
self.assertListEqual(
|
||||||
|
expected, mufs.iwss(self.X_w, self.y_w, 0.2).get_results()
|
||||||
|
)
|
||||||
|
expected = [0.5218299405215557, 0.5947822876110085, 0.4877384978817362]
|
||||||
|
self.assertListAlmostEqual(expected, mufs.get_scores())
|
||||||
|
|
||||||
|
def test_iwss_wine_max_features(self):
|
||||||
|
mufs = MUFS(max_features=3)
|
||||||
|
expected = [6, 9, 12]
|
||||||
|
self.assertListEqual(
|
||||||
|
expected, mufs.iwss(self.X_w, self.y_w, 0.4).get_results()
|
||||||
|
)
|
||||||
|
expected = [0.5218299405215557, 0.5947822876110085, 0.4877384978817362]
|
||||||
|
self.assertListAlmostEqual(expected, mufs.get_scores())
|
||||||
|
|
||||||
|
def test_iwss_exception(self):
|
||||||
|
mufs = MUFS()
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
mufs.iwss(self.X_w, self.y_w, 0.51)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
mufs.iwss(self.X_w, self.y_w, -0.01)
|
||||||
|
|
||||||
|
def test_iwss_better_merit_condition(self):
|
||||||
|
folder = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
data = pd.read_csv(
|
||||||
|
os.path.join(folder, "balloons_R.dat"),
|
||||||
|
sep="\t",
|
||||||
|
index_col=0,
|
||||||
|
)
|
||||||
|
X = data.drop("clase", axis=1).to_numpy()
|
||||||
|
y = data["clase"].to_numpy()
|
||||||
|
mufs = MUFS()
|
||||||
|
expected = [0, 2, 3, 1]
|
||||||
|
self.assertListEqual(expected, mufs.iwss(X, y, 0.3).get_results())
|
||||||
|
|
||||||
|
def test_iwss_empty(self):
|
||||||
|
mufs = MUFS()
|
||||||
|
X = np.delete(self.X_i, [0, 1], 1)
|
||||||
|
self.assertListEqual(mufs.iwss(X, self.y_i, 0.3).get_results(), [1, 0])
|
||||||
|
@@ -6,7 +6,7 @@ from mdlp import MDLP
|
|||||||
from ..Selection import Metrics
|
from ..Selection import Metrics
|
||||||
|
|
||||||
|
|
||||||
class Metrics_test(unittest.TestCase):
|
class MetricsTest(unittest.TestCase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
mdlp = MDLP(random_state=1)
|
mdlp = MDLP(random_state=1)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from .MUFS_test import MUFS_test
|
from .MUFS_test import MUFSTest
|
||||||
from .Metrics_test import Metrics_test
|
from .Metrics_test import MetricsTest
|
||||||
|
|
||||||
__all__ = ["MUFS_test", "Metrics_test"]
|
__all__ = ["MUFSTest", "MetricsTest"]
|
||||||
|
17
mufs/tests/balloons_R.dat
Executable file
17
mufs/tests/balloons_R.dat
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
f1 f2 f3 f4 clase
|
||||||
|
1 0.968246 -0.968246 0.968246 0.968246 1
|
||||||
|
2 0.968246 -0.968246 0.968246 -0.968246 1
|
||||||
|
3 0.968246 -0.968246 -0.968246 0.968246 1
|
||||||
|
4 0.968246 -0.968246 -0.968246 -0.968246 1
|
||||||
|
5 0.968246 0.968246 0.968246 0.968246 1
|
||||||
|
6 0.968246 0.968246 0.968246 -0.968246 0
|
||||||
|
7 0.968246 0.968246 -0.968246 0.968246 0
|
||||||
|
8 0.968246 0.968246 -0.968246 -0.968246 0
|
||||||
|
9 -0.968246 -0.968246 0.968246 0.968246 1
|
||||||
|
10 -0.968246 -0.968246 0.968246 -0.968246 0
|
||||||
|
11 -0.968246 -0.968246 -0.968246 0.968246 0
|
||||||
|
12 -0.968246 -0.968246 -0.968246 -0.968246 0
|
||||||
|
13 -0.968246 0.968246 0.968246 0.968246 1
|
||||||
|
14 -0.968246 0.968246 0.968246 -0.968246 0
|
||||||
|
15 -0.968246 0.968246 -0.968246 0.968246 0
|
||||||
|
16 -0.968246 0.968246 -0.968246 -0.968246 0
|
3
requirements/dev.txt
Normal file
3
requirements/dev.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-r production.txt
|
||||||
|
mdlp
|
||||||
|
pandas
|
@@ -1,2 +1 @@
|
|||||||
scikit-learn>0.24
|
scikit-learn>0.24
|
||||||
mdlp
|
|
21
sample.py
21
sample.py
@@ -1,4 +1,5 @@
|
|||||||
import warnings
|
import warnings
|
||||||
|
import time
|
||||||
from mufs import MUFS
|
from mufs import MUFS
|
||||||
from mufs.Metrics import Metrics
|
from mufs.Metrics import Metrics
|
||||||
from stree import Stree
|
from stree import Stree
|
||||||
@@ -26,16 +27,26 @@ for i in range(n):
|
|||||||
# Classification
|
# Classification
|
||||||
warnings.filterwarnings("ignore")
|
warnings.filterwarnings("ignore")
|
||||||
print("CFS")
|
print("CFS")
|
||||||
|
now = time.time()
|
||||||
cfs_f = mufsc.cfs(X, y).get_results()
|
cfs_f = mufsc.cfs(X, y).get_results()
|
||||||
print(cfs_f)
|
time_cfs = time.time() - now
|
||||||
|
print(cfs_f, "items: ", len(cfs_f), f"time: {time_cfs:.3f} seconds")
|
||||||
print("FCBF")
|
print("FCBF")
|
||||||
fcfb_f = mufsc.fcbf(X, y, 5e-2).get_results()
|
now = time.time()
|
||||||
print(fcfb_f, len(fcfb_f))
|
fcbf_f = mufsc.fcbf(X, y, 0.07).get_results()
|
||||||
|
time_fcbf = time.time() - now
|
||||||
|
print(fcbf_f, "items: ", len(fcbf_f), f"time: {time_fcbf:.3f} seconds")
|
||||||
|
now = time.time()
|
||||||
|
print("IWSS")
|
||||||
|
iwss_f = mufsc.iwss(X, y, 0.5).get_results()
|
||||||
|
time_iwss = time.time() - now
|
||||||
|
print(iwss_f, "items: ", len(iwss_f), f"time: {time_iwss:.3f} seconds")
|
||||||
print("X.shape=", X.shape)
|
print("X.shape=", X.shape)
|
||||||
clf = Stree(random_state=0)
|
clf = Stree(random_state=0)
|
||||||
print("Accuracy whole dataset", clf.fit(X, y).score(X, y))
|
print("Accuracy whole dataset", clf.fit(X, y).score(X, y))
|
||||||
clf = Stree(random_state=0)
|
clf = Stree(random_state=0)
|
||||||
print("Accuracy cfs", clf.fit(X[:, cfs_f], y).score(X[:, cfs_f], y))
|
print("Accuracy cfs", clf.fit(X[:, cfs_f], y).score(X[:, cfs_f], y))
|
||||||
clf = Stree(random_state=0)
|
clf = Stree(random_state=0)
|
||||||
subf = fcfb_f
|
print("Accuracy fcfb", clf.fit(X[:, fcbf_f], y).score(X[:, fcbf_f], y))
|
||||||
print("Accuracy fcfb", clf.fit(X[:, subf], y).score(X[:, subf], y))
|
clf = Stree(random_state=0)
|
||||||
|
print("Accuracy iwss", clf.fit(X[:, iwss_f], y).score(X[:, iwss_f], y))
|
||||||
|
15
setup.py
15
setup.py
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
import setuptools
|
import setuptools
|
||||||
|
|
||||||
|
|
||||||
@@ -6,9 +7,10 @@ def readme():
|
|||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
|
|
||||||
def get_data(field: str):
|
def get_data(field):
|
||||||
item = ""
|
item = ""
|
||||||
with open("mufs/__init__.py") as f:
|
file_name = "_version.py" if field == "version" else "__init__.py"
|
||||||
|
with open(os.path.join("mufs", file_name)) as f:
|
||||||
for line in f.readlines():
|
for line in f.readlines():
|
||||||
if line.startswith(f"__{field}__"):
|
if line.startswith(f"__{field}__"):
|
||||||
delim = '"' if '"' in line else "'"
|
delim = '"' if '"' in line else "'"
|
||||||
@@ -19,6 +21,11 @@ def get_data(field: str):
|
|||||||
return item
|
return item
|
||||||
|
|
||||||
|
|
||||||
|
def get_requirements():
|
||||||
|
with open("requirements/production.txt") as f:
|
||||||
|
return f.read().splitlines()
|
||||||
|
|
||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="MUFS",
|
name="MUFS",
|
||||||
version=get_data("version"),
|
version=get_data("version"),
|
||||||
@@ -38,11 +45,13 @@ setuptools.setup(
|
|||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 4 - Beta",
|
||||||
"License :: OSI Approved :: " + get_data("license"),
|
"License :: OSI Approved :: " + get_data("license"),
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
"Natural Language :: English",
|
"Natural Language :: English",
|
||||||
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
||||||
"Intended Audience :: Science/Research",
|
"Intended Audience :: Science/Research",
|
||||||
],
|
],
|
||||||
install_requires=["scikit-learn"],
|
install_requires=get_requirements(),
|
||||||
test_suite="mufs.tests",
|
test_suite="mufs.tests",
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
||||||
|
4
sonar-project.properties
Normal file
4
sonar-project.properties
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
sonar.projectKey=mufs
|
||||||
|
sonar.sourceEncoding=UTF-8
|
||||||
|
sonar.sources=.
|
||||||
|
sonar.python.version=3.8, 3.9, 3.10
|
Reference in New Issue
Block a user