线性模型-分类模型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性模型-分类模型相关的知识,希望对你有一定的参考价值。

参考技术A

线性模型也可用于分类问题。我们首先来看二分类。我们可以利用下面的公式预测:

y^=w[0]x[0]+w[1]x[1]+...+w[p]*x[p]+b>0

这个公式与线性回归的公式非常相似,但我们没有返回特征的加权求和,而是为预测设置了阈值(0)。如果函数值小于0,我们就预测类别-1,如果函数值大于0,我们就预测类别+1。对于所有用于分类的线性模型,这个预测规则都是通用的。同样,有很多不同的方法来找出系数(w)和截距(b)。
对于用于回归的线性模型,输出y^是特征的线性函数,是直线、平面或超平面(对于更高维的数据集)。对于用于分类的线性模型, 决策边界 是输入的线性函数。换句话说,(二元)线性分类器是利用直线、平面或超平面来分开两个类别的分类器。
学习线性模型有很多种算法。这些算法的区别在于以下两点:
1.系数和截距的特定组合对训练数据拟合好坏的度量方法;
2.是否使用正则化,以及使用哪种正则化方法。
不同的算法使用不同的方法来度量“对训练集拟合好坏”。由于数学上的技术原因,不可能调节w和b使得算法产生的误分类数量最少。对于我们的目的,以及对于许多有用而言,上面第一点(称为 损失函数 )的选择并不重要。
最常见的两种线性分类算法是 Logistic回归(logistic regression) 线性支持向量机(linear support vector machine,线性SVM)

Python version:3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)]
pandas version:0.23.4
matplotlib version:3.0.2
Numpy version:1.15.4
Scipy version:1.1.0
IPython version:7.2.0
scikit-learn version:0.20.1

对于LogisticRegression和LinearSVC,决定正则化强度的权衡参数叫作C。C值越大,对应的正则化越弱。换句话说,如果参数C值较大,那么LogisticRegression和LinearSVC将尽可能将训练集拟合到最好,而如果C值较小,那么模型更强调使系数向量(w)接近于0。
参数C的作用还有另一个有趣之处。较小的C值可以让算法尽量适应“大多数”数据点,而较大的C值强调每个数据点都分类正确的重要性。
mglearn.plots.plot_linear_svc_regularization()

Training set score:0.953
Test set score:0.958
C=1的默认值给出了相当好的性能,在训练集和测试集上都达到95%的精度。但由于训练集和测试集的性能非常接近,所以模型很可能是欠拟合的。我们尝试增大C来拟合一个更灵活的模型:

Training set score:0.972
Test set score:0.965
使用C=100可以得到更高的训练集精度,也得到了稍高的测试集精度,这也证实了我们的直觉,即更复杂的模型应该性能更好。

Training set score:0.934
Test set score:0.930
最后,看一下正则化参数C取三个不同的值模型学到的系数:

LogisticRegression模型默认应用L2正则化。更强的正则化使的系数更趋向于0,但系数永远不会正好等于0。进一步观察图像,还可以第3个系数那里发现有趣之处,这个系数是“平均周长”(mean perimeter)。C=100和C=1时这个系数为正,其绝对值比C=1时还要大。在解释这样的模型时,系数可以告诉我们某个特征与哪个类别有关。例如,人们可能会认为高“纹理错误”(texture error)特征与“恶性”样本有关。但“平均周长”系数的正负号发生变化,说明较大的“平均周长”可以被当作“良性”的指标或“恶性”的指标,具体取决于我们考虑的是哪个模型。这也说明,对线性模型系数的解释应该始终持保留态度。
如果想要一个可解释性更强的模型,使用L1正则化可能更好,因为它约束模型只使用少数几个特征:

Training accuracy of l1 logreg with C=0.001:0.91
Test accuracy of l1 logreg with C=0.001:0.92
Training accuracy of l1 logreg with C=1.000:0.96
Test accuracy of l1 logreg with C=1.000:0.96
Training accuracy of l1 logreg with C=100.000:0.99
Test accuracy of l1 logreg with C=100.000:0.98

将二分类算法推广到多分类算法的一种常见方法是“一对多余”(one-vs.-rest)方法。在“一对多余”方法中,对每个类别都学习一个二分类模型,将这个类别与所有其他类别尽量分开,这样就生成了与类别格式一样多的二分类偶像。在测试点上运行所有二分类器来进行预测。在对应类别上分数最高的分类器“胜出”,将这个类别标签返回作为预测结果。
每个类别都对应一个二类分类器,这样每个类别都有一个系数(w)向量与一个截距(b)。
我们将“一对多余”方法应用在一个简单的三分类数据集上。我们用到了一个二维数据集,每个类别的数据都是从一个高斯分布中采样得出的:

在上面的数据集上训练一个LinearSVC分类器:

