算法审查是选择合适机器学习算法的主要方法之一。审查算法前并不知道哪个算法对问题最有效,必须设计一定的实验进行验证,以找到对问题最有效的算法。
在选择算法时,应该换一种思路,不是针对数据应该采用哪种算法,而是应该用数据来审查哪些算法。应该先猜测一下,什么算法会具有最有效的效果。
- 尝试多种代表性算法
- 尝试机器学习算法
- 尝试多种模型
在分类算法中,目前存在很多类型的分类器:线性分类器,贝叶斯分类器,基于距离的分类器等。
线性分类器:逻辑回归,线性判别分析
非线性算法:K近邻,贝叶斯分类器,分类与回归树,支持向量机
本章继续使用Pima Indians数据集来审查算法,同时会采用10折交叉验证来评估算法的准确度。使用平均准确度来标准化算法的得分,以减少数据分布不均衡对算法的影响。
注:逻辑回归和线性判别分析都是假定输入的数据符合高斯分布。
逻辑回归
回归可以这样理解,相当于y=f(x),表明自变量x与因变量y的关系。
犹如医生治病时先望、闻、问、切,再判定病人是否生病或生了什么病,此处的望闻问切就是获取自变量x,即特征数据;判断是否生病就相当于获取因变量y,即预测分类。
逻辑回归其实是一个分类算法而不是回归算法,通常是利用已知的自变量来预测一个离散型因变量的值。简单来说,就是通过拟合一个逻辑函数(Logit Function)来预测一个事件的发生概率,也就是说它预测的是一个概率值,结果在0~1之间,因此非常适合处理二分类问题。
在scikit-learn中实现类是LogisticRegression。
1 #逻辑回归 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 10 filename='/home/aistudio/work/pima_data1.csv' 11 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 12 data=read_csv(filename,names=names) 13 #将数据分为输入数据和输出数据 14 array=data.values 15 x=array[:,0:8] 16 y=array[:,8] 17 num_folds=10 18 seed=4 19 kfold=KFold(n_splits=num_folds,random_state=seed) 20 model=LogisticRegression() 21 result=cross_val_score(model,x,y,cv=kfold) 22 23 print('Start------------') 24 print(result.mean()) 25 print('End------------')
Start------------ 0.7695146958304853 End------------
线性判别分析
线性判别分析(Linear Discriminant Analysis, LDA),也叫做Fisher线性判别(Fisher Linear Discriminant, FLD),是模式识别的经典算法。
线性判别分析的基本思路是将高维模式样本投影到最佳鉴别矢量空间,以达到抽取分类信息和压缩特征空间维数的效果,投影后保证模式样本在新的子空间有最大的类间距离和最小的类内距离,即模式在该空间有最佳的可分离性。
线性判别分析与主要成分分析一样,被广泛应用在数据降维中。
在scikit-learn中实现的类是LiearDiscriminantAnalysis。
1 #线性判别分析 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis 10 11 filename='/home/aistudio/work/pima_data1.csv' 12 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 13 data=read_csv(filename,names=names) 14 #将数据分为输入数据和输出数据 15 array=data.values 16 x=array[:,0:8] 17 y=array[:,8] 18 num_folds=10 19 seed=4 20 kfold=KFold(n_splits=num_folds,random_state=seed) 21 #model=LogisticRegression() 22 model=LinearDiscriminantAnalysis() 23 result=cross_val_score(model,x,y,cv=kfold) 24 25 print('Start------------') 26 print(result.mean()) 27 print('End------------')
Start------------ 0.773462064251538 End------------
接下来介绍四种非线性算法:K近邻(KNN),贝叶斯分类器,分类与回归树和支持向量机算法。
K近邻算法
如果一个样本在特征空间中的K个最相似(特征空间中最临近)的样本大多数属于某一个类别,则该样本也属于这个类别。
在KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象间的匹配问题,距离一般使用欧氏距离或曼哈顿距离;同时,KNN通过依据K个对象中占优的类别进行决策,而不是通过单一的对象类别决策。这就是KNN算法的优势。
在scikit-learn中实现的类是KNeighborsClassifier。
1 #KNN 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis 10 from sklearn.neighbors import KNeighborsClassifier 11 12 filename='/home/aistudio/work/pima_data1.csv' 13 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 14 data=read_csv(filename,names=names) 15 #将数据分为输入数据和输出数据 16 array=data.values 17 x=array[:,0:8] 18 y=array[:,8] 19 num_folds=10 20 seed=7 21 kfold=KFold(n_splits=num_folds,random_state=seed) 22 #model=LogisticRegression() 23 #model=LinearDiscriminantAnalysis() 24 model=KNeighborsClassifier() 25 result=cross_val_score(model,x,y,cv=kfold) 26 27 print('Start------------') 28 print(result.mean()) 29 print('End------------')
Start------------ 0.7265550239234451 End------------
贝叶斯分类器
原理是某对象的先验概率,利用贝叶斯公式计算出所有类别上的后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类。
贝叶斯分类器是最小错误率上的优化。对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大就认为此待分类项属于哪个类别。
贝叶斯分类器的特点:
- 基于统计的分类器
- 理论基础是贝叶斯理论
- 一种简单形式是朴素贝叶斯分类器,与随机森林、神经网络等分类器具有可比的性能
- 是一种增量型的分类器
在贝叶斯分类器中,对输入数据同样做了符合高斯分布的假设。在scikit-learn中实现的类是GaussianNB。
1 #贝叶斯分类器 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis 10 from sklearn.neighbors import KNeighborsClassifier 11 from sklearn.naive_bayes import GaussianNB 12 13 filename='/home/aistudio/work/pima_data1.csv' 14 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 15 data=read_csv(filename,names=names) 16 #将数据分为输入数据和输出数据 17 array=data.values 18 x=array[:,0:8] 19 y=array[:,8] 20 num_folds=10 21 seed=7 22 kfold=KFold(n_splits=num_folds,random_state=seed) 23 #model=LogisticRegression() 24 #model=LinearDiscriminantAnalysis() 25 #model=KNeighborsClassifier() 26 model=GaussianNB() 27 result=cross_val_score(model,x,y,cv=kfold) 28 29 print('Start------------') 30 print(result.mean()) 31 print('End------------')
Start------------ 0.7551777170198223 End------------
分类与回归树
分类与回归英文缩写是CART,也属于一种决策树,树的构建基于基尼指数。
CART假设决策树是二叉树,内部节点特征的取值为‘是’和‘否’,左分支是取值为‘是’的分支,有分支是取值为‘否’的分支。
这样的决策树等价于递归二分每个特征,将输入空间(特征空间)划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。
CART算法由以下两部组成:
- 树的生成:基于训练的数据集生成决策树,生成的决策树要尽量大
- 树的剪枝:用验证的数据集对已生成的树进行剪枝,并选择最优子树,这时以损失函数最小作为剪枝的标准。
决策树的生成是通过递归构建二叉决策树的过程,对回归树用平方误差最小化准测,或对分类数用基尼指数最小化准测,进行特征选择,生成二叉树。
可通过scikit-learn中的DecisionTreeClassifier类来构建一个CART模型。
1 #分类与回归树(CART) 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis 10 from sklearn.neighbors import KNeighborsClassifier 11 from sklearn.naive_bayes import GaussianNB 12 from sklearn.tree import DecisionTreeClassifier 13 14 filename='/home/aistudio/work/pima_data1.csv' 15 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 16 data=read_csv(filename,names=names) 17 #将数据分为输入数据和输出数据 18 array=data.values 19 x=array[:,0:8] 20 y=array[:,8] 21 num_folds=10 22 seed=7 23 kfold=KFold(n_splits=num_folds,random_state=seed) 24 #model=LogisticRegression() 25 #model=LinearDiscriminantAnalysis() 26 #model=KNeighborsClassifier() 27 #model=GaussianNB() 28 model=DecisionTreeClassifier(); 29 result=cross_val_score(model,x,y,cv=kfold) 30 31 print('Start------------') 32 print(result.mean()) 33 print('End------------')
Start------------ 0.7004272043745728 End------------
(测试结果发现,每点击一次运行,结果都不同,看来还是需要另外花时间对代码的结果进行解读)。
支持向量机
支持向量机在解决小样本,非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中。
给定一组训练样本,每条记录标记所属类别,使用支持向量机算法训练,并建立一个模型,对新数据实例进行分类,使其成为非概率二元线性分类。
如在空间不同点的映射,使得所属不同类别的实例是由一个差距明显尽可能宽的划分表示。新的实例映射到相同的空间中,并基于他们落在相同间隙上预测其属于同一个类别,可通过scikit-learn中的SVC类来构建一个SVM模型。
1 #SVM 2 from pandas import read_csv 3 import pandas as pd 4 from sklearn.model_selection import train_test_split 5 from sklearn.model_selection import KFold 6 from sklearn.model_selection import cross_val_score 7 from sklearn.linear_model import LogisticRegression 8 from sklearn.metrics import confusion_matrix 9 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis 10 from sklearn.neighbors import KNeighborsClassifier 11 from sklearn.naive_bayes import GaussianNB 12 from sklearn.tree import DecisionTreeClassifier 13 from sklearn.svm import SVC 14 15 filename='/home/aistudio/work/pima_data1.csv' 16 names=['preg','plas','pres','skin','test','mass','pedi','age','class'] 17 data=read_csv(filename,names=names) 18 #将数据分为输入数据和输出数据 19 array=data.values 20 x=array[:,0:8] 21 y=array[:,8] 22 num_folds=10 23 seed=7 24 kfold=KFold(n_splits=num_folds,random_state=seed) 25 #model=LogisticRegression() 26 #model=LinearDiscriminantAnalysis() 27 #model=KNeighborsClassifier() 28 #model=GaussianNB() 29 #model=DecisionTreeClassifier(); 30 model=SVC(); 31 result=cross_val_score(model,x,y,cv=kfold) 32 33 print('Start------------') 34 print(result.mean()) 35 print('End------------')
Start------------ 0.6510252904989747 End------------