From 922f44f0189877e769131fca117550c51e2ee545 Mon Sep 17 00:00:00 2001 From: Sebastian Raschka Date: Wed, 18 Oct 2017 22:32:59 -0400 Subject: [PATCH] add multiplexer function (#263) --- docs/mkdocs.yml | 1 + docs/sources/CHANGELOG.md | 1 + docs/sources/USER_GUIDE_INDEX.md | 1 + .../data/make_multiplexer_dataset.ipynb | 235 ++++++++++++++++++ .../6bit_multiplexer.pdf | Bin 0 -> 19379 bytes .../6bit_multiplexer.png | Bin 0 -> 49055 bytes mlxtend/data/__init__.py | 4 +- mlxtend/data/multiplexer.py | 110 ++++++++ .../tests/{test_data.py => test_datasets.py} | 8 + mlxtend/data/tests/test_multiplexer.py | 97 ++++++++ 10 files changed, 456 insertions(+), 1 deletion(-) create mode 100644 docs/sources/user_guide/data/make_multiplexer_dataset.ipynb create mode 100644 docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.pdf create mode 100644 docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.png create mode 100644 mlxtend/data/multiplexer.py rename mlxtend/data/tests/{test_data.py => test_datasets.py} (87%) create mode 100644 mlxtend/data/tests/test_multiplexer.py diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index f4aa77710..330fcf4c4 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -47,6 +47,7 @@ pages: - user_guide/data/boston_housing_data.md - user_guide/data/iris_data.md - user_guide/data/loadlocal_mnist.md + - user_guide/data/make_multiplexer_dataset.md - user_guide/data/mnist_data.md - user_guide/data/three_blobs_data.md - user_guide/data/wine_data.md diff --git a/docs/sources/CHANGELOG.md b/docs/sources/CHANGELOG.md index cb1170e95..b03c1f453 100755 --- a/docs/sources/CHANGELOG.md +++ b/docs/sources/CHANGELOG.md @@ -19,6 +19,7 @@ The CHANGELOG for the current development version is available at - Added `'leverage'` and `'conviction` as evaluation metrics to the `frequent_patterns.association_rules` function. [#246](https://github.com/rasbt/mlxtend/pull/246) & [#247](https://github.com/rasbt/mlxtend/pull/247) - Added a `loadings_` attribute to `PrincipalComponentAnalysis` to compute the factor loadings of the features on the principal components. [#251](https://github.com/rasbt/mlxtend/pull/251) - Allow grid search over classifiers/regressors in ensemble and stacking estimators [#259](https://github.com/rasbt/mlxtend/pull/259) +- New `make_multiplexer_dataset` function that creates a dataset generated by a n-bit Boolean multiplexer for evaluating supervised learning algorithms [#263](https://github.com/rasbt/mlxtend/pull/263) ##### Changes diff --git a/docs/sources/USER_GUIDE_INDEX.md b/docs/sources/USER_GUIDE_INDEX.md index bfc0fec50..8d856da67 100755 --- a/docs/sources/USER_GUIDE_INDEX.md +++ b/docs/sources/USER_GUIDE_INDEX.md @@ -18,6 +18,7 @@ - [boston_housing_data](user_guide/data/boston_housing_data.md) - [iris_data](user_guide/data/iris_data.md) - [loadlocal_mnist](user_guide/data/loadlocal_mnist.md) +- [make_multiplexer_dataset](user_guide/data/make_multiplexer_dataset.md) - [mnist_data](user_guide/data/mnist_data.md) - [three_blobs_data](user_guide/data/three_blobs_data.md) - [wine_data](user_guide/data/wine_data.md) diff --git a/docs/sources/user_guide/data/make_multiplexer_dataset.ipynb b/docs/sources/user_guide/data/make_multiplexer_dataset.ipynb new file mode 100644 index 000000000..929c10595 --- /dev/null +++ b/docs/sources/user_guide/data/make_multiplexer_dataset.ipynb @@ -0,0 +1,235 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Make Multiplexer Dataset" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Function that creates a dataset generated by a n-bit Boolean multiplexer for evaluating supervised learning algorithms." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> `from mlxtend.data import make_multiplexer_dataset` " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Overview" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `make_multiplexer_dataset` function creates a dataset generated by an n-bit Boolean multiplexer. Such dataset represents a dataset generated by a simple rule, based on the behavior of a electric multiplexer, yet presents a relatively challenging classification problem for supervised learning algorithm with interactions between features (epistasis) as it may be encountered in many real-world scenarios [1].\n", + "\n", + "The following illustration depicts a 6-bit multiplexer that consists of 2 address bits and 4 register bits. The address bits converted to decimal representation point to a position in the register bit. For example, if the address bits are \"00\" (0 in decimal), the address bits point to the register bit at position 0. The value of the register position pointed to determines the class label. For example, if the register bit at position is 0, the class label is 0. Vice versa, if the register bit at position 0 is 1, the class label is 1. \n", + "\n", + "![](make_multiplexer_dataset_data_files/6bit_multiplexer.png)\n", + "\n", + "\n", + "In the example above, the address bits \"10\" (2 in decimal) point to the 3rd register position (as we start counting from index 0), which has a bit value of 1. Hence, the class label is 1.\n", + "\n", + "Below are a few more examples:\n", + "\n", + "1. Address bits: [0, 1], register bits: [1, 0, 1, 1], class label: 0\n", + "2. Address bits: [0, 1], register bits: [1, 1, 1, 0], class label: 1\n", + "3. Address bits: [1, 0], register bits: [1, 0, 0, 1], class label: 0\n", + "4. Address bits: [1, 1], register bits: [1, 1, 1, 0], class label: 0\n", + "5. Address bits: [0, 1], register bits: [0, 1, 1, 0], class label: 1\n", + "6. Address bits: [0, 1], register bits: [1, 0, 0, 1], class label: 0\n", + "7. Address bits: [0, 1], register bits: [0, 1, 1, 1], class label: 1\n", + "8. Address bits: [0, 1], register bits: [0, 0, 0, 0], class label: 0\n", + "9. Address bits: [1, 0], register bits: [1, 0, 1, 1], class label: 1\n", + "10. Address bits: [0, 1], register bits: [1, 1, 1, 1], class label: 1\n", + "\n", + "Note that in the implementation of the multiplexer function, if the number of address bits is set to 2, this results in a 6 bit multiplexer as two bit can have 2^2=4 different register positions (2 bit + 4 bit = 6 bit). However, if we choose 3 address bits instead, 2^3=8 positions would be covered, resulting in a 11 bit (3 bit + 8 bit = 11 bit) multiplexer, and so forth.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### References\n", + "\n", + "- [1] Urbanowicz, R. J., & Browne, W. N. (2017). *Introduction to Learning Classifier Systems*. Springer." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 1 -- 6-bit multiplexer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This simple example illustrates how to create dataset from a 6-bit multiplexer" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Features:\n", + " [[0 1 0 1 0 1]\n", + " [1 0 0 0 1 1]\n", + " [0 1 1 1 0 0]\n", + " [0 1 1 1 0 0]\n", + " [0 0 1 1 0 0]\n", + " [0 1 0 0 0 0]\n", + " [0 1 1 0 1 1]\n", + " [1 0 1 0 0 0]\n", + " [1 0 0 1 0 1]\n", + " [1 0 1 0 0 1]]\n", + "\n", + "Class labels:\n", + " [1 1 1 1 1 0 0 0 0 0]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from mlxtend.data import make_multiplexer_dataset\n", + "\n", + "\n", + "X, y = make_multiplexer_dataset(address_bits=2, \n", + " sample_size=10,\n", + " positive_class_ratio=0.5, \n", + " shuffle=False,\n", + " random_seed=123)\n", + "\n", + "print('Features:\\n', X)\n", + "print('\\nClass labels:\\n', y)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## API" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "## make_multiplexer_dataset\n", + "\n", + "*make_multiplexer_dataset(address_bits=2, sample_size=100, positive_class_ratio=0.5, shuffle=False, random_seed=None)*\n", + "\n", + "Function to create a binary n-bit multiplexer dataset.\n", + "\n", + "New in mlxtend v0.9\n", + "\n", + "**Parameters**\n", + "\n", + "- `address_bits` : int (default: 2)\n", + "\n", + " A positive integer that determines the number of address\n", + " bits in the multiplexer, which in turn determine the\n", + " n-bit capacity of the multiplexer and therefore the\n", + " number of features. The number of features is determined by\n", + " the number of address bits. For example, 2 address bits\n", + " will result in a 6 bit multiplexer and consequently\n", + " 6 features (2 + 2^2 = 6). If `address_bits=3`, then\n", + " this results in an 11-bit multiplexer as (2 + 2^3 = 11)\n", + " with 11 features.\n", + "\n", + "\n", + "- `sample_size` : int (default: 100)\n", + "\n", + " The total number of samples generated.\n", + "\n", + "\n", + "- `positive_class_ratio` : float (default: 0.5)\n", + "\n", + " The fraction (a float between 0 and 1)\n", + " of samples in the `sample_size`d dataset\n", + " that have class label 1.\n", + " If `positive_class_ratio=0.5` (default), then\n", + " the ratio of class 0 and class 1 samples is perfectly balanced.\n", + "\n", + "\n", + "- `shuffle` : Bool (default: False)\n", + "\n", + " Whether or not to shuffle the features and labels.\n", + " If `False` (default), the samples are returned in sorted\n", + " order starting with `sample_size`/2 samples with class label 0\n", + " and followed by `sample_size`/2 samples with class label 1.\n", + "\n", + "\n", + "- `random_seed` : int (default: None)\n", + "\n", + " Random seed used for generating the multiplexer samples and shuffling.\n", + "\n", + "**Returns**\n", + "\n", + "- `X, y` : [n_samples, n_features], [n_class_labels]\n", + "\n", + " X is the feature matrix with the number of samples equal\n", + " to `sample_size`. The number of features is determined by\n", + " the number of address bits. For instance, 2 address bits\n", + " will result in a 6 bit multiplexer and consequently\n", + " 6 features (2 + 2^2 = 6).\n", + " All features are binary (values in {0, 1}).\n", + " y is a 1-dimensional array of class labels in {0, 1}.\n", + "\n", + "\n" + ] + } + ], + "source": [ + "with open('../../api_modules/mlxtend.data/make_multiplexer_dataset.md', 'r') as f:\n", + " s = f.read() \n", + "print(s)" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.pdf b/docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b0072ec185f9c1d1e6915960aa1ba5e685d7b0a2 GIT binary patch literal 19379 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 literal 0 HcmV?d00001 diff --git a/docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.png b/docs/sources/user_guide/data/make_multiplexer_dataset_data_files/6bit_multiplexer.png new file mode 100644 index 0000000000000000000000000000000000000000..45069e9f9bb8fd3bc8c26699218db3ff166507f2 GIT binary patch literal 49055 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 iK44P7q=3gz;Qs+P&7HZK(rv#00000 +# +# License: BSD 3 clause + +import numpy as np + + +def make_multiplexer_dataset(address_bits=2, sample_size=100, + positive_class_ratio=0.5, shuffle=False, + random_seed=None): + """ + Function to create a binary n-bit multiplexer dataset. + + New in mlxtend v0.9 + + Parameters + --------------- + address_bits : int (default: 2) + A positive integer that determines the number of address + bits in the multiplexer, which in turn determine the + n-bit capacity of the multiplexer and therefore the + number of features. The number of features is determined by + the number of address bits. For example, 2 address bits + will result in a 6 bit multiplexer and consequently + 6 features (2 + 2^2 = 6). If `address_bits=3`, then + this results in an 11-bit multiplexer as (2 + 2^3 = 11) + with 11 features. + + sample_size : int (default: 100) + The total number of samples generated. + + positive_class_ratio : float (default: 0.5) + The fraction (a float between 0 and 1) + of samples in the `sample_size`d dataset + that have class label 1. + If `positive_class_ratio=0.5` (default), then + the ratio of class 0 and class 1 samples is perfectly balanced. + + shuffle : Bool (default: False) + Whether or not to shuffle the features and labels. + If `False` (default), the samples are returned in sorted + order starting with `sample_size`/2 samples with class label 0 + and followed by `sample_size`/2 samples with class label 1. + + random_seed : int (default: None) + Random seed used for generating the multiplexer samples and shuffling. + + Returns + -------- + X, y : [n_samples, n_features], [n_class_labels] + X is the feature matrix with the number of samples equal + to `sample_size`. The number of features is determined by + the number of address bits. For instance, 2 address bits + will result in a 6 bit multiplexer and consequently + 6 features (2 + 2^2 = 6). + All features are binary (values in {0, 1}). + y is a 1-dimensional array of class labels in {0, 1}. + + """ + + if not isinstance(address_bits, int): + raise AttributeError('address_bits' + ' must be an integer. Got %s.' % + type(address_bits)) + if address_bits < 1: + raise AttributeError('Number of address_bits' + ' must be greater than 0. Got %s.' % address_bits) + register_bits = 2**address_bits + total_bits = address_bits + register_bits + X_pos, y_pos = [], [] + X_neg, y_neg = [], [] + + # use numpy's instead of python's round because of consistent + # banker's rounding behavior across versions + n_positives = np.round(sample_size*positive_class_ratio).astype(np.int) + n_negatives = sample_size - n_positives + + rng = np.random.RandomState(random_seed) + + def gen_randsample(): + all_bits = [rng.randint(0, 2) for i in range(total_bits)] + address_str = ''.join(str(c) for c in all_bits[:address_bits]) + register_pos = int(address_str, base=2) + class_label = all_bits[address_bits:][register_pos] + return all_bits, class_label + + while len(y_pos) < n_positives or len(y_neg) < n_negatives: + + all_bits, class_label = gen_randsample() + + if class_label and len(y_pos) < n_positives: + X_pos.append(all_bits) + y_pos.append(class_label) + + elif not class_label and len(y_neg) < n_negatives: + X_neg.append(all_bits) + y_neg.append(class_label) + + X, y = X_pos + X_neg, y_pos + y_neg + X, y = np.array(X, dtype=np.int), np.array(y, dtype=np.int) + + if shuffle: + p = rng.permutation(y.shape[0]) + X, y = X[p], y[p] + + return X, y diff --git a/mlxtend/data/tests/test_data.py b/mlxtend/data/tests/test_datasets.py similarity index 87% rename from mlxtend/data/tests/test_data.py rename to mlxtend/data/tests/test_datasets.py index f28e3e24c..98150b542 100644 --- a/mlxtend/data/tests/test_data.py +++ b/mlxtend/data/tests/test_datasets.py @@ -1,3 +1,11 @@ +# Sebastian Raschka 2014-2017 +# mlxtend Machine Learning Library Extensions +# +# Author: Sebastian Raschka +# +# License: BSD 3 clause + + from mlxtend.data import iris_data from mlxtend.data import wine_data from mlxtend.data import autompg_data diff --git a/mlxtend/data/tests/test_multiplexer.py b/mlxtend/data/tests/test_multiplexer.py new file mode 100644 index 000000000..7faeb28ce --- /dev/null +++ b/mlxtend/data/tests/test_multiplexer.py @@ -0,0 +1,97 @@ +# Sebastian Raschka 2014-2017 +# mlxtend Machine Learning Library Extensions +# +# Author: Sebastian Raschka +# +# License: BSD 3 clause + + +import numpy as np +import sys +from mlxtend.data import make_multiplexer_dataset +from mlxtend.utils import assert_raises + + +def test_defaults(): + + X, y = make_multiplexer_dataset() + + assert X.shape == (100, 6), X.shape + assert X.dtype == np.int + assert y.shape == (100, ), y.shape + assert y.dtype == np.int + + +def test_invalid_address_bits(): + + msg_1 = "address_bits must be an integer. Got ." + + # for Python 2.7: + if sys.version_info[0] == 2: + msg_1 = msg_1.replace('