Coefficient shape: (3, 2)
Intercept shape: (3,)
我们看到,coef_的形状是(3,2),说明coef_每行包含三个类别之一的系数向量,每列包含某个特征(这个数据集有2个特征)对应的系数值。现在intercetp_是一维数组,保存每个类别的截距,我们将这3个二分类器给出的直线可视化:

你可以看到,训练集中所有属于类别0的点都在类别0对应的直线上方,这说明它们位于这个二分类器属于“类别0”的那一侧。属于类别0的点位于与类别2对应的直线上方,这说明它们被类别2的二分类器划为“其余”。属于类别0的点位于与类别1对应的直线左侧,这说明类别1的二元分类器将它们划为“其余”。因此,这一区域的所有点都会被最终分类器划为类别0(类别0的分类器的分类置信方程的结果大于0,其他两个类别对应的结果小于0)。
但图像中间的三角形区域属于哪一个类别呢,3个分类器都将这一区域内的点划为“其余”。这里的点应该应该划归到哪一个类别呢?答案是分类方程结果最大的那个类别,即最接近的那条线对应的类别。

线性模型的主要参数是正则化参数,在回归模型中叫作alpha,在LinearSVC和LogisticRegression中叫作C。alpha值较大或C值较小,说明模型比较简单。特别是对于回归模型而言,调节这些参数非常重要。通常在对数尺度上对C和alpha进行搜索。你还需要确定的是用L1正则化还是L2正则化。如果你假定只有几个特征是真正重要的,那么你应该用的是L1正则化,否则默认使用L2正则化。如果模型的可解释性很重要的话,使用L1也会有帮助。由于L1只用到几个特征,所以更容易解释哪些特征对模型时重要的,以及这些特征的作用。
线性模型的训练速度非常快,预测速度也很快。这种模型可以推广到非常大的数据集,对稀疏数据也很有效。如果你的数据包含数十万甚至上百万个样本,你可能需要研究使用LogisticRegression和Ridge模型的solver=\'sag\'选项,在处理大型数据时,这一选项比默认值要更快。其他选项还有SGDClassifier类和SGDRegressor类,它们对线性模型实现了可扩展性更强的版本。
线性模型的另一个优点在于,利用我们之前见过的用于回归和分类的公式,理解如何进行预测是相对比较容易的。不幸的是,往往并不完全清楚系数为什么是这样的。如果你的数据集中包含高度相关的特征,这一问题尤为突出。在这种情况下,可能很难对系数做出解释。
如果特征数量大于样本数量,线性模型的表现通常都很好。它也常用于非常大的数据集,只是尤为训练其他模型并不可行。但在更低维的空间中,其他模型的泛化性能可能更好。

R中具有虚拟(因)变量和分类(独立)变量的线性回归模型

【中文标题】R中具有虚拟(因)变量和分类(独立)变量的线性回归模型【英文标题】:Linear Regression model with dummy (dependent) variable and categorical (independent) variable in R 【发布时间】:2021-07-29 08:02:29 【问题描述】:

我的数据是虚拟变量(1 = 如果公开,0 = 未公开)作为因变量,分类变量(五种行业)作为自变量。

有了这些数据,可以用线性回归模型吗?

我的目标是确定哪些部门披露或不披露。

那么是不是很好用呢?例如:

summary(lm(Disclosed ~ 0 + Sectors, data = df_0))

我在模型中添加“0 +”,使其也返回第一个扇区,消除截距。如果我不添加它,我不知道为什么第一个扇区不返回给我。我很失落。谢谢!

如果我使用二项式逻辑回归,则我通过它所指示的估计符号获得的显着性值将不会被解释。

Call:
glm(formula = Disclosed ~ 0 + Sectors, family = binomial(link = "logit"), 
    data = df_0)

Deviance Residuals: 
     Min        1Q    Median        3Q       Max  
-0.96954  -0.32029  -0.00005  -0.00005   2.48638  

Coefficients:
                         Estimate Std. Error z value Pr(>|z|)    
SectorsCOMMUNICATION      -0.5108     0.5164  -0.989  0.32256    
SectorsCONSIMERSTAPLES   -20.5661  6268.6324  -0.003  0.99738    
SectorsCONSUMERDISCRET    -3.0445     1.0235  -2.975  0.00293 ** 
SectorsENERGY            -20.5661  3780.1276  -0.005  0.99566    
SectorsFINANCIALS         -2.9444     0.7255  -4.059 4.94e-05 ***
SectorsHEALTHCARE        -20.5661  5345.9077  -0.004  0.99693    
SectorsINDUSTRIALS       -20.5661  2803.4176  -0.007  0.99415    
SectorsINDUSTRIALS       -20.5661 17730.3699  -0.001  0.99907    
SectorsINFORMATION        -1.0986     0.8165  -1.346  0.17846    
SectorsMATERIALS         -20.5661  3780.1276  -0.005  0.99566    
SectorsREALESTATE        -20.5661  8865.1850  -0.002  0.99815    
SectorsUTILITIES         -20.5661  7238.3932  -0.003  0.99773    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 277.259  on 200  degrees of freedom
Residual deviance:  54.185  on 188  degrees of freedom
AIC: 78.185

