百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

回归or分类线性or逻辑一文掌握模型的不同之处

toyiye 2024-04-27 03:47 18 浏览 0 评论

全文共7366字,预计学习时长30分钟或更长




图片来源:https://techdifferences.com/wp-content/uploads/2018/01/Untitled-2.jpg

回归 VS 分类


为确定使用回归还是分类模型,首先要问的问题是:

目标变量是一个量,一个二进制分类的概率,还是一个标签?


如果目标变量是一个量或概率,须应用回归模型。这意味着如果要推测量值,如高度、收入、价格和分数,使用的模型应该输出一个连续数字。或者,如果目标变量是某一项二进制标签的概率(判断好坏的概率除外),那么也应该选择回归模型,只是具体使用的模型略有不同。我们用均方差(MSE或其它误差)和均方根误差(RMSE或标准差)来评估此类模型,以量化模型中的误差。


如果目标变量是一个标签,则应该使用分类模型。分类有助于预测观察标签(好中差等标签除外)。棘手之处在于判断目标变量是否为标签。比方说,如果目标变量是一个顺序变量,表示1至5之间的不同等级,那么它们即为标签,但其同时具有数学意义。


这意味着数据的平均值和偏差仍有意义,但若要进行推测,应用分类模型是更为明智的选择。我们通过F分数或精确度来评估这些模型,而非其误差或标准差。下面的谱系可以帮助我们理解有多少观察被正确标注,而通过混淆矩阵,这些观察得到视觉化呈现。矩阵中,观察被分为真阳性/真阴性/假阳性/假阴性。



混淆矩阵


运行模型做出预测之前,理解目标变量的特征尤为重要。若应该使用分类模型却误用了回归模型,会得出一堆连续的预测,而非离散标签。而因为大多数(或全部)预测并非你想得出的1或0值,会导致推测出一个较低的F分数(也可能为0)。如果使用得出概率的逻辑模型,有一个方法是设定一个边界值。比如,假定任何大于0.9的值即为1,任何小于0.9的值为0,你仍然会得出一个F分数和混淆矩阵。但使用合适的模型通常可以避免这项额外的步骤。


一旦决定了要使用的方法,接下来就要选择模型进行预测。


视觉化呈现:回归模型 vs. 分类模型


回归模型


回归模型中使用最普遍的是线性回归和逻辑回归。

基本的线性回归模型遵循这个众所周知的等式y=mx+b,但通常实际应用中形式略有不同:

y=β?+β?x?+…+β?x?

该等式中,β?代表纵轴截距,即全部解释变量为0值时的y值。β?到β?是x?到x?变量的相关系数,若其它变量不变,x?到x?中有一项增加或减少,则y值随之增减。比如,在y=1+2x?+3x?这个等式中,若x?由0变为1,x?不变,则y至由1变为3。


逻辑模型遵循的等式略有不同:

y= 1 / (1+e^-(β?+β?x?+…+β?x?))

其中y值在0到1之间。因此,逻辑模型通常被用来分析二进制目标变量。此种情况下,目标变量值为0或1,或者目标变量是二进制变量的概率。正如前面提到,此等式防止出现非逻辑预测,得出的概率低于0或高于1。


视觉化呈现:线性回归 vs. 逻辑回归


两种标准模型均可被调整,以更好拟合数据。主要方法是包含惩罚参数。线性和逻辑回归模型对应的等式均包含全部输入的变量,而这很可能会导致过度拟合。如果数据拟合过度,模型得出预测的可靠性会降低,并局限于训练样本。为了避免此种情况的出现,可以进行特征选择,挑选出相对重要的特征;或在模型中引入惩罚参数。


视觉化呈现:低度拟合与过度拟合


引入L2惩罚项会产生岭回归模型。在此模型中,相对无关变量的系数较少,以限制其影响,但仍包含所有输入的变量。如果想无视变量的相关性并把每一个变量包含进模型中,以上操作十分有效。但大多数情况下,你会倾向于尽可能简化的模型。


引入L1惩罚项会产生拉索回归模型。拉索模型的机制与岭回归模型相似,但会把不相关变量的系数缩减至0,完全消除其影响。而拉索模型的不足之处在于观察数(n)比变量数(k)多,其最多可包含n个变量。同时,拉索模型对相关变量的处理有局限,只能随机保留其中一个变量。


弹性网络回归模型可以解决以上所有问题,它可以结合两个惩罚项,更好地处理多维数据和多重共线性问题。因此,弹性网络模型通常会比拉索模型更精确,但这取决于其所选的L1惩罚项比例,即其超参数之一。


