前面我们讲了二元逻辑回归问题。现在来讨论多元逻辑回归问题。考虑一下,如果我们的返回值不是0,1,而是0,1,2,或者是“好”,“中”,“差”,那么要如何使用逻辑回归来进行预测呢?根据之前的二元逻辑回归的思路,我们可以划分多个阈值来实现。例如,0~0.3 归为0,0.3~0.6 归为1,0.6~1归为2,等等。
医学研究、社会科学领域中, 存在因变量是多项的情况, 其中又分为无序(口味:苦、 甜、 酸、 辣;科目:数学、 自然、 语文、 英语) 和有序(辣度:微辣、 中辣、 重辣) 两类。
对于有序多元逻辑回归,我们可以通过划分多个阈值来实现。例如,0~0.3 归为微辣,0.3~0.6 归为中辣,0.6~1归为重辣,等等。
对于无序多元逻辑回归,我们可建立K-1个二元回归模型(其中k表示类别个数)。给定一个数据点,K-1个模型都会运行,概率最大的类别将会被选为预测类别。对于输入点x,分类结果为各类别的概率分别为如下公式:
在R中,有序逻辑回归可以使用MASS::polr 函数来进行模型预测:
#读取数据
wine <- read.csv("winequality-white.csv", sep=";")
#由于wine的品质有1,2,3,4,5,6,7 等多种类型,但是实际上我们不需要这么多类型
#我们只需要划分好、中、坏三种类型,因此我哦们可以使用如下方法来将原来的7种类型重新划分为3种类型
#小于5的归为0,大于6的归为2,其余归位1。
wine$quality <- factor(ifelse(wine$quality < 5, 0, ifelse(wine$quality > 6, 2, 1)))
#划分测试集和训练集
set.seed(7644)
wine_sampling_vector <- createDataPartition(wine$quality, p = 0.80, list = FALSE)
wine_train <- wine[wine_sampling_vector,]
wine_test <- wine[-wine_sampling_vector,]
#使用polr函数来进行有序逻辑回归
library(MASS)
wine_model <- polr(quality ~., data = wine_train, Hess=T)
#查看回归结果
summary(wine_model)
Call:
polr(formula = quality ~ ., data = wine_train, Hess = T)
Coefficients:
Value Std. Error t value
fixed.acidity 3.067e-01 0.055939 5.4828
volatile.acidity -4.239e+00 0.430971 -9.8357
citric.acid -1.517e-01 0.356087 -0.4261
residual.sugar 2.622e-01 0.009930 26.4073
chlorides -3.288e+00 2.061758 -1.5947
free.sulfur.dioxide 1.391e-02 0.003157 4.4050
total.sulfur.dioxide 4.811e-04 0.001396 0.3447
density -5.443e+02 0.651263 -835.7740
pH 2.316e+00 0.303956 7.6187
sulphates 2.155e+00 0.337039 6.3936
alcohol 2.820e-01 0.043573 6.4724
Intercepts:
Value Std. Error t value
0|1 -530.5911 0.6625 -800.8336
1|2 -525.0512 0.6849 -766.5609
Residual Deviance: 4419.114
AIC: 4445.114
对于有序逻辑回归,如果有K个类别,需要对一个二元逻辑回归模型
的输出设置K-1个阈值。该模型用决定该直线斜率的一组系数,但是包含K-1个截距项。
从上面的结果我们可以看到,我们有3个类别,产生了两个截距项。关于有序逻辑回归的更多解释,可以参考《有序logistic回归》
无序逻辑回归,可以使用glmnet::multinorm函数来预测:
#读取数据
glass <- read.csv("glass.data", header=FALSE)
#重命名属性
names(glass) <- c("id","RI","Na", "Mg", "Al", "Si", "K", "Ca", "Ba", "Fe", "Type")
#去掉第一列(ID不是特征)
glass <- glass[,-1]
#划分训练集和测试集
set.seed(4365677)
glass_sampling_vector <- createDataPartition(glass$Type, p = 0.80, list = FALSE)
glass_train <- glass[glass_sampling_vector,]
glass_test <- glass[-glass_sampling_vector,]
#使用multinom函数来进行多元逻辑回归
library(nnet)
glass_model <- multinom(Type ~ ., data = glass_train)
#查看模型结果
summary(glass_model)
Call:
multinom(formula = Type ~ ., data = glass_train)
Coefficients:
(Intercept) RI Na Mg Al Si
2 88.38269 157.08023 -2.3673886 -5.0267504 0.877379 -3.41913137
3 47.39946 -55.92268 1.4463655 0.9474131 4.217085 -0.02663305
5 19.09162 12.18003 -0.4994562 -3.4609854 10.512980 -0.47914302
6 -11.58902 -16.49982 -1.4285456 -4.9773258 50.073683 0.58528791
7 -33.94812 35.21297 2.1003583 -5.1605090 6.518912 -0.32453356
K Ca Ba Fe
2 -2.4824078 -3.4529191 -4.798335 3.9004356
3 -0.4554840 1.1770520 -2.261806 3.5402764
5 0.2840309 -0.4108929 -3.670666 -0.3565494
6 -182.0373775 -2.3927701 -191.362765 -360.1904720
7 -0.4393933 -2.2908750 -2.934206 -16.2597361
Std. Errors:
(Intercept) RI Na Mg Al Si K
2 0.13873234 0.34942950 0.5375687 0.7813359 1.3757878 0.1361653 1.84414502
3 0.06148251 0.09974268 0.7592587 1.3621772 1.8285346 0.1929260 2.40562605
5 0.04973139 0.10197329 0.7925746 1.1559582 2.5560426 0.2200123 2.35769251
6 0.01983548 0.02146023 3.4573795 4.5301804 0.5130094 0.3330953 0.07282538
7 0.19802113 0.42883613 1.0163134 1.2334636 2.2783457 0.2240136 2.35104838
Ca Ba Fe
2 0.4961426 2.270415e+00 2.282575e+00
3 0.6614129 4.653237e+00 3.326838e+00
5 0.8039363 2.442393e+00 4.765766e+00
6 6.7453264 1.197158e-08 1.960701e-13
7 0.9515986 2.627772e+00 1.913829e+01
Residual Deviance: 246.4441
AIC: 346.4441
#查看训练集的回归结果
glass_predictions <- predict(glass_model, glass_train)
mean(glass_predictions==glass_train$Type)
table(predicted=glass_predictions,actual=glass_train$Type)
#查看测试集的回归结果
glass_test_predictions <- predict(glass_model, glass_test)
mean(glass_test_predictions==glass_test$Type)
table(predicted = glass_test_predictions,actual =glass_test$Type)
可以看到,原来有6个类别(1,2,3,5,6,7),生成了5个模型(2,3,5,6,7)。其原因是,多项逻辑回归的原理是,在结果变量的类别中,会选择一个类别作为参考类别,其他各个类别的系数结果都是以参考类别作为参考(即定义为1),进一步计算及进行诠释。其实在二分类的逻辑回归中,我们也应用到了这一点,0/1变量中,我们默认的0是参考类别,1是感兴趣类别。但是由于二分类结果没有第三个类别,所以不需要额外提出所谓的参考和非参考类别。但是多项逻辑回归就有所不同,有多个类别在结果变量,需要考虑参考类别的选择。
关于模型结果的解读,这里不再细述,可以参考这篇文章:《R-多项逻辑回归/多类别逻辑回归》
当然,对于有序多元逻辑回归,我们也可以采用多分类器的方法来进行回归预测。只是实现原理不同而已。
#采用多分类器的方法来进行回归预测
wine_model2 <- multinom(quality ~ ., data = wine_train, maxit=1000)
wine_predictions2 <- predict(wine_model2, wine_test)
mean(wine_predictions2==wine_test$quality)
table(predicted=wine_predictions2,actual=wine_test$quality)
#比较两种分类器的优劣
AIC(wine_model)
AIC(wine_model2)
#对于有序逻辑回归,我们也可以使用step函数来进行参数的选择(这里默认是向后剔除)
wine_model3 <- step(wine_model)
wine_test_predictions3 <- predict(wine_model3, wine_test)
mean(wine_test_predictions3==wine_test$quality)
table(predicted = wine_test_predictions3,actual =wine_test$quality)