Number of Fisher Scoring iterations: 19

这意味着金融和非必需消费品行业的披露最少,对吧?

另一方面,如果我应用 lm,它会返回更一致的结果。传播最多的部门是信息和通信。它们是显着的正估计值

Call:
lm(formula = Disclosed ~ 0 + Sectors, data = df_0)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.3750 -0.0500  0.0000  0.0000  0.9546 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)    
SectorsCOMMUNICATION   3.750e-01  5.191e-02   7.224 1.22e-11 ***
SectorsCONSIMERSTAPLES 0.000e+00  7.341e-02   0.000 1.000000    
SectorsCONSUMERDISCRET 4.545e-02  4.427e-02   1.027 0.305815    
SectorsENERGY          0.000e+00  4.427e-02   0.000 1.000000    
SectorsFINANCIALS      5.000e-02  3.283e-02   1.523 0.129426    
SectorsHEALTHCARE      0.000e+00  6.260e-02   0.000 1.000000    
SectorsINDUSTRIALS     2.194e-18  3.283e-02   0.000 1.000000    
SectorsINDUSTRIALS     0.000e+00  2.076e-01   0.000 1.000000    
SectorsINFORMATION     2.500e-01  7.341e-02   3.406 0.000807 ***
SectorsMATERIALS       0.000e+00  4.427e-02   0.000 1.000000    
SectorsREALESTATE      0.000e+00  1.038e-01   0.000 1.000000    
SectorsUTILITIES       1.416e-17  8.476e-02   0.000 1.000000    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2076 on 188 degrees of freedom
Multiple R-squared:  0.2632,    Adjusted R-squared:  0.2162 
F-statistic: 5.597 on 12 and 188 DF,  p-value: 3.568e-08

【问题讨论】:

考虑运行概率模型,例如logistic regressionprobit regression 您可能想要使用逻辑回归,您可以通过添加family = "binomial" 作为lm 的参数来实现。 如果我指出它是二项式,它会返回以下错误:In lm.fit (x, y, offset = offset, singular.ok = singular.ok, ...): The additional argument `` family '' will be ignored. 【参考方案1】:

对于这个特定问题,最好使用逻辑回归。

关于线性回归输出,对于分类输入(自变量),lm 将按字母顺序排列的第一类/类别作为intercept 中显示的基类,并返回其他类的相对结果。

在示例中,类别A 将被拦截,我们将获得其他类与类A 的相对结果

例如,

set.seed(100)

a <- sample(c(1,0), 100, replace = TRUE)
b <- sample(c('A', 'B', 'C', 'D', 'E'), 100, replace = TRUE)

lm(a ~ b)
Call:
lm(formula = a ~ b)

Coefficients:
(Intercept)           bB           bC           bD           bE  
   0.562500    -0.183190     0.104167    -0.107955    -0.006944  

相同
Call:
lm(formula = a ~ 0 + b)

Coefficients:
    bA      bB      bC      bD      bE  
0.5625  0.3793  0.6667  0.4545  0.5556  
c <- broom::tidy(lm(a ~ 0 + b))
c$estimate
[1] 0.5625000 0.3793103 0.6666667 0.4545455 0.5555556

d <- broom::tidy(lm(a ~ b))
d$estimate
[1]  0.562500000 -0.183189655  0.104166667 -0.107954545 -0.006944444

d$estimate[2:5] + d$estimate[1]
[1] 0.3793103 0.6666667 0.4545455 0.5555556

【讨论】:

你需要使用glm而不是lmglmfamily作为参数。 在没有family 的情况下使用lm 不是正确的吗?使用glm,它没有给我带来连贯的含义。我的模型最好使用lm。会有问题吗? @roach 基本上在逻辑回归中,我们得到logit函数的输出,我们必须分类ifelse(estimate &gt; 0.5, 'Disclosed', 'Not Disclosed')。 logit 函数是 [0,1] 而线性回归是 linear 基本上。 ***.com/questions/12146914/… 更详细地解释了这一点。 我明白了。谢谢!。你能帮我解决它返回给我的结果吗?我已将其添加到主消息中。谢谢! @roach logit2prob &lt;- function(logit) odds &lt;- exp(logit) prob &lt;- odds / (1 + odds) return(prob) sebastiansauer.github.io/convert_logit2prob。使用此函数将 logit 输出(系数)转换为概率。

以上是关于线性模型-分类模型的主要内容,如果未能解决你的问题,请参考以下文章

广义与一般线性模型及R使用

线性模型

线性模型

SparkMLlib学习之线性回归

经典分类:线性判别分析模型!

python实现感知机线性分类模型