最后还有一个问题,即严格意义上目标变量可能不是解释变量的线性功能。对此,有两个解决方法:更高层级的回归模型或随机森林回归模型。


比方说,在最初的数据探测阶段,你发现要预测收入时,年龄与收入的关联更偏向于二次关系,而非线性关系。在这种情况下,会对原来的线性等式中引入一个二阶变量。等式就变成了这种形式:

y=β?+β?x+β?x2


随后你再次应用模型。你仍然可以应用线性回归模型或更高层级的模型。

一个常见的误解是:线性回归模型仅能产生线性功能。但其实,线性回归模型中的“线性”是指相关系数之间的关系,而非变量本身。因此,在模型中包含更高的层级或互动有助于解释变量之间的关系。但要注意的是,如果这样做,必须保证最终等式中包含低层级和主要影响变量,无论它们是否重要。避免出现这样的等式:

y=β?+β?x2 或y=β?+β?x?*x?


我们也可以使用随机森林回归模型(如下图所示),后文将会更详细地介绍其替代模型——应用更广泛的随机森林分类。随机森林回归的机制与逻辑回归相似,二者均可得出二进制标签的概率。简单来说,随机森林回归会产生大量决策树。这些决策树都会得出预测,而最终预测结果为最普遍的预测或平均预测。


泰坦尼克事件的随机森林分类

现在你可能会想,难道不能用这些模型预测概率目标变量吗?如果训练组的y值在0到1之间,那么模型的预测y值也在0到1之间,是吧?是,也不是。


大多数情况下,模型预测的y值都在0到1之间。但如果模型为线性,则低于0或高于1的概率值是非逻辑回归的。你可以在模型建构中付出110%的努力,但一个观察被分为某一类的概率不可能达到110%。


而且,在线性模型中,诊断患病的概率分别为10%和15%的人群之间的不同就相当于诊断患病概率为95%和1%的人群之间的不同。显然,如果某人100%患病,那么这一点在线性模型中就不会体现,因为此数据对于低于50%的概率而言影响极小。


分类模型


如果分析是为了构建模型以预测观察标签,那么就得使用分类模型。最简单的分类模型就是逻辑模型。然而,通过创建假目标变量并对各变量应用逻辑模型,我们能够训练非二进制目标变量的逻辑模型。你也可以对此逻辑模型导入L1和L2惩罚项,从而运行拉索和岭逻辑模型。


随机森林分类则更有助于推测。和随机森林回归一样,随机森林分类包含仅在特定情况下有影响的特征。随机森林分类的机制同上,其采取决策树的概念以创建一个随机森林,并随机选择变量,最终基于森林得出预测。在应用模型的编码中,可以看到许多超参数,比如决策树的数量、每一片树叶上的最小观察数、最大分裂数、决策树的最大深度等。这些超参数有助于构建一个更为精准的模型,但随机森林仍有可能过度拟合。如果决策树太大,那么它们很可能过于具体,因此无法应用于测试组。


视觉化呈现:随机森林分类


最后,创建神经网络也有助于预测观察标签。这是最为复杂的方法,但相比其他方法的确有某些优势。其主要优势在于可促成无监督学习。这意味着无需先前标记的训练数据,该算法即可根据检测到的相似点来聚合组别。尽管创建起来很复杂,神经网络在预测标签方面更为精确,这一点对于利害关系重大的预测十分重要,如疾病诊断和诈骗检测。


本质上,神经网络算法的工作机制是引入一组数据,找到其中的模型和趋势,然后做出预测(受监督)或聚合组别(无监督)。通过重复此流程并引入更大的训练组,神经网络算法愈加精确。但要注意避免创建过多网络层级导致训练组过度拟合。


视觉化呈现:神经网络


总结


选择预测模型时,首要考虑的问题是目标变量的特征。目标变量是持续的还是离散的?变量是量还是标签?变量是概率还是类别?变量与所有解释变量存在线性相关性吗?需要在预测中包含所有的变量吗?思考这些问题的答案有助于你挑选出最佳预测模型。



源代码及运行对比:


Regression

In [0]:
import sklearn
from sklearn.linear_model import ElasticNet, Lasso, Ridge, LogisticRegression, LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
import matplotlib
from matplotlib import pyplot
def warn(*args, **kwargs):
 pass
import warnings
warnings.warn = warn

In [0]:
from google.colab import files
uploaded = files.upload()

In [0]:
data = pd.read_csv("avocado.csv")
data = data.drop(['Unnamed: 0','Date', 'region','Total Volume','Total Bags'], axis = 1)
data = pd.get_dummies(data, drop_first=True)
y = data['AveragePrice']
X = data.drop('AveragePrice', axis=1)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=.1)

