{"id":3239,"date":"2020-03-15T18:00:07","date_gmt":"2020-03-15T18:00:07","guid":{"rendered":"https:\/\/www.aiproblog.com\/index.php\/2020\/03\/15\/imbalanced-multiclass-classification-with-the-e-coli-dataset\/"},"modified":"2020-03-15T18:00:07","modified_gmt":"2020-03-15T18:00:07","slug":"imbalanced-multiclass-classification-with-the-e-coli-dataset","status":"publish","type":"post","link":"https:\/\/www.aiproblog.com\/index.php\/2020\/03\/15\/imbalanced-multiclass-classification-with-the-e-coli-dataset\/","title":{"rendered":"Imbalanced Multiclass Classification with the E.coli Dataset"},"content":{"rendered":"<p>Author: Jason Brownlee<\/p>\n<div>\n<p>Multiclass classification problems are those where a label must be predicted, but there are more than two labels that may be predicted.<\/p>\n<p>These are challenging predictive modeling problems because a sufficiently representative number of examples of each class is required for a model to learn the problem. It is made challenging when the number of examples in each class is imbalanced, or skewed toward one or a few of the classes with very few examples of other classes.<\/p>\n<p>Problems of this type are referred to as imbalanced multiclass classification problems and they require both the careful design of an evaluation metric and test harness and choice of machine learning models. The E.coli protein localization sites dataset is a standard dataset for exploring the challenge of imbalanced multiclass classification.<\/p>\n<p>In this tutorial, you will discover how to develop and evaluate a model for the imbalanced multiclass E.coli dataset.<\/p>\n<p>After completing this tutorial, you will know:<\/p>\n<ul>\n<li>How to load and explore the dataset and generate ideas for data preparation and model selection.<\/li>\n<li>How to systematically evaluate a suite of machine learning models with a robust test harness.<\/li>\n<li>How to fit a final model and use it to predict the class labels for specific examples.<\/li>\n<\/ul>\n<p>Discover SMOTE, one-class classification, cost-sensitive learning, threshold moving, and much more <a href=\"https:\/\/machinelearningmastery.com\/imbalanced-classification-with-python\/\">in my new book<\/a>, with 30 step-by-step tutorials and full Python source code.<\/p>\n<p>Let&rsquo;s get started.<\/p>\n<div id=\"attachment_9772\" style=\"width: 810px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-9772\" class=\"size-full wp-image-9772\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2020\/03\/Imbalanced-Multiclass-Classification-with-the-E.coli-Dataset.jpg\" alt=\"Imbalanced Multiclass Classification with the E.coli Dataset\" width=\"800\" height=\"450\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/03\/Imbalanced-Multiclass-Classification-with-the-E.coli-Dataset.jpg 800w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/03\/Imbalanced-Multiclass-Classification-with-the-E.coli-Dataset-300x169.jpg 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/03\/Imbalanced-Multiclass-Classification-with-the-E.coli-Dataset-768x432.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\"><\/p>\n<p id=\"caption-attachment-9772\" class=\"wp-caption-text\">Imbalanced Multiclass Classification with the E.coli Dataset<br \/>Photo by <a href=\"https:\/\/flickr.com\/photos\/tempoworld\/16957865281\/\">Marcus<\/a>, some rights reserved.<\/p>\n<\/div>\n<h2>Tutorial Overview<\/h2>\n<p>This tutorial is divided into five parts; they are:<\/p>\n<ol>\n<li>E.coli Dataset<\/li>\n<li>Explore the Dataset<\/li>\n<li>Model Test and Baseline Result<\/li>\n<li>Evaluate Models\n<ol>\n<li>Evaluate Machine Learning Algorithms<\/li>\n<li>Evaluate Data Oversampling<\/li>\n<\/ol>\n<\/li>\n<li>Make Predictions on New Data<\/li>\n<\/ol>\n<h2>E.coli Dataset<\/h2>\n<p>In this project, we will use a standard imbalanced machine learning dataset referred to as the &ldquo;<em>E.coli<\/em>&rdquo; dataset, also referred to as the &ldquo;<em>protein localization sites<\/em>&rdquo; dataset.<\/p>\n<p>The dataset describes the problem of classifying <a href=\"https:\/\/en.wikipedia.org\/wiki\/Escherichia_coli\">E.coli proteins<\/a> using their amino acid sequences in their cell localization sites. That is, predicting how a protein will bind to a cell based on the chemical composition of the protein before it is folded.<\/p>\n<p>The dataset is credited to Kenta Nakai and was developed into its current form by <a href=\"https:\/\/paulhorton.gitlab.io\/\">Paul Horton<\/a> and <a href=\"https:\/\/www.hgc.jp\/~knakai\/\">Kenta Nakai<\/a> in their 1996 paper titled &ldquo;<a href=\"https:\/\/www.ncbi.nlm.nih.gov\/pubmed\/8877510\">A Probabilistic Classification System For Predicting The Cellular Localization Sites Of Proteins<\/a>.&rdquo; In it, they achieved a classification accuracy of 81 percent.<\/p>\n<blockquote>\n<p>336 E.coli proteins were classified into 8 classes with an accuracy of 81% &hellip;<\/p>\n<\/blockquote>\n<p>&mdash; <a href=\"https:\/\/www.ncbi.nlm.nih.gov\/pubmed\/8877510\">A Probabilistic Classification System For Predicting The Cellular Localization Sites Of Proteins<\/a>, 1996.<\/p>\n<p>The dataset is comprised of 336 examples of E.coli proteins and each example is described using seven input variables calculated from the proteins amino acid sequence.<\/p>\n<p>Ignoring the sequence name, the input features are described as follows:<\/p>\n<ul>\n<li><strong>mcg<\/strong>: McGeoch&rsquo;s method for signal sequence recognition.<\/li>\n<li><strong>gvh<\/strong>: von Heijne&rsquo;s method for signal sequence recognition.<\/li>\n<li><strong>lip<\/strong>: von Heijne&rsquo;s Signal Peptidase II consensus sequence score.<\/li>\n<li><strong>chg<\/strong>: Presence of charge on N-terminus of predicted lipoproteins.<\/li>\n<li><strong>aac<\/strong>: score of discriminant analysis of the amino acid content of outer membrane and periplasmic proteins.<\/li>\n<li><strong>alm1<\/strong>: score of the ALOM membrane-spanning region prediction program.<\/li>\n<li><strong>alm2<\/strong>: score of ALOM program after excluding putative cleavable signal regions from the sequence.<\/li>\n<\/ul>\n<p>There are eight classes described as follows:<\/p>\n<ul>\n<li><strong>cp<\/strong>: cytoplasm<\/li>\n<li><strong>im<\/strong>: inner membrane without signal sequence<\/li>\n<li><strong>pp<\/strong>: periplasm<\/li>\n<li><strong>imU<\/strong>: inner membrane, non cleavable signal sequence<\/li>\n<li><strong>om<\/strong>: outer membrane<\/li>\n<li><strong>omL<\/strong>: outer membrane lipoprotein<\/li>\n<li><strong>imL<\/strong>: inner membrane lipoprotein<\/li>\n<li><strong>imS<\/strong>: inner membrane, cleavable signal sequence<\/li>\n<\/ul>\n<p>The distribution of examples across the classes is not equal and in some cases severely imbalanced.<\/p>\n<p>For example, the &ldquo;<em>cp<\/em>&rdquo; class has 143 examples, whereas the &ldquo;<em>imL<\/em>&rdquo; and &ldquo;<em>imS<\/em>&rdquo; classes have just two examples each.<\/p>\n<p>Next, let&rsquo;s take a closer look at the data.<\/p>\n<\/p>\n<div class=\"woo-sc-hr\"><\/div>\n<p><center><\/p>\n<h3>Want to Get Started With Imbalance Classification?<\/h3>\n<p>Take my free 7-day email crash course now (with sample code).<\/p>\n<p>Click to sign-up and also get a free PDF Ebook version of the course.<\/p>\n<p><a href=\"https:\/\/machinelearningmastery.lpages.co\/leadbox\/14de34d42172a2%3A164f8be4f346dc\/4529268551712768\/\" target=\"_blank\" style=\"background: rgb(255, 206, 10); color: rgb(255, 255, 255); text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-weight: bold; font-size: 16px; line-height: 20px; padding: 10px; display: inline-block; max-width: 300px; border-radius: 5px; text-shadow: rgba(0, 0, 0, 0.25) 0px -1px 1px; box-shadow: rgba(255, 255, 255, 0.5) 0px 1px 3px inset, rgba(0, 0, 0, 0.5) 0px 1px 3px;\" rel=\"noopener noreferrer\">Download Your FREE Mini-Course<\/a><script data-leadbox=\"14de34d42172a2:164f8be4f346dc\" data-url=\"https:\/\/machinelearningmastery.lpages.co\/leadbox\/14de34d42172a2%3A164f8be4f346dc\/4529268551712768\/\" data-config=\"%7B%7D\" type=\"text\/javascript\" src=\"https:\/\/machinelearningmastery.lpages.co\/leadbox-1576257931.js\"><\/script><\/p>\n<p><\/center><\/p>\n<div class=\"woo-sc-hr\"><\/div>\n<h2>Explore the Dataset<\/h2>\n<p>First, download and unzip the dataset and save it in your current working directory with the name &ldquo;<em>ecoli.csv<\/em>&ldquo;.<\/p>\n<p>Note that this version of the dataset has the first column (sequence name) removed as it does not contain generalizable information for modeling.<\/p>\n<ul>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/ecoli.csv\">Download E.coli Dataset (ecoli.csv)<\/a><\/li>\n<\/ul>\n<p>Review the contents of the file.<\/p>\n<p>The first few lines of the file should look as follows:<\/p>\n<pre class=\"crayon-plain-tag\">0.49,0.29,0.48,0.50,0.56,0.24,0.35,cp\r\n0.07,0.40,0.48,0.50,0.54,0.35,0.44,cp\r\n0.56,0.40,0.48,0.50,0.49,0.37,0.46,cp\r\n0.59,0.49,0.48,0.50,0.52,0.45,0.36,cp\r\n0.23,0.32,0.48,0.50,0.55,0.25,0.35,cp\r\n...<\/pre>\n<p>We can see that the input variables all appear numeric, and the class labels are string values that will need to be label encoded prior to modeling.<\/p>\n<p>The dataset can be loaded as a DataFrame using the <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.read_csv.html\">read_csv() Pandas function<\/a>, specifying the location of the file and the fact that there is no header line.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define the dataset location\r\nfilename = 'ecoli.csv'\r\n# load the csv file as a data frame\r\ndataframe = read_csv(filename, header=None)<\/pre>\n<p>Once loaded, we can summarize the number of rows and columns by printing the shape of the <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.html\">DataFrame<\/a>.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# summarize the shape of the dataset\r\nprint(dataframe.shape)<\/pre>\n<p>Next, we can calculate a five-number summary for each input variable.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# describe the dataset\r\nset_option('precision', 3)\r\nprint(dataframe.describe())<\/pre>\n<p>Finally, we can also summarize the number of examples in each class using the <a href=\"https:\/\/docs.python.org\/3\/library\/collections.html\">Counter<\/a> object.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# summarize the class distribution\r\ntarget = dataframe.values[:,-1]\r\ncounter = Counter(target)\r\nfor k,v in counter.items():\r\n\tper = v \/ len(target) * 100\r\n\tprint('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))<\/pre>\n<p>Tying this together, the complete example of loading and summarizing the dataset is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># load and summarize the dataset\r\nfrom pandas import read_csv\r\nfrom pandas import set_option\r\nfrom collections import Counter\r\n# define the dataset location\r\nfilename = 'ecoli.csv'\r\n# load the csv file as a data frame\r\ndataframe = read_csv(filename, header=None)\r\n# summarize the shape of the dataset\r\nprint(dataframe.shape)\r\n# describe the dataset\r\nset_option('precision', 3)\r\nprint(dataframe.describe())\r\n# summarize the class distribution\r\ntarget = dataframe.values[:,-1]\r\ncounter = Counter(target)\r\nfor k,v in counter.items():\r\n\tper = v \/ len(target) * 100\r\n\tprint('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))<\/pre>\n<p>Running the example first loads the dataset and confirms the number of rows and columns, which are 336 rows and 7 input variables and 1 target variable.<\/p>\n<p>Reviewing the summary of each variable, it appears that the variables have been centered, that is, shifted to have a mean of 0.5. It also appears that the variables have been normalized, meaning all values are in the range between about 0 and 1; at least no variables have values outside this range.<\/p>\n<p>The class distribution is then summarized, confirming the severe skew in the observations for each class. We can see that the &ldquo;<em>cp<\/em>&rdquo; class is dominant with about 42 percent of the examples and minority classes such as &ldquo;<em>imS<\/em>&ldquo;, &ldquo;<em>imL<\/em>&ldquo;, and &ldquo;<em>omL<\/em>&rdquo; have about 1 percent or less of the dataset.<\/p>\n<p>There may not be sufficient data to generalize from these minority classes. One approach might be to simply remove the examples with these classes.<\/p>\n<pre class=\"crayon-plain-tag\">(336, 8)\r\n             0        1        2        3        4        5        6\r\ncount  336.000  336.000  336.000  336.000  336.000  336.000  336.000\r\nmean     0.500    0.500    0.495    0.501    0.500    0.500    0.500\r\nstd      0.195    0.148    0.088    0.027    0.122    0.216    0.209\r\nmin      0.000    0.160    0.480    0.500    0.000    0.030    0.000\r\n25%      0.340    0.400    0.480    0.500    0.420    0.330    0.350\r\n50%      0.500    0.470    0.480    0.500    0.495    0.455    0.430\r\n75%      0.662    0.570    0.480    0.500    0.570    0.710    0.710\r\nmax      0.890    1.000    1.000    1.000    0.880    1.000    0.990\r\n\r\nClass=cp, Count=143, Percentage=42.560%\r\nClass=im, Count=77, Percentage=22.917%\r\nClass=imS, Count=2, Percentage=0.595%\r\nClass=imL, Count=2, Percentage=0.595%\r\nClass=imU, Count=35, Percentage=10.417%\r\nClass=om, Count=20, Percentage=5.952%\r\nClass=omL, Count=5, Percentage=1.488%\r\nClass=pp, Count=52, Percentage=15.476%<\/pre>\n<p>We can also take a look at the distribution of the input variables by creating a histogram for each.<\/p>\n<p>The complete example of creating histograms of all input variables is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># create histograms of all variables\r\nfrom pandas import read_csv\r\nfrom matplotlib import pyplot\r\n# define the dataset location\r\nfilename = 'ecoli.csv'\r\n# load the csv file as a data frame\r\ndf = read_csv(filename, header=None)\r\n# create a histogram plot of each variable\r\ndf.hist(bins=25)\r\n# show the plot\r\npyplot.show()<\/pre>\n<p>We can see that variables such as 0, 5, and 6 may have a multi-modal distribution. The variables 2 and 3 may have a binary distribution and variables 1 and 4 may have a <a href=\"https:\/\/machinelearningmastery.com\/continuous-probability-distributions-for-machine-learning\/\">Gaussian-like distribution<\/a>.<\/p>\n<p>Depending on the choice of model, the dataset may benefit from standardization, normalization, and perhaps a power transform.<\/p>\n<div id=\"attachment_9769\" style=\"width: 1290px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-9769\" class=\"size-full wp-image-9769\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2019\/12\/Histogram-of-Variables-in-the-E.coli-Dataset.png\" alt=\"Histogram of Variables in the E.coli Dataset\" width=\"1280\" height=\"960\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Histogram-of-Variables-in-the-E.coli-Dataset.png 1280w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Histogram-of-Variables-in-the-E.coli-Dataset-300x225.png 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Histogram-of-Variables-in-the-E.coli-Dataset-1024x768.png 1024w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Histogram-of-Variables-in-the-E.coli-Dataset-768x576.png 768w\" sizes=\"(max-width: 1280px) 100vw, 1280px\"><\/p>\n<p id=\"caption-attachment-9769\" class=\"wp-caption-text\">Histogram of Variables in the E.coli Dataset<\/p>\n<\/div>\n<p>Now that we have reviewed the dataset, let&rsquo;s look at developing a test harness for evaluating candidate models.<\/p>\n<h2>Model Test and Baseline Result<\/h2>\n<p>The k-fold cross-validation procedure provides a good general estimate of model performance that is not too optimistically biased, at least compared to a single train-test split. We will use <em>k=5<\/em>, meaning each fold will contain about 336\/5 or about 67 examples.<\/p>\n<p>Stratified means that each fold will aim to contain the same mixture of examples by class as the entire training dataset. Repeated means that the evaluation process will be performed multiple times to help avoid fluke results and better capture the variance of the chosen model. We will use three repeats.<\/p>\n<p>This means a single model will be fit and evaluated 5 * 3, or 15, times and the mean and standard deviation of these runs will be reported.<\/p>\n<p>This can be achieved using the <a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.model_selection.RepeatedStratifiedKFold.html\">RepeatedStratifiedKFold<\/a> scikit-learn class.<\/p>\n<p>All classes are equally important. As such, in this case, we will use classification accuracy to evaluate models.<\/p>\n<p>First, we can define a function to load the dataset and split the input variables into inputs and output variables and use a label encoder to ensure class labels are numbered sequentially.<\/p>\n<pre class=\"crayon-plain-tag\"># load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdata = read_csv(full_path, header=None)\r\n\t# retrieve numpy array\r\n\tdata = data.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable to have the classes 0 and 1\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y<\/pre>\n<p>We can define a function to evaluate a candidate model using stratified repeated 5-fold cross-validation, then return a list of scores calculated on the model for each fold and repeat.<\/p>\n<p>The <em>evaluate_model()<\/em> function below implements this.<\/p>\n<pre class=\"crayon-plain-tag\"># evaluate a model\r\ndef evaluate_model(X, y, model):\r\n\t# define evaluation procedure\r\n\tcv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)\r\n\t# evaluate model\r\n\tscores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)\r\n\treturn scores<\/pre>\n<p>We can then call the <em>load_dataset()<\/em> function to load and confirm the E.coli dataset.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y = load_dataset(full_path)\r\n# summarize the loaded dataset\r\nprint(X.shape, y.shape, Counter(y))<\/pre>\n<p>In this case, we will evaluate the baseline strategy of predicting the majority class in all cases.<\/p>\n<p>This can be implemented automatically using the <a href=\"https:\/\/machinelearningmastery.com\/how-to-develop-and-evaluate-naive-classifier-strategies-using-probability\/\">DummyClassifier<\/a> class and setting the &ldquo;<em>strategy<\/em>&rdquo; to &ldquo;<em>most_frequent<\/em>&rdquo; that will predict the most common class (e.g. class &lsquo;<em>cp<\/em>&lsquo;) in the training dataset. As such, we would expect this model to achieve a classification accuracy of about 42 percent given this is the distribution of the most common class in the training dataset.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define the reference model\r\nmodel = DummyClassifier(strategy='most_frequent')<\/pre>\n<p>We can then evaluate the model by calling our <em>evaluate_model()<\/em> function and report the mean and standard deviation of the results.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# evaluate the model\r\nscores = evaluate_model(X, y, model)\r\n# summarize performance\r\nprint('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))<\/pre>\n<p>Tying this all together, the complete example of evaluating the baseline model on the E.coli dataset using classification accuracy is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># baseline model and test harness for the ecoli dataset\r\nfrom collections import Counter\r\nfrom numpy import mean\r\nfrom numpy import std\r\nfrom pandas import read_csv\r\nfrom sklearn.preprocessing import LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom sklearn.model_selection import RepeatedStratifiedKFold\r\nfrom sklearn.dummy import DummyClassifier\r\n\r\n# load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdata = read_csv(full_path, header=None)\r\n\t# retrieve numpy array\r\n\tdata = data.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable to have the classes 0 and 1\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y\r\n\r\n# evaluate a model\r\ndef evaluate_model(X, y, model):\r\n\t# define evaluation procedure\r\n\tcv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)\r\n\t# evaluate model\r\n\tscores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)\r\n\treturn scores\r\n\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y = load_dataset(full_path)\r\n# summarize the loaded dataset\r\nprint(X.shape, y.shape, Counter(y))\r\n# define the reference model\r\nmodel = DummyClassifier(strategy='most_frequent')\r\n# evaluate the model\r\nscores = evaluate_model(X, y, model)\r\n# summarize performance\r\nprint('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))<\/pre>\n<p>Running the example first loads the dataset and reports the number of cases correctly as 336 and the distribution of class labels as we expect.<\/p>\n<p>The <em>DummyClassifier<\/em> with our default strategy is then evaluated using repeated stratified <a href=\"https:\/\/machinelearningmastery.com\/k-fold-cross-validation\/\">k-fold cross-validation<\/a> and the mean and standard deviation of the classification accuracy is reported as about 42.6 percent.<\/p>\n<pre class=\"crayon-plain-tag\">(336, 7) (336,) Counter({0: 143, 1: 77, 7: 52, 4: 35, 5: 20, 6: 5, 3: 2, 2: 2})\r\nMean Accuracy: 0.426 (0.006)<\/pre>\n<p>Warnings are reported during the evaluation of the model; for example:<\/p>\n<pre class=\"crayon-plain-tag\">Warning: The least populated class in y has only 2 members, which is too few. The minimum number of members in any class cannot be less than n_splits=5.<\/pre>\n<p>This is because some of the classes do not have a sufficient number of examples for the 5-fold cross-validation, e.g. classes &ldquo;<em>imS<\/em>&rdquo; and &ldquo;<em>imL<\/em>&ldquo;.<\/p>\n<p>In this case, we will remove these examples from the dataset. This can be achieved by updating the <em>load_dataset()<\/em> to remove those rows with these classes, e.g. four rows.<\/p>\n<pre class=\"crayon-plain-tag\"># load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdf = read_csv(full_path, header=None)\r\n\t# remove rows for the minority classes\r\n\tdf = df[df[7] != 'imS']\r\n\tdf = df[df[7] != 'imL']\r\n\t# retrieve numpy array\r\n\tdata = df.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable to have the classes 0 and 1\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y<\/pre>\n<p>We can then re-run the example to establish a baseline in classification accuracy.<\/p>\n<p>The complete example is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># baseline model and test harness for the ecoli dataset\r\nfrom collections import Counter\r\nfrom numpy import mean\r\nfrom numpy import std\r\nfrom pandas import read_csv\r\nfrom sklearn.preprocessing import LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom sklearn.model_selection import RepeatedStratifiedKFold\r\nfrom sklearn.dummy import DummyClassifier\r\n\r\n# load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdf = read_csv(full_path, header=None)\r\n\t# remove rows for the minority classes\r\n\tdf = df[df[7] != 'imS']\r\n\tdf = df[df[7] != 'imL']\r\n\t# retrieve numpy array\r\n\tdata = df.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable to have the classes 0 and 1\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y\r\n\r\n# evaluate a model\r\ndef evaluate_model(X, y, model):\r\n\t# define evaluation procedure\r\n\tcv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)\r\n\t# evaluate model\r\n\tscores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)\r\n\treturn scores\r\n\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y = load_dataset(full_path)\r\n# summarize the loaded dataset\r\nprint(X.shape, y.shape, Counter(y))\r\n# define the reference model\r\nmodel = DummyClassifier(strategy='most_frequent')\r\n# evaluate the model\r\nscores = evaluate_model(X, y, model)\r\n# summarize performance\r\nprint('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))<\/pre>\n<p>Running the example confirms that the number of examples was reduced by four, from 336 to 332.<\/p>\n<p>We can also see that the number of classes was reduced from eight to six (class 0 through to class 5).<\/p>\n<p>The baseline in performance was established at 43.1 percent. This score provides a baseline on this dataset by which all other classification algorithms can be compared. Achieving a score above about 43.1 percent indicates that a model has skill on this dataset, and a score at or below this value indicates that the model does not have skill on this dataset.<\/p>\n<pre class=\"crayon-plain-tag\">(332, 7) (332,) Counter({0: 143, 1: 77, 5: 52, 2: 35, 3: 20, 4: 5})\r\nMean Accuracy: 0.431 (0.005)<\/pre>\n<p>Now that we have a test harness and a baseline in performance, we can begin to evaluate some models on this dataset.<\/p>\n<h2>Evaluate Models<\/h2>\n<p>In this section, we will evaluate a suite of different techniques on the dataset using the test harness developed in the previous section.<\/p>\n<p>The reported performance is good, but not highly optimized (e.g. hyperparameters are not tuned).<\/p>\n<p><strong>Can you do better?<\/strong> If you can achieve better classification accuracy using the same test harness, I&rsquo;d love to hear about it. Let me know in the comments below.<\/p>\n<h3>Evaluate Machine Learning Algorithms<\/h3>\n<p>Let&rsquo;s start by evaluating a mixture of machine learning models on the dataset.<\/p>\n<p>It can be a good idea to spot check a suite of different nonlinear algorithms on a dataset to quickly flush out what works well and deserves further attention, and what doesn&rsquo;t.<\/p>\n<p>We will evaluate the following machine learning models on the E.coli dataset:<\/p>\n<ul>\n<li>Linear Discriminant Analysis (LDA)<\/li>\n<li>Support Vector Machine (SVM)<\/li>\n<li>Bagged Decision Trees (BAG)<\/li>\n<li>Random Forest (RF)<\/li>\n<li>Extra Trees (ET)<\/li>\n<\/ul>\n<p>We will use mostly default model hyperparameters, with the exception of the number of trees in the ensemble algorithms, which we will set to a reasonable default of 1,000.<\/p>\n<p>We will define each model in turn and add them to a list so that we can evaluate them sequentially. The <em>get_models()<\/em> function below defines the list of models for evaluation, as well as a list of model short names for plotting the results later.<\/p>\n<pre class=\"crayon-plain-tag\"># define models to test\r\ndef get_models():\r\n\tmodels, names = list(), list()\r\n\t# LDA\r\n\tmodels.append(LinearDiscriminantAnalysis())\r\n\tnames.append('LDA')\r\n\t# SVM\r\n\tmodels.append(LinearSVC())\r\n\tnames.append('SVM')\r\n\t# Bagging\r\n\tmodels.append(BaggingClassifier(n_estimators=1000))\r\n\tnames.append('BAG')\r\n\t# RF\r\n\tmodels.append(RandomForestClassifier(n_estimators=1000))\r\n\tnames.append('RF')\r\n\t# ET\r\n\tmodels.append(ExtraTreesClassifier(n_estimators=1000))\r\n\tnames.append('ET')\r\n\treturn models, names<\/pre>\n<p>We can then enumerate the list of models in turn and evaluate each, storing the scores for later evaluation.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define models\r\nmodels, names = get_models()\r\nresults = list()\r\n# evaluate each model\r\nfor i in range(len(models)):\r\n\t# evaluate the model and store results\r\n\tscores = evaluate_model(X, y, models[i])\r\n\tresults.append(scores)\r\n\t# summarize performance\r\n\tprint('&gt;%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))<\/pre>\n<p>At the end of the run, we can plot each sample of scores as a box and whisker plot with the same scale so that we can directly compare the distributions.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# plot the results\r\npyplot.boxplot(results, labels=names, showmeans=True)\r\npyplot.show()<\/pre>\n<p>Tying this all together, the complete example of evaluating a suite of machine learning algorithms on the E.coli dataset is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># spot check machine learning algorithms on the ecoli dataset\r\nfrom numpy import mean\r\nfrom numpy import std\r\nfrom pandas import read_csv\r\nfrom matplotlib import pyplot\r\nfrom sklearn.preprocessing import LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom sklearn.model_selection import RepeatedStratifiedKFold\r\nfrom sklearn.svm import LinearSVC\r\nfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis\r\nfrom sklearn.ensemble import RandomForestClassifier\r\nfrom sklearn.ensemble import ExtraTreesClassifier\r\nfrom sklearn.ensemble import BaggingClassifier\r\n\r\n# load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdf = read_csv(full_path, header=None)\r\n\t# remove rows for the minority classes\r\n\tdf = df[df[7] != 'imS']\r\n\tdf = df[df[7] != 'imL']\r\n\t# retrieve numpy array\r\n\tdata = df.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y\r\n\r\n# evaluate a model\r\ndef evaluate_model(X, y, model):\r\n\t# define evaluation procedure\r\n\tcv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)\r\n\t# evaluate model\r\n\tscores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)\r\n\treturn scores\r\n\r\n# define models to test\r\ndef get_models():\r\n\tmodels, names = list(), list()\r\n\t# LDA\r\n\tmodels.append(LinearDiscriminantAnalysis())\r\n\tnames.append('LDA')\r\n\t# SVM\r\n\tmodels.append(LinearSVC())\r\n\tnames.append('SVM')\r\n\t# Bagging\r\n\tmodels.append(BaggingClassifier(n_estimators=1000))\r\n\tnames.append('BAG')\r\n\t# RF\r\n\tmodels.append(RandomForestClassifier(n_estimators=1000))\r\n\tnames.append('RF')\r\n\t# ET\r\n\tmodels.append(ExtraTreesClassifier(n_estimators=1000))\r\n\tnames.append('ET')\r\n\treturn models, names\r\n\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y = load_dataset(full_path)\r\n# define models\r\nmodels, names = get_models()\r\nresults = list()\r\n# evaluate each model\r\nfor i in range(len(models)):\r\n\t# evaluate the model and store results\r\n\tscores = evaluate_model(X, y, models[i])\r\n\tresults.append(scores)\r\n\t# summarize performance\r\n\tprint('&gt;%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))\r\n# plot the results\r\npyplot.boxplot(results, labels=names, showmeans=True)\r\npyplot.show()<\/pre>\n<p>Running the example evaluates each algorithm in turn and reports the mean and standard deviation classification accuracy.<\/p>\n<p>Your specific results will vary given the stochastic nature of the learning algorithms; consider running the example a few times.<\/p>\n<p>In this case, we can see that all of the tested algorithms have skill, achieving an accuracy above the default of 43.1 percent.<\/p>\n<p>The results suggest that most algorithms do well on this dataset and that perhaps the ensembles of decision trees perform the best with Extra Trees achieving 88 percent accuracy and Random Forest achieving 89.5 percent accuracy.<\/p>\n<pre class=\"crayon-plain-tag\">&gt;LDA 0.886 (0.027)\r\n&gt;SVM 0.883 (0.027)\r\n&gt;BAG 0.851 (0.037)\r\n&gt;RF 0.895 (0.032)\r\n&gt;ET 0.880 (0.030)<\/pre>\n<p>A figure is created showing one box and whisker plot for each algorithm&rsquo;s sample of results. The box shows the middle 50 percent of the data, the orange line in the middle of each box shows the median of the sample, and the green triangle in each box shows the mean of the sample.<\/p>\n<p>We can see that the distributions of scores for the ensembles of decision trees clustered together separate from the other algorithms tested. In most cases, the mean and median are close on the plot, suggesting a somewhat symmetrical distribution of scores that may indicate the models are stable.<\/p>\n<div id=\"attachment_9770\" style=\"width: 1290px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-9770\" class=\"size-full wp-image-9770\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset.png\" alt=\"Box and Whisker Plot of Machine Learning Models on the Imbalanced E.coli Dataset\" width=\"1280\" height=\"960\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset.png 1280w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-300x225.png 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-1024x768.png 1024w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-768x576.png 768w\" sizes=\"(max-width: 1280px) 100vw, 1280px\"><\/p>\n<p id=\"caption-attachment-9770\" class=\"wp-caption-text\">Box and Whisker Plot of Machine Learning Models on the Imbalanced E.coli Dataset<\/p>\n<\/div>\n<h3>Evaluate Data Oversampling<\/h3>\n<p>With so many classes and so few examples in many of the classes, the dataset may benefit from oversampling.<\/p>\n<p>We can test the SMOTE algorithm applied to all except the majority class (<em>cp<\/em>) results in a lift in performance.<\/p>\n<p>Generally, SMOTE does not appear to help ensembles of decision trees, so we will change the set of algorithms tested to the following:<\/p>\n<ul>\n<li>Multinomial Logistic Regression (LR)<\/li>\n<li>Linear Discriminant Analysis (LDA)<\/li>\n<li>Support Vector Machine (SVM)<\/li>\n<li>k-Nearest Neighbors (KNN)<\/li>\n<li>Gaussian Process (GP)<\/li>\n<\/ul>\n<p>The updated version of the <em>get_models()<\/em> function to define these models is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># define models to test\r\ndef get_models():\r\n\tmodels, names = list(), list()\r\n\t# LR\r\n\tmodels.append(LogisticRegression(solver='lbfgs', multi_class='multinomial'))\r\n\tnames.append('LR')\r\n\t# LDA\r\n\tmodels.append(LinearDiscriminantAnalysis())\r\n\tnames.append('LDA')\r\n\t# SVM\r\n\tmodels.append(LinearSVC())\r\n\tnames.append('SVM')\r\n\t# KNN\r\n\tmodels.append(KNeighborsClassifier(n_neighbors=3))\r\n\tnames.append('KNN')\r\n\t# GP\r\n\tmodels.append(GaussianProcessClassifier())\r\n\tnames.append('GP')\r\n\treturn models, names<\/pre>\n<p>We can use the <a href=\"https:\/\/imbalanced-learn.readthedocs.io\/en\/stable\/generated\/imblearn.over_sampling.SMOTE.html\">SMOTE<\/a> implementation from the imbalanced-learn library, and a <a href=\"https:\/\/imbalanced-learn.readthedocs.io\/en\/stable\/generated\/imblearn.pipeline.Pipeline.html\">Pipeline<\/a> from the same library to first apply SMOTE to the training dataset, then fit a given model as part of the cross-validation procedure.<\/p>\n<p>SMOTE will synthesize new examples using k-nearest neighbors in the training dataset, where by default, <em>k<\/em> is set to 5.<\/p>\n<p>This is too large for some of the classes in our dataset. Therefore, we will try a <em>k<\/em> value of 2.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# create pipeline\r\nsteps = [('o', SMOTE(k_neighbors=2)), ('m', models[i])]\r\npipeline = Pipeline(steps=steps)\r\n# evaluate the model and store results\r\nscores = evaluate_model(X, y, pipeline)<\/pre>\n<p>Tying this together, the complete example of using SMOTE oversampling on the E.coli dataset is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># spot check smote with machine learning algorithms on the ecoli dataset\r\nfrom numpy import mean\r\nfrom numpy import std\r\nfrom pandas import read_csv\r\nfrom matplotlib import pyplot\r\nfrom sklearn.preprocessing import LabelEncoder\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom sklearn.model_selection import RepeatedStratifiedKFold\r\nfrom sklearn.svm import LinearSVC\r\nfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis\r\nfrom sklearn.neighbors import KNeighborsClassifier\r\nfrom sklearn.gaussian_process import GaussianProcessClassifier\r\nfrom sklearn.linear_model import LogisticRegression\r\nfrom imblearn.pipeline import Pipeline\r\nfrom imblearn.over_sampling import SMOTE\r\n\r\n# load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdf = read_csv(full_path, header=None)\r\n\t# remove rows for the minority classes\r\n\tdf = df[df[7] != 'imS']\r\n\tdf = df[df[7] != 'imL']\r\n\t# retrieve numpy array\r\n\tdata = df.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable\r\n\ty = LabelEncoder().fit_transform(y)\r\n\treturn X, y\r\n\r\n# evaluate a model\r\ndef evaluate_model(X, y, model):\r\n\t# define evaluation procedure\r\n\tcv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=1)\r\n\t# evaluate model\r\n\tscores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)\r\n\treturn scores\r\n\r\n# define models to test\r\ndef get_models():\r\n\tmodels, names = list(), list()\r\n\t# LR\r\n\tmodels.append(LogisticRegression(solver='lbfgs', multi_class='multinomial'))\r\n\tnames.append('LR')\r\n\t# LDA\r\n\tmodels.append(LinearDiscriminantAnalysis())\r\n\tnames.append('LDA')\r\n\t# SVM\r\n\tmodels.append(LinearSVC())\r\n\tnames.append('SVM')\r\n\t# KNN\r\n\tmodels.append(KNeighborsClassifier(n_neighbors=3))\r\n\tnames.append('KNN')\r\n\t# GP\r\n\tmodels.append(GaussianProcessClassifier())\r\n\tnames.append('GP')\r\n\treturn models, names\r\n\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y = load_dataset(full_path)\r\n# define models\r\nmodels, names = get_models()\r\nresults = list()\r\n# evaluate each model\r\nfor i in range(len(models)):\r\n\t# create pipeline\r\n\tsteps = [('o', SMOTE(k_neighbors=2)), ('m', models[i])]\r\n\tpipeline = Pipeline(steps=steps)\r\n\t# evaluate the model and store results\r\n\tscores = evaluate_model(X, y, pipeline)\r\n\tresults.append(scores)\r\n\t# summarize performance\r\n\tprint('&gt;%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))\r\n# plot the results\r\npyplot.boxplot(results, labels=names, showmeans=True)\r\npyplot.show()<\/pre>\n<p>Running the example evaluates each algorithm in turn and reports the mean and standard deviation classification accuracy.<\/p>\n<p>Your specific results will vary given the stochastic nature of the learning algorithms; consider running the example a few times.<\/p>\n<p>In this case, we can see that LDA with SMOTE resulted in a small drop from 88.6 percent to about 87.9 percent, whereas SVM with SMOTE saw a small increase from about 88.3 percent to about 88.8 percent.<\/p>\n<p>SVM also appears to be the best-performing method when using SMOTE in this case, although it does not achieve an improvement as compared to random forest in the previous section.<\/p>\n<pre class=\"crayon-plain-tag\">&gt;LR 0.875 (0.024)\r\n&gt;LDA 0.879 (0.029)\r\n&gt;SVM 0.888 (0.025)\r\n&gt;KNN 0.835 (0.040)\r\n&gt;GP 0.876 (0.023)<\/pre>\n<p>Box and whisker plots of classification accuracy scores are created for each algorithm.<\/p>\n<p>We can see that LDA has a number of performance outliers with high 90-percent values, which is quite interesting. It might suggest that LDA could perform better if focused on the abundant classes.<\/p>\n<div id=\"attachment_9771\" style=\"width: 1290px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-9771\" class=\"size-full wp-image-9771\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-SMOTE-with-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset.png\" alt=\"Box and Whisker Plot of SMOTE With Machine Learning Models on the Imbalanced E.coli Dataset\" width=\"1280\" height=\"960\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-SMOTE-with-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset.png 1280w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-SMOTE-with-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-300x225.png 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-SMOTE-with-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-1024x768.png 1024w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2019\/12\/Box-and-Whisker-Plot-of-SMOTE-with-Machine-Learning-Models-on-the-Imbalanced-E.coli-Dataset-768x576.png 768w\" sizes=\"(max-width: 1280px) 100vw, 1280px\"><\/p>\n<p id=\"caption-attachment-9771\" class=\"wp-caption-text\">Box and Whisker Plot of SMOTE With Machine Learning Models on the Imbalanced E.coli Dataset<\/p>\n<\/div>\n<p>Now that we have seen how to evaluate models on this dataset, let&rsquo;s look at how we can use a final model to make predictions.<\/p>\n<h2>Make Predictions on New Data<\/h2>\n<p>In this section, we can fit a final model and use it to make predictions on single rows of data.<\/p>\n<p>We will use the Random Forest model as our final model that achieved a classification accuracy of about 89.5 percent.<\/p>\n<p>First, we can define the model.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define model to evaluate\r\nmodel = RandomForestClassifier(n_estimators=1000)<\/pre>\n<p>Once defined, we can fit it on the entire training dataset.<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# fit the model\r\nmodel.fit(X, y)<\/pre>\n<p>Once fit, we can use it to make predictions for new data by calling the <em>predict()<\/em> function. This will return the encoded class label for each example.<\/p>\n<p>We can then use the label encoder to inverse transform to get the string class label.<\/p>\n<p>For example:<\/p>\n<pre class=\"crayon-plain-tag\">...\r\n# define a row of data\r\nrow = [...]\r\n# predict the class label\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]<\/pre>\n<p>To demonstrate this, we can use the fit model to make some predictions of labels for a few cases where we know the outcome.<\/p>\n<p>The complete example is listed below.<\/p>\n<pre class=\"crayon-plain-tag\"># fit a model and make predictions for the on the ecoli dataset\r\nfrom pandas import read_csv\r\nfrom sklearn.preprocessing import LabelEncoder\r\nfrom sklearn.ensemble import RandomForestClassifier\r\n\r\n# load the dataset\r\ndef load_dataset(full_path):\r\n\t# load the dataset as a numpy array\r\n\tdf = read_csv(full_path, header=None)\r\n\t# remove rows for the minority classes\r\n\tdf = df[df[7] != 'imS']\r\n\tdf = df[df[7] != 'imL']\r\n\t# retrieve numpy array\r\n\tdata = df.values\r\n\t# split into input and output elements\r\n\tX, y = data[:, :-1], data[:, -1]\r\n\t# label encode the target variable\r\n\tle = LabelEncoder()\r\n\ty = le.fit_transform(y)\r\n\treturn X, y, le\r\n\r\n# define the location of the dataset\r\nfull_path = 'ecoli.csv'\r\n# load the dataset\r\nX, y, le = load_dataset(full_path)\r\n# define model to evaluate\r\nmodel = RandomForestClassifier(n_estimators=1000)\r\n# fit the model\r\nmodel.fit(X, y)\r\n# known class \"cp\"\r\nrow = [0.49,0.29,0.48,0.50,0.56,0.24,0.35]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected cp)' % (label))\r\n# known class \"im\"\r\nrow = [0.06,0.61,0.48,0.50,0.49,0.92,0.37]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected im)' % (label))\r\n# known class \"imU\"\r\nrow = [0.72,0.42,0.48,0.50,0.65,0.77,0.79]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected imU)' % (label))\r\n# known class \"om\"\r\nrow = [0.78,0.68,0.48,0.50,0.83,0.40,0.29]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected om)' % (label))\r\n# known class \"omL\"\r\nrow = [0.77,0.57,1.00,0.50,0.37,0.54,0.0]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected omL)' % (label))\r\n# known class \"pp\"\r\nrow = [0.74,0.49,0.48,0.50,0.42,0.54,0.36]\r\nyhat = model.predict([row])\r\nlabel = le.inverse_transform(yhat)[0]\r\nprint('&gt;Predicted=%s (expected pp)' % (label))<\/pre>\n<p>Running the example first fits the model on the entire training dataset.<\/p>\n<p>Then the fit model is used to predict the label for one example taken from each of the six classes.<\/p>\n<p>We can see that the correct class label is predicted for each of the chosen examples. Nevertheless, on average, we expect that 1 in 10 predictions will be wrong and these errors may not be equally distributed across the classes.<\/p>\n<pre class=\"crayon-plain-tag\">&gt;Predicted=cp (expected cp)\r\n&gt;Predicted=im (expected im)\r\n&gt;Predicted=imU (expected imU)\r\n&gt;Predicted=om (expected om)\r\n&gt;Predicted=omL (expected omL)\r\n&gt;Predicted=pp (expected pp)<\/pre>\n<\/p>\n<h2>Further Reading<\/h2>\n<p>This section provides more resources on the topic if you are looking to go deeper.<\/p>\n<h3>Papers<\/h3>\n<ul>\n<li><a href=\"https:\/\/onlinelibrary.wiley.com\/doi\/abs\/10.1002\/prot.340110203\">Expert System For Predicting Protein Localization Sites In Gram&#8208;negative Bacteria<\/a>, 1991.<\/li>\n<li><a href=\"https:\/\/www.sciencedirect.com\/science\/article\/pii\/S0888754305801119\">A Knowledge Base For Predicting Protein Localization Sites In Eukaryotic Cells<\/a>, 1992.<\/li>\n<li><a href=\"https:\/\/www.ncbi.nlm.nih.gov\/pubmed\/8877510\">A Probabilistic Classification System For Predicting The Cellular Localization Sites Of Proteins<\/a>, 1996.<\/li>\n<\/ul>\n<h3>APIs<\/h3>\n<ul>\n<li><a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.read_csv.html\">pandas.read_csv API<\/a>.<\/li>\n<li><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.dummy.DummyClassifier.html\">sklearn.dummy.DummyClassifier API<\/a>.<\/li>\n<li><a href=\"https:\/\/imbalanced-learn.readthedocs.io\/en\/stable\/generated\/imblearn.over_sampling.SMOTE.html\">imblearn.over_sampling.SMOTE API<\/a>.<\/li>\n<li><a href=\"https:\/\/imbalanced-learn.readthedocs.io\/en\/stable\/generated\/imblearn.pipeline.Pipeline.html\">imblearn.pipeline.Pipeline API<\/a>.<\/li>\n<\/ul>\n<h3>Dataset<\/h3>\n<ul>\n<li><a href=\"https:\/\/archive.ics.uci.edu\/ml\/datasets\/ecoli\">Ecoli Dataset, UCI Machine Learning Repository<\/a>.<\/li>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/ecoli.csv\">Ecoli Dataset Download<\/a>.<\/li>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/ecoli.names\">Ecoli Dataset Description<\/a>.<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>In this tutorial, you discovered how to develop and evaluate a model for the imbalanced multiclass E.coli dataset.<\/p>\n<p>Specifically, you learned:<\/p>\n<ul>\n<li>How to load and explore the dataset and generate ideas for data preparation and model selection.<\/li>\n<li>How to systematically evaluate a suite of machine learning models with a robust test harness.<\/li>\n<li>How to fit a final model and use it to predict the class labels for specific examples.<\/li>\n<\/ul>\n<p>Do you have any questions?<br \/>\nAsk your questions in the comments below and I will do my best to answer.<\/p>\n<p>The post <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/imbalanced-multiclass-classification-with-the-e-coli-dataset\/\">Imbalanced Multiclass Classification with the E.coli Dataset<\/a> appeared first on <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/\">Machine Learning Mastery<\/a>.<\/p>\n<\/div>\n<p><a href=\"https:\/\/machinelearningmastery.com\/imbalanced-multiclass-classification-with-the-e-coli-dataset\/\">Go to Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Jason Brownlee Multiclass classification problems are those where a label must be predicted, but there are more than two labels that may be predicted. [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/www.aiproblog.com\/index.php\/2020\/03\/15\/imbalanced-multiclass-classification-with-the-e-coli-dataset\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":3240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/3239"}],"collection":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/comments?post=3239"}],"version-history":[{"count":0,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/3239\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media\/3240"}],"wp:attachment":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media?parent=3239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/categories?post=3239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/tags?post=3239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}