原文链接:http://tecdat.cn/?p=22966
逻辑回归是一种拟合回归曲线的方法,y=f(x),当y是一个分类变量时。这个模型的典型用途是在给定一组预测因素x的情况下预测y,预测因素可以是连续的、分类的或混合的。
一般来说,分类变量y可以是不同的值。在最简单的情况下,y是二进制的,意味着它可以是1或0的值。机器学习中使用的一个经典例子是电子邮件分类:给定每封电子邮件的一组属性,如字数、链接和图片,算法应该决定该电子邮件是垃圾邮件(1)或不是(0)。
在这篇文章中,我们把这个模型称为 "二项逻辑回归",因为要预测的变量是二进制的,然而,逻辑回归也可以用来预测一个可以两个以上数值的因变量。在这第二种情况下,我们称该模型为 "多项式逻辑回归"。例如,一个典型的例子是将电影分为 "搞笑片"、"纪录片 "或 "剧情片"等。
R中的逻辑Logistic回归实现
R使拟合一个逻辑回归模型变得非常容易。要调用的函数是glm(),其拟合过程与线性回归中使用的函数没有太大区别。在这篇文章中,我将拟合一个二元逻辑回归模型并解释每个步骤。
数据集
我们将在泰坦尼克号数据集上工作。这个数据集在网上有不同的版本,但是我建议使用Kaggle提供的版本,因为它几乎已经可以使用了(为了下载它,你需要在Kaggle注册)。 数据集(训练)是一些乘客(准确的说是889人)的数据集合,比赛的目标是根据一些特征,如服务等级、性别、年龄等来预测生存率(如果乘客幸存下来就是1,如果没有就是0)。正如你所看到的,我们将同时使用分类和连续变量。
数据清理过程
在处理真实的数据集时,我们需要考虑到一些数据可能丢失的情况,因此我们需要为我们的分析准备数据集。作为第一步,我们使用read.csv()函数加载csv数据。 确保参数na.strings等于c(""),这样每个缺失值都被编码为NA。
加载和预处理数据
现在我们需要检查缺失值,并使用sapply()函数查看每个变量有多少个唯一值,该函数将作为参数传递的函数应用于数据框的每一列。
代码语言:javascript复制sapply(function(x) sum(is.na(x)))
代码语言:javascript复制sapply(function(x) length(unique(x)))
绘制数据集并突出缺失值。
代码语言:javascript复制map(training)
处理缺失值
变量cabin有太多的缺失值,不使用它。我们也剔除PassengerId,因为它只是一个索引。 使用subset()函数,对原始数据集进行子集,只选择相关列。
现在需要考虑其他的缺失值。在拟合广义线性模型时,R可以通过在拟合函数中设置一个参数来处理它们。
然而,我个人更喜欢 "手动"替换缺失值。有不同的方法可以做到这一点,一个典型的方法是用平均数、中位数或现有数值来替换缺失的数值。我使用平均数。
代码语言:javascript复制Age[is.na(Age)] <- mean(Age,na.rm=T) ## 用平均数代替缺失
就分类变量而言,使用read.table()或read.csv()默认会把分类变量编码为因子。因子是R处理分类变量的方式。我们可以使用以下几行代码来检查编码情况。
为了更好地了解R是如何处理分类变量的,我们可以使用contrasts()函数。这个函数向我们展示变量是如何虚拟出来的,以及如何在模型中解释它们。
例如,你可以看到,在性别这个变量中,女性将被用作参考变量。Embarked中的缺失值,由于只有两个,我们将剔除这两行(我们也可以替换缺失值,保留数据点)。
代码语言:javascript复制data[!is.na(Embarked),]
在进行拟合之前,数据的清洗和格式化很重要。这个预处理步骤对于获得良好的模型拟合和更好的预测能力是非常重要的。
模型拟合
我们把数据分成两部分:训练集和测试集。训练集将被用来拟合我们的模型,我们将在测试集上进行测试。
代码语言:javascript复制##现在,让我们来拟合这个模型。请务必在glm()函数中指定参数family=binomial。
glm(Survived ~.,family=binomial(link='logit'))
##通过使用函数summary(),我们得到了我们模型的结果。
解释我们的逻辑回归模型的结果
首先,我们可以看到,SibSp、票价都没有统计学意义。至于有统计学意义的变量,性别的P值最低,表明乘客的性别与存活的概率有很大关系。这个预测因素的负系数表明,在所有其他变量相同的情况下,男性乘客生存的可能性较小。请记住,在Logit模型中,反应变量是对数几率:ln(odds) = ln(p/(1-p)) = ax1 bx2 。 z*xn。
由于男性是一个虚拟变量,所以男性会使对数几率减少2.75,而年龄增加一个单位会使对数几率减少0.037。
现在我们可以对模型分析偏差表
无效偏差和_残差_之间的差异显示了我们的模型与空模型(只有截距的模型)的对比情况。这个差距越大越好。分析该表,我们可以看到逐一添加每个变量时_残差_的下降。同样,加入Pclass、Sex和Age可以明显减少残差。尽管SibSp的p值很低,但其他变量似乎对模型的改善较少。这里的大p值表明,没有变量的模型或多或少解释了相同数量的变化。最终,我们希望看到的是_残差_和AIC的明显下降。
虽然不存在与线性回归的R2完全等同的指标,但麦克法登R2指数可以用来评估模型的拟合度。
评估模型的预测能力
在上面的步骤中,我们简要地评估了模型的拟合情况,现在我们想看看在新的数据集上预测y时,模型的表现如何。通过设置参数type='response',R将以P(y=1|X)的形式输出概率。我们的决策边界将是0.5。如果P(y=1|X)>0.5,那么y=1,否则y=0。
代码语言:javascript复制Error <- mean(fitted != Survived)
print(paste('准确度',1- Error))
测试集上0.84的准确度是一个相当不错的结果。然而,请记住,这个结果在一定程度上取决于我先前对数据的手动分割,因此,如果想得到一个更精确的分数,最好运行某种交叉验证,如k-fold交叉验证。
作为最后一步,我们将绘制ROC曲线并计算AUC(曲线下面积),这是二元分类器的典型性能测量。
ROC是在不同的阈值设置下,通过绘制真阳性率(TPR)与假阳性率(FPR)产生的曲线,而AUC是ROC曲线下的面积。根据经验,一个具有良好预测能力的模型的AUC应该比0.5更接近于1(1是理想的)。
代码语言:javascript复制performance( measure = "tpr", x.measure = "fpr")
plot(prf)
代码语言:javascript复制auc