In [250]:
lm = LinearRegression()
lm_fit = lm.fit(X_train, y_train)
lm_predict = lm_fit.predict(X_test)
 
#lr = LogisticRegression()
#lr_fit = lr.fit(X_train,y_train)
#lr_predict = lr_fit.predict(X_test)
## will not work because the range of y is 0 to 3.25, not 0 to 1
 
ridge = Ridge()
ridge_fit = ridge.fit(X_train,y_train)
r_predict = ridge_fit.predict(X_test)
 
lasso = Lasso(max_iter=1000)
lasso_fit = lasso.fit(X_train,y_train)
l_predict = lasso_fit.predict(X_test)
 
ENet = ElasticNet(l1_ratio=.01)
ENet_fit = ENet.fit(X_train,y_train)
en_predict = ENet_fit.predict(X_test)
 
## there are no higher order variables in this dataset, but for the sake of exemplifying the procedure,
## pretend there is a quadratic relationship between the number of 4225 avocados and the price
data1 = data.head(500)
data1['4225_sq'] = 0
for i in range(len(data1['4225'])):
 data1['4225_sq'][i] = (data1['4225'][i])**2
y2 = data1['AveragePrice']
X2 = data1.drop('AveragePrice', axis=1)
X_train2, X_test2, y_train2, y_test2 = train_test_split(X2,y2, test_size=.1)
lm_fit = lm.fit(X_train2, y_train2)
ho_predict = lm_fit.predict(X_test2)
 
rand = RandomForestRegressor()
rand_fit = rand.fit(X_train,y_train)
rf_predict = rand_fit.predict(X_test)
/usr/local/lib/python3.6/dist-packages/sklearn/ensemble/forest.py:245: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
 "10 in version 0.20 to 100 in 0.22.", FutureWarning)
In [252]:
print('Linear Model MSE:' , mean_squared_error(y_test,lm_predict))
#mean_squared_error(y_test,lr_predict)
print('Ridge Model MSE:' , mean_squared_error(y_test,r_predict))
print('Lasso Model MSE:' , mean_squared_error(y_test,l_predict))
print('Elastic Net Model MSE:',mean_squared_error(y_test,en_predict))
print('Higher Order Model MSE:' ,mean_squared_error(y_test2,ho_predict))
print('Random Forest MSE:' ,mean_squared_error(y_test,rf_predict))
Linear Model MSE: 0.09792038897928204
Ridge Model MSE: 0.09791772364668704
Lasso Model MSE: 0.14654262570004578
Elastic Net Model MSE: 0.12919487097231586
Higher Order Model MSE: 0.015512612920132457
Random Forest MSE: 0.034497292054794515

Classification

In [0]:
import sklearn
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score, confusion_matrix
import pandas as pd
In [0]:
from google.colab import files
uploaded = files.upload()

In [0]:
data = pd.read_csv("train.csv")
data = data.drop(['Name','Ticket','Cabin'], axis=1)
data = pd.get_dummies(data)
data = data.fillna(0)
 
y = data['Survived']
X = data.drop('Survived', axis=1)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=.1)
In [236]:
data.head()
Out[236]:

In [0]:
lr = LogisticRegression()
lr_fit = lr.fit(X_train,y_train)
 
lasso2 = LogisticRegression(penalty='l1')
lasso2_fit = lasso2.fit(X_train,y_train)
 
ridge2 = LogisticRegression(penalty='l2')
ridge2_fit = ridge2.fit(X_train,y_train)
 
rand_for = RandomForestClassifier(n_estimators = 500, random_state = 40)
rand_for_fit = rand_for.fit(X_train,y_train)
 
clf = MLPClassifier(activation='logistic', solver='lbfgs',learning_rate='adaptive', alpha=.0005)
clf_fit = clf.fit(X_train, y_train)

In [273]:
print('Logistic F Score:',lr_fit.score(X_test, y_test))
print('LASSO F Score:',lasso2_fit.score(X_test, y_test))
print('Ridge F Score:',ridge2_fit.score(X_test, y_test))
print('Random Forest Classifier F Score:',rand_for_fit.score(X_test, y_test))
print('Neural Net F Score:',clf_fit.score(X_test, y_test))
Logistic F Score: 0.8555555555555555
LASSO F Score: 0.8555555555555555
Ridge F Score: 0.8555555555555555
Random Forest Classifier F Score: 0.8777777777777778
Neural Net F Score: 0.7333333333333333

