第一部分 整体思路
下面是这次算法比较进行对比的算法
1、线性回归算法(运用了LinearRegression函数)
2、逻辑回归算法(运用了logisticRegression函数)
3、决策树算法(运用了DecisionTreeClassifier以及GradientBoostingClassifier函数)
4、神经网络算法(运用了MLPClassifier函数)
5、支持向量机算法(运用了SVC函数)
我的比较思路是对比各种算法的运行时间长短,训练集、测试集准度,ROC曲线图像以及对比算法各自的优缺点。
第二部分 代码实现
一、算法步骤
第一步:从python库sklearn中调用内置的乳腺癌数据集、划分训练集以及测试集的工具以及实现算法的函数(sklearn中都有)。
第二步:将乳腺癌数据集划分为训练集以及测试集。
第三步:使用各算法对应的函数,并且在函数后的括号内调节参数。
第四步:打印准确率的结果,由于我要进行程序运行时间的比较,最后还打印了出了算法运行时间。
二、ROC曲线python代码实现
第一步:导入画图工具(matplotlib.pyplot)以及需要的以及计算roc和auc的函数(roc_curve, auc)。
第二步:执行算法实现代码,其中y_test为测试集的结果,scores为模型预测的测试集得分(注意:通过predict(x_test)计算scores的值),用在roc_curve()函数中。
第三步:计算真正例率和假正例率以及auc值,fpr,tpr,thresholds 分别为假正率、真正率和阈值。(应该是不同阈值下的真正率和假正率)。
第四步:画图的参数调节,为保持可比性,所有算法在绘制roc曲线时都是使用一样的参数。
第五步:显示绘制出的ROC曲线以及AUC值。
第三部分 算法对比
一、线性回归算法(LinearRegression)
① 算法思想
什么是线性回归:
线性:两个变量之间的关系是一次函数关系的——图象是直线,叫做线性。
非线性:两个变量之间的关系不是一次函数关系的——图象不是直线,叫做非线性。
回归:人们在测量事物的时候因为客观条件所限,求得的都是测量值,而不是事物真实的值,为了能够得到真实值,无限次的进行测量,最后通过这些测量数据计算回归到真实值。
② 算法展示
参数介绍:
fit_intercept:是否有截据,如果没有则直线过原点。
normalize:是否将数据归一化。
copy_X:默认为True,当为True时,X会被copied,否则X将会被覆写。
n_jobs:默认值为1。计算时使用的核数。
(由于调参与不调参的结果是一致的,所以这里的LinearRegression函数没有进行调参)
下面是代码以及代码运行的输出结果,细节与前面所述的大体算法步奏基本一致:
从运行结果来看训练集的准度为0.783,而测试集准度只有0.725,总体的准度是偏低的,也并没有达到0.9以上。
运行时间是0.005秒左右,时间是非常短的。
下面是利用绘制roc曲线的代码绘制出的roc曲线:
另外下面是其AUC值:
③ 算法优缺点
优点:
(1)思想简单,实现容易。建模迅速,对于小数据量、简单的关系很有效;
(2)是许多强大的非线性模型的基础。
(3)线性回归模型十分容易理解,结果具有很好的可解释性,有利于决策分析。
(4)蕴含机器学习中的很多重要思想。
(5)能解决回归问题。
缺点:
(1)对于非线性数据或者数据特征间具有相关性多项式回归难以建模.
(2)难以很好地表达高度复杂的数据。
二、逻辑回归算法(LogisticRegression)
① 算法思想
逻辑回归算法:虽然名字中带有回归两个字,但它却不是回归算法,它是一个经典的二分类算法。
回归与分类的区别:
回归:可以得到一个准确值或一个区间值,比如房屋价格预测,NBA比赛得分等。
分类:预测结果是一个分类值,yes or no,0或1,好或坏,输或赢等等,比如预测猛龙队能否获得2019NBA总冠军,预测小明同学今年能否考上大学等等,结果都只有两个。
逻辑回归算法是所有机器学习算法中最简单的算法,但简单不一定代表效果不好。我们在处理机器学习问题时,优先采用简单算法,并对其参数进行优化。如果不能达到你的目的,我们再选择更加复杂的算法,比如支持向量机,神经网络等等。
逻辑回归是用来处理分类问题的,其分类边界不一定都是线性的,也可以是非线性的。如下图,一条非线性的决策边界将已有的数据点分成了两类。
② 算法展示
下面是代码,细节与前面所述的大体算法步奏基本一致:
参数介绍:
下面的算法代码中,主要只调了参数"C=100"以及"solver='liblinear'",因为处理的乳腺癌数据集是二分类问题,因此使用了"solver='liblinear'";
另外参数"C"共进行了三次调节,第一次"C=1.0",代码运行的输出结果如下图:
第二次"C=100",结果如下图:
第三次"C=0.01",结果如下图:
第一个训练集是0.955,测试集是0.958好像很接近,但由于训练集和测试集的性能非常接近,所以模型很可能是欠拟合的。接下来第二个我们尝试增大 C 来拟合一个更灵活的模型,而第三个则是降低 C ,发现调第二次和第三次的时候,第二次提高了,第三次开始降低了。特别是第三次,测试集开始比第二次降低了。可见第二个是三个数值之中最佳的参数设置。
参数设置为"C=100"时的输出结果是:训练集: 0.971831,测试集: 0.965035,运行时间:0.005984秒,总体上相比于线性回归算法有显著的提高,尽管运行时间稍微必线性回归长,但是差别甚微。
下面是利用绘制roc曲线的代码绘制出的roc曲线:
另外下面是其AUC值:
可见其AUC值比线性回归的小。
③ 算法优缺点
优点:
(1)便于理解和实现,可以观测样本的概率分数
(2)训练速度快
(3)由于经过了sigmoid函数的映射,对数据中小噪声的鲁棒性较好
(4)不受多重共线性的影响(可通过正则化进行消除)
缺点:
(1)容易欠拟合
(2)特征空间很大时效果不好
(3)由于sigmoid函数的特性,接近0/1的两侧概率变化较平缓,中间概率敏感,波动较大;导致很多区间特征变量的变化对目标概率的影响没有区分度,无法确定临界值。
第三部分 决策树算法(DecisionTreeClassifier以及 GradientBoostingClassifier函数)
① 算法思想
决策树(decision tree)是一个树结构(可以是二叉树或非二叉树)。
其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。
使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。
② 算法展示
下面是使用DecisionTreeClassifier函数的代码,细节与前面所述的大体算法步奏基本一致:
如果我们不限制决策树的深度,它的深度和复杂度都可以变得特别大。因此,未剪枝的树容易过拟合,对新数据的泛化性能不佳。现在我们将预剪枝应用在决策树上,这可以在完美拟合训练数据之前阻止树的展开。一种选择是在到达一定深度后停止树的展开。这里我们设置 max_depth=4,这意味着只可以连续问 4 个问题。结论:限制树的深度可以减少过拟合。这会降低训练集的精度,但可以提高测试集的精度。(此处参考了老师题目为”过拟合和欠拟合的文章)
下面是使用GradientBoostingClassifier函数的代码:
使用GradientBoostingClassifier函数的模型简称为GBDT
GBDT,通过合并多个决策树来构建一个更为强大的模型。虽然名字中含有“回归”,但这个模型既可以用于回归也可以用于分类。梯度提升采用连续的方式构造树,每棵树都试图纠正前一棵树的错误。默认情况下,梯度提升回归树中没有随机化,而是用到了强预剪枝。梯度提升树通常使用深度很小(1 到 5 之间)的树,这样模型占用的内存更少,预测速度也更快。
上面GBDT的例子中默认使用 100 棵树,最大深度是 3,学习率为 0.1:由于训练集精度达到 100%,所以很可能存在过拟合。为了降低过拟合,我们可以限制最大深度来加强预剪枝max_depth,也可以降低学习率learning_rate。降低模型复杂度的两种方法都降低了训练集精度,这和预期相同。在这个例子中,参数设置"max_depth=1"显著提升了模型性能,"learning_rate=0.1"仅稍稍提高了泛化性能。(以上参考了老师题目为”过拟合和欠拟合的文章)
上面代码中默认使用的是100棵树,而我使用了200棵树即"n_estimators=200",这是经过四个实验后确定的:
第一个设置默认值n_estimators=100:
第二个设置n_estimators=200:
第三个设置n_estimators=300:
第四个设置n_estimators=250:
从上面实验结果来看设置值300的结果要比100的结果要高,但是训练集的准度为1,可见出现了过拟合,而设置值为200以及250的结果则比前两者更优,同为0.99/0.96,略微减轻了过拟合的现象,由于设置值为200的程序运行时间比250的运行时间短,鉴于两者结果一样,所以最后选择了参数设置为"n_estimators=200"。
上述两个函数参数设置完毕,最后的结果如下,
使用DecisionTreeClassifier函数:
使用GradientBoostingClassifier函数:
两者相比于逻辑回归算法的准度都略微有所提高,但存在稍微的过拟合现象,运行时间又有所差别,使用DecisionTreeClassifier函数运行时间较短,使用GradientBoostingClassifier函数运行时间较长。
下面是两者的ROC曲线及AUC值,
使用DecisionTreeClassifier函数:
使用GradientBoostingClassifier函数:
两者对比可见使用GradientBoostingClassifier函数的算法性能是比使用DecisionTreeClassifier函数的算法的性能是要好的。
③ 算法优缺点
优点:
(1)速度快: 计算量相对较小, 且容易转化成分类规则. 只要沿着树根向下一直走到叶, 沿途的分裂条件就能够唯一确定一条分类的谓词.
(2)准确性高: 挖掘出来的分类规则准确性高, 便于理解, 决策树可以清晰的显示哪些字段比较重要, 即可以生成可以理解的规则.
(3)可以处理连续和种类字段
(4)不需要任何领域知识和参数假设
(5)适合高维数据
缺点:
(1)对于各类别样本数量不一致的数据, 信息增益偏向于那些更多数值的特征
(2)容易过拟合
(3)忽略属性之间的相关性
四 神经网络算法(MLPClassifier函数)
① 算法思想
MLPClassifier是一个监督学习算法,下图是只有1个隐藏层的MLP模型 ,左侧是输入层,右侧是输出层。
上图的整体结构可以简单的理解为下图所示:
MLP又名多层感知机,也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出层,它中间可以有多个隐藏层,如果没有隐藏层即可解决线性可划分的数据问题。最简单的MLP模型只包含一个隐藏层,即三层的结构,如上图。
从上图可以看到,多层感知机的层与层之间是全连接的(全连接的意思就是:上一层的任何一个神经元与下一层的所有神经元都有连接)。多层感知机最底层是输入层,中间是隐藏层,最后是输出层。
② 算法展示
下面是使用MLPClassifier函数的代码,其中的乳腺癌数据使用了sklearn.preprocessing包中的 StandardScaler工具进行了数据缩放(MLP 的精度相当好,但没有其他模型好。与较早的 SVC 例子相同,原因可能在于数据的缩放。神经网络也要求所有输入特征的变化范围相似,最理想的情况是均值为 0、方差为 1。我们必须对数据进行缩放以满足这些要求),如图#数据缩放:
参数说明(有选择性地进行讲解):
1. hidden_layer_sizes :例如hidden_layer_sizes=(50, 50),表示有两层隐藏层,第一层隐藏层有50个神经元,第二层也有50个神经元。
2. activation :激活函数,{‘identity’, ‘logistic’, ‘tanh’, ‘relu’}, 默认relu
- identity:f(x) = x
- logistic:其实就是sigmod,f(x) = 1 / (1 + exp(-x)).
- tanh:f(x) = tanh(x).
- relu:f(x) = max(0, x)
3. solver: {‘lbfgs’, ‘sgd’, ‘adam’}, 默认adam,用来优化权重
- lbfgs:quasi-Newton方法的优化器
- sgd:随机梯度下降
- adam: Kingma, Diederik, and Jimmy Ba提出的机遇随机梯度的优化器
注意:默认solver ‘adam’在相对较大的数据集上效果比较好(几千个样本或者更多),对小数据集来说,lbfgs收敛更快效果也更好。
4. alpha :float,可选的,默认0.0001,正则化项参数
5. max_iter: int,可选,默认200,最大迭代次数。
6. random_state:int 或RandomState,可选,默认None,随机数生成器的状态或种子。
参数设置:增加迭代次数加到了1000(max_iter=1000),但仅提高了训练集性能,但没有提高泛化性能。不过模型的表现相当不错。由于训练性能和测试性能之间仍有一些差距,所以我们可以尝试降低模型复杂度来得到更好的泛化性能。这里我们选择增大 alpha 参数(变化范围相当大,从 0.0001 到 1)(alpha=1),以此向权重添加更强的正则化。
运行结果如下图:
这是目前为止性能最好的模型,尽管运行时间比较之前的算法较长。
下面是他的ROC曲线:
可见其性能也是十分优秀的。
③ 算法优缺点
优点:
(1)具有自学习功能。例如实现图像识别时,只在先把许多不同的图像样板和对应的应识别的结果输入人工神经网络,网络就会通过自学习功能,慢慢学会识别类似的图像。
自学习功能对于预测有特别重要的意义。预期未来的人工神经网络计算机将为人类提供经济预测、市场预测、效益预测,其应用前途是很远大的。
(2)具有联想存储功能。用人工神经网络的反馈网络就可以实现这种联想。
(3)具有高速寻找优化解的能力。寻找一个复杂问题的优化解,往往需要很大的计算量,利用一个针对某问题而设计的反馈型人工神经网络,发挥计算机的高速运算能力,可能很快找到优化解。
(4)能够获取大量数据中包含的信息,并构建无比复杂的模型。
缺点:
(1)最严重的问题是没能力来解释自己的推理过程和推理依据。
(2)神经网络——特别是功能强大的大型神经网络——通常需要很长的训练时间。
(3)它还需要仔细地预处理数据,正如我们这里所看到的。
(4)不能向用户提出必要的询问,而且当数据不充分的时候,神经网络就无法进行工作。
(5)把一切问题的特征都变为数字,把一切推理都变为数值计算,其结果势必是丢失信息。
五 支持向量机算法(SVC函数)
① 算法介绍
支持向量机英文Support Vector Machine,简称SVM。SVM本来是一种线性分类和非线性分类都支持的二元分类算法,但经过演变,现在也支持多分类问题,也能应用到了回归问题。
② 算法展示
下面是使用SVC函数的代码,其中的乳腺癌数据使用了sklearn.preprocessing包中的 MinMaxScaler工具进行了数据的归一化,以使数据的所有特征缩放到 0 和 1 之间,如图#数据归一化:
参数介绍:
SVC的重要参数kernel(核函数),作为SVC类最重要的参数之一,“kernel"在sklearn中可选以下几种选项:
可以看出,除了选项"linear"之外,其他核函数都可以处理非线性问题。多项式核函数有次数d,当d为1的时候它就是再处理线性问题,当d为更高次项的时候它就是在处理非线性问题。
在上述代码中,我遍历了不同的核函数结果如下:
可见在数据归一化后性能最好的还是使用'poly'核函数。
另外我未进行归一化处理时,运行poly核函数,其运行时间十分长,但在把degree参数调整为1,多项式核函数的运行速度立刻加快了,并且精度也提升到了接近线性核函数的水平。在数据归一化后,其结果在把degree参数调整为1后也略有提升,因此保留了这个参数调节。
另一个使用到的参数C:
在实际使用中,C和核函数的相关参数(gamma,degree等等)们搭配,往往是SVM调参的重点。与gamma不同,C没有在对偶函数中出现,并且是明确了调参目标的,所以我们可以明确我们究竟是否需要训练集上的高精确度来调整C的方向。默认情况下C为1,通常来说这都是一个合理的参数。
我们可以尝试增大 C 或 gamma 来拟合更为复杂的模型。因此我设置了三个数值:1、100、100。
第一个数值,也即默认数值C=1,得到的结果如下图:
可见其准度十分低,因此继续提高其数值,C=100:
准度马上提高了许多,但我还是不满意,因此继续提高C=1000:
其准度可见比前者更加提高了。
最后我将C提高到了5000,结果如下:
增大 C 可以显著改进模型,得到 97.3% 的精度,运行时间也十分的快速,这也是这个算法的最终结果,至此我们得到了和神经网络算法(MLPClassifier函数)相媲美的准度。
此算法的ROC曲线如下图所示:
AUC值为:
其性能也是相当不错。
③ 算法优缺点
优点:
(1)非线性映射是SVM方法的理论基础,SVM利用内积核函数代替向高维空间的非线性映射;
(2)对特征空间划分的最优超平面是SVM的目标,最大化分类边际的思想是SVM方法的核心;
(3)支持向量是SVM的训练结果,在SVM分类决策中起决定作用的是支持向量。
(4)SVM 是一种有坚实理论基础的新颖的小样本学习方法。它基本上不涉及概率测度及大数定律等,因此不同于现有的统计方法。从本质上看,它避开了从归纳到演绎的传统过程,实现了高效的从训练样本到预报样本的“转导推理”,大大简化了通常的分类和回归等问题。
(5)SVM 的最终决策函数只由少数的支持向量所确定,计算的复杂性取决于支持向量的数目,而不是样本空间的维数,这在某种意义上避免了“维数灾难”。
(6)少数支持向量决定了最终结果,这不但可以帮助我们抓住关键样本、“剔除”大量冗余样本,而且注定了该方法不但算法简单,而且具有较好的“鲁棒”性。
缺点:
(1) SVM算法对大规模训练样本难以实施。由于SVM是借助二次规划来求解支持向量,而求解二次规划将涉及m阶矩阵的计算(m为样本的个数),当m数目很大时该矩阵的存储和计算将耗费大量的机器内存和运算时间。
(2)用SVM解决多分类问题存在困难。
第四部分 整理总结
根据以上的总结,与我的观点来说,我会选择神经网络算法(MLPClassifier函数)或者支持向量机算法(SVC函数),两者的准确率相对来说最高,且比较接近,ROC曲线分析下,性能也十分的优异。但运行时间上,神经网络的运行时间比较长,如果需处理的数据集十分巨大的话,时间上来说是一个负担,而支持向量机SVM算法对大规模训练样本难以实施。在较大数据集基础上,我们选择神经网络算法会比较好,但运行时间可能会比较长。
代码地址:码云
参考资料:
2、机器学习--线性回归算法的原理及优缺点 - 泰初 - 博客园
3、sklearn线性回归LinearRegression代码及调参_人工智能_lyy的博客-CSDN博客
5、LogisticRegression函数的各个参数意义_Python_默默学习-CSDN博客
7、sklearn 神经网络 MLPClassifier简单应用与参数说明 - 简书
8、支持向量机(SVM)的优缺点_网络_qq_38734403的博客-CSDN博客