# LogitModelFit to predict a categorical variable

I am trying to predict life expectancy based on GDP per capita and literacy rate. Life expectancy is coded as low and high, and the two predictor variables are numerical.

Here is some sample data:

data = {{"GDP", "Literacy", "LifeExpectancy"}, {3948.34, 81.4078, "high"}, {2973.59,
66.0301, "low"}, {1219.43, 42.3624, "low"}, {7961.34, 86.8232,
"low"}, {774.84, 41.2245, "low"}, {261.247, 68.3753,
"low"}, {1497.91, 77.071, "low"}, {3603.78, 86.7903,
"high"}, {467.907, 37.3958, "low"}, {709.54, 22.3116,
"low"}, {1393.52, 58.817, "low"}, {545.216, 77.0427,
"low"}, {3408.85, 67.9, "low"}, {3020.03, 71.1683,
"high"}, {8131.92, 95, "low"}, {642.508, 76.5705, "low"}, {3224.39,
83.0983, "low"}};


I tried setting up the model the following way, but I get an error message.

lm =
LogitModelFit[data[[2 ;;, {1, 2, 3}]],
{x, y},
{x, y}]


LogitModelFit::notdata: The first argument is not a vector, matrix, or a list containing a design matrix and response vector.

I have tried changing low -> 0 and high -> 1 and running the model again, but it does not allow me to predict which life expectancy group a person will be in depending on changes in the predictor variables.

• I think you're right that LogitModelFit is expecting numeric data instead of the strings "low" and "high". Unfortunately, I'm not an expert in this sort of problem. There are others on this site who know more, and I hope they can help you. Commented Feb 25, 2022 at 16:02

Changing to 0 and 1 is necessary:

data = {{"GDP", "Literacy", "LifeExpectancy"}, {3948.34, 81.4078, "high"},
{2973.59, 66.0301, "low"}, {1219.43, 42.3624, "low"}, {7961.34, 86.8232, "low"},
{774.84, 41.2245, "low"}, {261.247, 68.3753, "low"}, {1497.91, 77.071, "low"},
{3603.78, 86.7903, "high"}, {467.907, 37.3958, "low"}, {709.54, 22.3116, "low"},
{1393.52, 58.817, "low"}, {545.216, 77.0427, "low"}, {3408.85, 67.9, "low"},
{3020.03, 71.1683, "high"}, {8131.92, 95, "low"}, {642.508, 76.5705, "low"},
{3224.39, 83.0983, "low"}};

data = data /. "low" -> 0 /. "high" -> 1;

lm = LogitModelFit[data[[2 ;;]], {GDP, Literacy}, {GDP, Literacy}];
lm["ParameterTable"]


To make a prediction where GDP = 3000 and Literacy = 35

lm[3000, 35]
(* 0.00887439 *)


Plotting the data is also essential. Given that you just have 2 predictor, this is made easy:

low = Select[data, #[[3]] == 0 &][[All, {1, 2}]];
high = Select[data, #[[3]] == 1 &][[All, {1, 2}]];
ListPlot[{low, high}, PlotRange -> All, PlotStyle -> PointSize[0.02],
AxesLabel -> {"GDP", "Literacy"}, PlotLegends -> {"Low", "High"}]


To see all of the predictions of the probability of a high life expectancy, use ContourPlot:

ContourPlot[lm[GDP, Literacy], {GDP, 150, 8200}, {Literacy, 20, 100},
Contours -> Range[9]/10., ContourLabels -> True,
FrameLabel -> (Style[#, Bold, 18] &) /@ {"GDP", "Literacy"}]


A slightly more complicated model fits the limited data better but likely doesn't make much sense:

lm2 = LogitModelFit[data[[2 ;;]], {GDP, Literacy, GDP*Literacy}, {GDP, Literacy}];
lm2["ParameterTable"]


low = Select[data, #[[3]] == 0 &][[All, {1, 2}]];
high = Select[data, #[[3]] == 1 &][[All, {1, 2}]];
Show[ContourPlot[lm2[GDP, Literacy], {GDP, 150, 8200}, {Literacy, 20, 100},
Contours -> Range[9]/10., ContourLabels -> True,
FrameLabel -> (Style[#, Bold, 18] &) /@ {"GDP", "Literacy"},
ContourStyle -> Gray, ContourShading -> None],
ListPlot[{low, high}, PlotRange -> All, PlotStyle -> PointSize[0.03],
AxesLabel -> {"GDP", "Literacy"}, PlotLegends -> {"Low", "High"}]]


• So with the example you provided, with a GDP of 3000 and literacy of 35%, the odds of having a high life expectancy is 0.009? Commented Feb 26, 2022 at 7:38
• With the data you provided the estimate of the probability (and NOT the odds) of a high life expectancy is 0.009 for a GDP of 3000 and literacy of 35%. The odds would be 0.009/(1-0.009). Also note that if there were no covariates, the estimate of the probability of a high life expectancy is just 3/17 = 0.1764706. And neither of the covariates are statistically significant.
– JimB
Commented Feb 26, 2022 at 16:26