留言 点赞 关注

我们一起分享AI学习与发展的干货

欢迎关注全平台AI垂类自媒体 “读芯术”

相关推荐

Asterisk-ARI对通道中的DTMF事件处理

Asterisk通道中关于DTMF处理是一个非常重要的功能。通过DTMF可以实现很多的业务处理。现在我们介绍一下关于ARI对通道中的DTMF处理,我们通过自动话务员实例来说明Asterisk如何创建一...

PyQt5 初次使用(pyqt5下载官网)

本篇文章默认已安装Python3,本篇文章默认使用虚拟环境。安装pipinstallPyQt5PyQt一些图形界面开发工具QtDesigner、国际化翻译工具Liguist需要另外...

Qt开发,使用Qt for Python还是Qt C++ Qt开发,使用Qt for

Qt开发使用QtforPython还是QtC++?1.早些年写过一个PyQt5的项目,最近几年重构成QtC++了,其中有个人原因,如早期代码写得烂,...

最简单方法!!用python生成动态条形图

最近非常流行动态条形图,在B站等视频网站上,此类视频经常会有上百万的播放量,今天我们通过第三方库:bar_chart_race(0.2版本)来实现动态条形图的生成;生成的效果如图:问题:...

Asterisk通道和ARI接口的通信(aau通道数)

Asterisk通道和ARI详解什么是通道Asterisk中,通道是介于终端和Asterisk自己本身的一个通信媒介。它包含了所有相关信息传递到终端,或者从终端传递到Asterisk服务器端。这些信...

Python GUI-长链转短链(长链接转化成短链接java)

当我们要分享某一个链接给别人,或是要把某个链接放入帖子中时,如果链接太长,则会占用大量空间,而且很不美观。这时候,我们可以结束长链转短链工具进行转换。当然可以直接搜索在线的网站进行转换,但我们可以借此...

Python 的hash 函数(python的hash函数)

今天在看python的hash函数源码的时候,发现针对不同的数据类型python实现了不同的hash函数,今天简单介绍源码中提到的hash函数。(https://github.com/pyth...

8款Python GUI开源框架,谁才是你的菜?

作为Python开发者,你迟早都会用到图形用户界面来开发应用。本文千锋武汉Python培训小编将推荐一些PythonGUI框架,希望对你有所帮助。1、Python的UI开发工具包Kivy...

python适合开发桌面软件吗?(python可不可以开发桌面应用软件)

其实Python/Java/PHP都不适合用来做桌面开发,Java还是有几个比较成熟的产品的,比如大名鼎鼎的Java集成开发环境IntelliJIDEA、Eclipse就是用Java开发的,不过PH...

CryptoChat:一款功能强大的纯Python消息加密安全传输工具

关于CryptoChatCryptoChat是一款功能强大的纯Python消息加密安全传输工具,该工具专为安全研究专家、渗透测试人员和红蓝队专家设计,该工具可以完全保证数据传输中的隐私安全。该工具建立...

为什么都说Python简单,但我觉得难?

Python普遍被大家认为是编程语言中比较简单的一种,但有一位电子信息的学生说自己已经学了C语言,但仍然觉得Python挺难的,感觉有很多疑问,像迭代器、装饰器什么的……所以他提出疑问:Python真...

蓝牙电话-关联FreeSwitch中继SIP账号通过Rest接口

蓝牙电话-关联FreeSwitch中继SIP账号通过Rest接口前言上一篇章《蓝牙电话-与FreeSwitch服务器和UA坐席的通话.docx》中,我们使用开源的B2B-UA当中经典的FreeSWIT...

技术分享|Sip与WebRTC互通-SRProxy开源库讲解

SRProxy介绍目前WebRTC协议跟SIP协议互通场景主要运用在企业呼叫中心、企业内部通信、电话会议(PSTN)、智能门禁等场景,要想让WebRTC与SIP互通,要解决两个层面的...

全网第N篇SIP协议之GB28181注册 JAVA版本

鉴于网上大部分关于SIP注册服务器编写都是C/C++/python,故开此贴,JAVA实现也贴出分享GB28181定义了了基于SIP架构的视频监控互联规范,而对于多数私有协议实现的监控系统...

「linux专栏」top命令用法详解,再也不怕看不懂top了

在linux系统中,我们经常使用到的一个命令就是top,它主要是用来显示系统运行中所有的进程和进程对应资源的使用等信息,所有的用户都可以使用top命令。top命令内容量丰富,可令使用者头疼的是无法全部...

取消回复欢迎 发表评论:

请填写验证码