{"id":3943,"date":"2020-10-06T18:00:12","date_gmt":"2020-10-06T18:00:12","guid":{"rendered":"https:\/\/www.aiproblog.com\/index.php\/2020\/10\/06\/how-to-develop-elastic-net-regression-models-in-python\/"},"modified":"2020-10-06T18:00:12","modified_gmt":"2020-10-06T18:00:12","slug":"how-to-develop-elastic-net-regression-models-in-python","status":"publish","type":"post","link":"https:\/\/www.aiproblog.com\/index.php\/2020\/10\/06\/how-to-develop-elastic-net-regression-models-in-python\/","title":{"rendered":"How to Develop Elastic Net Regression Models in Python"},"content":{"rendered":"<p>Author: Jason Brownlee<\/p>\n<div>\n<p>Regression is a modeling task that involves predicting a numeric value given an input.<\/p>\n<p>Linear regression is the standard algorithm for regression that assumes a linear relationship between inputs and the target variable. An extension to linear regression involves adding penalties to the loss function during training that encourage simpler models that have smaller coefficient values. These extensions are referred to as regularized linear regression or penalized linear regression.<\/p>\n<p><strong>Elastic net<\/strong> is a popular type of regularized linear regression that combines two popular penalties, specifically the L1 and L2 penalty functions.<\/p>\n<p>In this tutorial, you will discover how to develop Elastic Net regularized regression in Python.<\/p>\n<p>After completing this tutorial, you will know:<\/p>\n<ul>\n<li>Elastic Net is an extension of linear regression that adds regularization penalties to the loss function during training.<\/li>\n<li>How to evaluate an Elastic Net model and use a final model to make predictions for new data.<\/li>\n<li>How to configure the Elastic Net model for a new dataset via grid search and automatically.<\/li>\n<\/ul>\n<p>Let&rsquo;s get started.<\/p>\n<div id=\"attachment_10578\" style=\"width: 810px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" aria-describedby=\"caption-attachment-10578\" loading=\"lazy\" class=\"size-full wp-image-10578\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2020\/07\/How-to-Develop-Elastic-Net-Regression-Models-in-Python.jpg\" alt=\"How to Develop Elastic Net Regression Models in Python\" width=\"800\" height=\"492\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/07\/How-to-Develop-Elastic-Net-Regression-Models-in-Python.jpg 800w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/07\/How-to-Develop-Elastic-Net-Regression-Models-in-Python-300x185.jpg 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2020\/07\/How-to-Develop-Elastic-Net-Regression-Models-in-Python-768x472.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\"><\/p>\n<p id=\"caption-attachment-10578\" class=\"wp-caption-text\">How to Develop Elastic Net Regression Models in Python<br \/>Photo by <a href=\"https:\/\/flickr.com\/photos\/126654539@N08\/30388901788\/\">Phil Dolby<\/a>, some rights reserved.<\/p>\n<\/div>\n<h2>Tutorial Overview<\/h2>\n<p>This tutorial is divided into three parts; they are:<\/p>\n<ol>\n<li>Elastic Net Regression<\/li>\n<li>Example of Elastic Net Regression<\/li>\n<li>Tuning Elastic Net Hyperparameters<\/li>\n<\/ol>\n<h2>Elastic Net Regression<\/h2>\n<p>Linear regression refers to a model that assumes a linear relationship between input variables and the target variable.<\/p>\n<p>With a single input variable, this relationship is a line, and with higher dimensions, this relationship can be thought of as a hyperplane that connects the input variables to the target variable. The coefficients of the model are found via an optimization process that seeks to minimize the sum squared error between the predictions (<em>yhat<\/em>) and the expected target values (<em>y<\/em>).<\/p>\n<ul>\n<li>loss = sum i=0 to n (y_i &ndash; yhat_i)^2<\/li>\n<\/ul>\n<p>A problem with linear regression is that estimated coefficients of the model can become large, making the model sensitive to inputs and possibly unstable. This is particularly true for problems with few observations (<em>samples<\/em>) or more samples (<em>n<\/em>) than input predictors (<em>p<\/em>) or variables (so-called <em>p &gt;&gt; n problems<\/em>).<\/p>\n<p>One approach to addressing the stability of regression models is to change the loss function to include additional costs for a model that has large coefficients. Linear regression models that use these modified loss functions during training are referred to collectively as penalized linear regression.<\/p>\n<p>One popular penalty is to penalize a model based on the sum of the squared coefficient values. This is called an L2 penalty. An L2 penalty minimizes the size of all coefficients, although it prevents any coefficients from being removed from the model.<\/p>\n<ul>\n<li>l2_penalty = sum j=0 to p beta_j^2<\/li>\n<\/ul>\n<p>Another popular penalty is to penalize a model based on the sum of the absolute coefficient values. This is called the L1 penalty. An L1 penalty minimizes the size of all coefficients and allows some coefficients to be minimized to the value zero, which removes the predictor from the model.<\/p>\n<ul>\n<li>l1_penalty = sum j=0 to p abs(beta_j)<\/li>\n<\/ul>\n<p>Elastic net is a penalized linear regression model that includes both the L1 and L2 penalties during training.<\/p>\n<p>Using the terminology from &ldquo;<a href=\"https:\/\/amzn.to\/3aBTnMV\">The Elements of Statistical Learning<\/a>,&rdquo; a hyperparameter &ldquo;<em>alpha<\/em>&rdquo; is provided to assign how much weight is given to each of the L1 and L2 penalties. Alpha is a value between 0 and 1 and is used to weight the contribution of the L1 penalty and one minus the alpha value is used to weight the L2 penalty.<\/p>\n<ul>\n<li>elastic_net_penalty = (alpha * l1_penalty) + ((1 &ndash; alpha) * l2_penalty)<\/li>\n<\/ul>\n<p>For example, an alpha of 0.5 would provide a 50 percent contribution of each penalty to the loss function. An alpha value of 0 gives all weight to the L2 penalty and a value of 1 gives all weight to the L1 penalty.<\/p>\n<blockquote>\n<p>The parameter alpha determines the mix of the penalties, and is often pre-chosen on qualitative grounds.<\/p>\n<\/blockquote>\n<p>&mdash; Page 663, <a href=\"https:\/\/amzn.to\/3aBTnMV\">The Elements of Statistical Learning<\/a>, 2016.<\/p>\n<p>The benefit is that elastic net allows a balance of both penalties, which can result in better performance than a model with either one or the other penalty on some problems.<\/p>\n<p>Another hyperparameter is provided called &ldquo;<em>lambda<\/em>&rdquo; that controls the weighting of the sum of both penalties to the loss function. A default value of 1.0 is used to use the fully weighted penalty; a value of 0 excludes the penalty. Very small values of lambada, such as 1e-3 or smaller, are common.<\/p>\n<ul>\n<li>elastic_net_loss = loss + (lambda * elastic_net_penalty)<\/li>\n<\/ul>\n<p>Now that we are familiar with elastic net penalized regression, let&rsquo;s look at a worked example.<\/p>\n<h2>Example of Elastic Net Regression<\/h2>\n<p>In this section, we will demonstrate how to use the Elastic Net regression algorithm.<\/p>\n<p>First, let&rsquo;s introduce a standard regression dataset. We will use the housing dataset.<\/p>\n<p>The housing dataset is a standard machine learning dataset comprising 506 rows of data with 13 numerical input variables and a numerical target variable.<\/p>\n<p>Using a test harness of repeated stratified 10-fold cross-validation with three repeats, a naive model can achieve a mean absolute error (MAE) of about 6.6. A top-performing model can achieve a MAE on this same test harness of about 1.9. This provides the bounds of expected performance on this dataset.<\/p>\n<p>The dataset involves predicting the house price given details of the house&rsquo;s suburb in the American city of Boston.<\/p>\n<ul>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv\">Housing Dataset (housing.csv)<\/a><\/li>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.names\">Housing Description (housing.names)<\/a><\/li>\n<\/ul>\n<p>No need to download the dataset; we will download it automatically as part of our worked examples.<\/p>\n<p>The example below downloads and loads the dataset as a Pandas <a href=\"https:\/\/pandas.pydata.org\/pandas-docs\/stable\/reference\/api\/pandas.DataFrame.html\">DataFrame<\/a> and summarizes the shape of the dataset and the first five rows of data.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># load and summarize the housing dataset\r\nfrom pandas import read_csv\r\nfrom matplotlib import pyplot\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\n# summarize shape\r\nprint(dataframe.shape)\r\n# summarize first few lines\r\nprint(dataframe.head())<\/pre>\n<p>Running the example confirms the 506 rows of data and 13 input variables and a single numeric target variable (14 in total).<\/p>\n<p>We can also see that all input variables are numeric.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">(506, 14)\r\n        0     1     2   3      4      5   ...  8      9     10      11    12    13\r\n0  0.00632  18.0  2.31   0  0.538  6.575  ...   1  296.0  15.3  396.90  4.98  24.0\r\n1  0.02731   0.0  7.07   0  0.469  6.421  ...   2  242.0  17.8  396.90  9.14  21.6\r\n2  0.02729   0.0  7.07   0  0.469  7.185  ...   2  242.0  17.8  392.83  4.03  34.7\r\n3  0.03237   0.0  2.18   0  0.458  6.998  ...   3  222.0  18.7  394.63  2.94  33.4\r\n4  0.06905   0.0  2.18   0  0.458  7.147  ...   3  222.0  18.7  396.90  5.33  36.2\r\n\r\n[5 rows x 14 columns]<\/pre>\n<p>The scikit-learn Python machine learning library provides an implementation of the Elastic Net penalized regression algorithm via the <a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.linear_model.ElasticNet.html\">ElasticNet class<\/a>.<\/p>\n<p>Confusingly, the <em>alpha<\/em> hyperparameter can be set via the &ldquo;<em>l1_ratio<\/em>&rdquo; argument that controls the contribution of the L1 and L2 penalties and the <em>lambda<\/em> hyperparameter can be set via the &ldquo;<em>alpha<\/em>&rdquo; argument that controls the contribution of the sum of both penalties to the loss function.<\/p>\n<p>By default, an equal balance of 0.5 is used for &ldquo;<em>l1_ratio<\/em>&rdquo; and a full weighting of 1.0 is used for alpha.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# define model\r\nmodel = ElasticNet(alpha=1.0, l1_ratio=0.5)<\/pre>\n<p>We can evaluate the Elastic Net model on the housing dataset using <a href=\"https:\/\/machinelearningmastery.com\/k-fold-cross-validation\/\">repeated 10-fold cross-validation<\/a> and report the average mean absolute error (MAE) on the dataset.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># evaluate an elastic net model on the dataset\r\nfrom numpy import mean\r\nfrom numpy import std\r\nfrom numpy import absolute\r\nfrom pandas import read_csv\r\nfrom sklearn.model_selection import cross_val_score\r\nfrom sklearn.model_selection import RepeatedKFold\r\nfrom sklearn.linear_model import ElasticNet\r\n# load the dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\ndata = dataframe.values\r\nX, y = data[:, :-1], data[:, -1]\r\n# define model\r\nmodel = ElasticNet(alpha=1.0, l1_ratio=0.5)\r\n# define model evaluation method\r\ncv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)\r\n# evaluate model\r\nscores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)\r\n# force scores to be positive\r\nscores = absolute(scores)\r\nprint('Mean MAE: %.3f (%.3f)' % (mean(scores), std(scores)))<\/pre>\n<p>Running the example evaluates the Elastic Net algorithm on the housing dataset and reports the average MAE across the three repeats of 10-fold cross-validation.<\/p>\n<p>Your specific results may vary given the stochastic nature of the learning algorithm. Consider running the example a few times.<\/p>\n<p>In this case, we can see that the model achieved a MAE of about 3.682.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">Mean MAE: 3.682 (0.530)<\/pre>\n<p>We may decide to use the Elastic Net as our final model and make predictions on new data.<\/p>\n<p>This can be achieved by fitting the model on all available data and calling the <em>predict()<\/em> function, passing in a new row of data.<\/p>\n<p>We can demonstrate this with a complete example, listed below.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># make a prediction with an elastic net model on the dataset\r\nfrom pandas import read_csv\r\nfrom sklearn.linear_model import ElasticNet\r\n# load the dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\ndata = dataframe.values\r\nX, y = data[:, :-1], data[:, -1]\r\n# define model\r\nmodel = ElasticNet(alpha=1.0, l1_ratio=0.5)\r\n# fit model\r\nmodel.fit(X, y)\r\n# define new data\r\nrow = [0.00632,18.00,2.310,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98]\r\n# make a prediction\r\nyhat = model.predict([row])\r\n# summarize prediction\r\nprint('Predicted: %.3f' % yhat)<\/pre>\n<p>Running the example fits the model and makes a prediction for the new rows of data.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">Predicted: 31.047<\/pre>\n<p>Next, we can look at configuring the model hyperparameters.<\/p>\n<h2>Tuning Elastic Net Hyperparameters<\/h2>\n<p>How do we know that the default hyperparameters of alpha=1.0 and l1_ratio=0.5 are any good for our dataset?<\/p>\n<p>We don&rsquo;t.<\/p>\n<p>Instead, it is good practice to test a suite of different configurations and discover what works best.<\/p>\n<p>One approach would be to gird search <em>l1_ratio<\/em> values between 0 and 1 with a 0.1 or 0.01 separation and <em>alpha<\/em> values from perhaps 1e-5 to 100 on a log-10 scale and discover what works best for a dataset.<\/p>\n<p>The example below demonstrates this using the <a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.model_selection.GridSearchCV.html\">GridSearchCV<\/a> class with a grid of values we have defined.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># grid search hyperparameters for the elastic net\r\nfrom numpy import arange\r\nfrom pandas import read_csv\r\nfrom sklearn.model_selection import GridSearchCV\r\nfrom sklearn.model_selection import RepeatedKFold\r\nfrom sklearn.linear_model import ElasticNet\r\n# load the dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\ndata = dataframe.values\r\nX, y = data[:, :-1], data[:, -1]\r\n# define model\r\nmodel = ElasticNet()\r\n# define model evaluation method\r\ncv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)\r\n# define grid\r\ngrid = dict()\r\ngrid['alpha'] = [1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 0.0, 1.0, 10.0, 100.0]\r\ngrid['l1_ratio'] = arange(0, 1, 0.01)\r\n# define search\r\nsearch = GridSearchCV(model, grid, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)\r\n# perform the search\r\nresults = search.fit(X, y)\r\n# summarize\r\nprint('MAE: %.3f' % results.best_score_)\r\nprint('Config: %s' % results.best_params_)<\/pre>\n<p>Running the example will evaluate each combination of configurations using repeated cross-validation.<\/p>\n<p>You might see some warnings that can be safely ignored, such as:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">Objective did not converge. You might want to increase the number of iterations.<\/pre>\n<p>Your specific results may vary given the stochastic nature of the learning algorithm. Try running the example a few times.<\/p>\n<p>In this case, we can see that we achieved slightly better results than the default 3.378 vs. 3.682. Ignore the sign; the library makes the MAE negative for optimization purposes.<\/p>\n<p>We can see that the model assigned an alpha weight of 0.01 to the penalty and focuses exclusively on the L2 penalty.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">MAE: -3.378\r\nConfig: {'alpha': 0.01, 'l1_ratio': 0.97}<\/pre>\n<p>The scikit-learn library also provides a built-in version of the algorithm that automatically finds good hyperparameters via the <a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.linear_model.ElasticNetCV.html\">ElasticNetCV<\/a> class.<\/p>\n<p>To use this class, it is first fit on the dataset, then used to make a prediction. It will automatically find appropriate hyperparameters.<\/p>\n<p>By default, the model will test 100 alpha values and use a default ratio. We can specify our own lists of values to test via the &ldquo;<em>l1_ratio<\/em>&rdquo; and &ldquo;<em>alphas<\/em>&rdquo; arguments, as we did with the manual grid search.<\/p>\n<p>The example below demonstrates this.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># use automatically configured elastic net algorithm\r\nfrom numpy import arange\r\nfrom pandas import read_csv\r\nfrom sklearn.linear_model import ElasticNetCV\r\nfrom sklearn.model_selection import RepeatedKFold\r\n# load the dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\ndata = dataframe.values\r\nX, y = data[:, :-1], data[:, -1]\r\n# define model evaluation method\r\ncv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)\r\n# define model\r\nratios = arange(0, 1, 0.01)\r\nalphas = [1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 0.0, 1.0, 10.0, 100.0]\r\nmodel = ElasticNetCV(l1_ratio=ratios, alphas=alphas, cv=cv, n_jobs=-1)\r\n# fit model\r\nmodel.fit(X, y)\r\n# summarize chosen configuration\r\nprint('alpha: %f' % model.alpha_)\r\nprint('l1_ratio_: %f' % model.l1_ratio_)<\/pre>\n<p>Your specific results may vary given the stochastic nature of the learning algorithm. Try running the example a few times.<\/p>\n<p>Again, you might see some warnings that can be safely ignored, such as:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">Objective did not converge. You might want to increase the number of iterations.<\/pre>\n<p>In this case, we can see that an alpha of 0.0 was chosen, removing both penalties from the loss function.<\/p>\n<p>This is different from what we found via our manual grid search, perhaps due to the systematic way in which configurations were searched or selected.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">alpha: 0.000000\r\nl1_ratio_: 0.470000<\/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>Books<\/h3>\n<ul>\n<li><a href=\"https:\/\/amzn.to\/3aBTnMV\">The Elements of Statistical Learning<\/a>, 2016.<\/li>\n<li><a href=\"https:\/\/amzn.to\/38uGJOl\">Applied Predictive Modeling<\/a>, 2013.<\/li>\n<\/ul>\n<h3>APIs<\/h3>\n<ul>\n<li><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.linear_model.ElasticNet.html\">sklearn.linear_model.ElasticNet API<\/a>.<\/li>\n<li><a href=\"https:\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn.linear_model.ElasticNetCV.html\">sklearn.linear_model.ElasticNetCV API<\/a>.<\/li>\n<\/ul>\n<h3>Articles<\/h3>\n<ul>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Elastic_net_regularization\">Elastic net regularization, Wikipedia<\/a>.<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>In this tutorial, you discovered how to develop Elastic Net regularized regression in Python.<\/p>\n<p>Specifically, you learned:<\/p>\n<ul>\n<li>Elastic Net is an extension of linear regression that adds regularization penalties to the loss function during training.<\/li>\n<li>How to evaluate an Elastic Net model and use a final model to make predictions for new data.<\/li>\n<li>How to configure the Elastic Net model for a new dataset via grid search and automatically.<\/li>\n<\/ul>\n<p><strong>Do you have any questions?<\/strong><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\/elastic-net-regression-in-python\/\">How to Develop Elastic Net Regression Models in Python<\/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\/elastic-net-regression-in-python\/\">Go to Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Jason Brownlee Regression is a modeling task that involves predicting a numeric value given an input. Linear regression is the standard algorithm for regression [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/www.aiproblog.com\/index.php\/2020\/10\/06\/how-to-develop-elastic-net-regression-models-in-python\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":3944,"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\/3943"}],"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=3943"}],"version-history":[{"count":0,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/3943\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media\/3944"}],"wp:attachment":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media?parent=3943"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/categories?post=3943"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/tags?post=3943"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}