本文链接:https://blog.csdn.net/Vapor_/article/details/80625988
依赖的python库
- os
- time
- sklearn
- numpy
简易demo
from sklearn import datasets
from classify import ClassfyMethods
from sklearn.model_selection import train_test_split
if __name__ == '__main__':
iris = datasets.load_iris() #sklearn鸢尾花数据集作为测试
train_X, train_Y = iris.data, iris.target
train_X, test_x, train_Y, _ = train_test_split(train_X, train_Y, test_size=.3)
print(train_X.shape, train_Y.shape)
Thanos = ClassfyMethods() #实例化分类算法对象
Thanos.train_all(train_X, train_Y) #七种分类算法进行训练并交叉验证
Thanos.ensembling(train_X, train_Y, test_x) #进行模型融合
安装包结构
分类算法
class ClassfyMethods(object):
def __init__(self, k_fold_num=5 ):
self.sortedClassifies = []
self.sortedIndex = []
self.test_classifiers = ['KNN', 'LR', 'RF', 'DT', 'SVM', 'SVMCV', 'GBDT']
self.classifiers = {'KNN': self.knn_classifier,
'LR': self.logistic_regression_classifier,
'RF': self.random_forest_classifier,
'DT': self.decision_tree_classifier,
'SVM': self.svm_classifier,
'SVMCV': self.svm_cross_validation,
'GBDT': self.gradient_boosting_classifier
}
-
传入参数k_fold_num,当参数缺省时,默认为5。如果处理训练样本比较大,可适当提高数值(一般为10)。
-
有七种分类算法分别对应:KNN(K-nearest Neighbor, 近邻分类算法)、LR(Lenear Regression,线性回归分类算法)、RF(Random Forrest, 随机森林分类算法)、DT(Decision Tree, 决策树分类算法)、SVM(Support Vector Machine,支持向量机)、SVMCV(Support Vector Machine, 交叉验证的支持向量机)、GBDT(Gradient Boosting Decision Tree,梯度提升决策树)
# KNN Classifier
def knn_classifier(self, train_x, train_y):
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier()
model.fit(train_x, train_y)
return model
# Logistic Regression Classifier
def logistic_regression_classifier(self, train_x, train_y):
pass
# Random Forest Classifier
def random_forest_classifier(self, train_x, train_y):
pass
# Decision Tree Classifier
def decision_tree_classifier(self, train_x, train_y):
pass
# GBDT(Gradient Boosting Decision Tree) Classifier
def gradient_boosting_classifier(self, train_x, train_y):
pass
#SVM Classifier
def svm_classifier(self, train_x, train_y):
pass
# SVM Classifier using cross validation
def svm_cross_validation(self, train_x, train_y):
pass
- 这里只展示KNN分类算法的具体细节,其他分类算法大同小异,不做赘述,
大都是从sklearn引入分类模型,对传进来的参数进行训练返回模型
数据处理
def read_data(self, train_X, train_Y, split_size=.3):
pass
- 穿参split_size的值默认值为0.3,防止参数缺省时报错,用户可自定义切割尺寸。
- 传入的train_X, train_Y 的尺寸必须规整,不能有NAN空值。故对传入参数进行检验,
如传入参数有误,则会提示* train_X must be full size. Its row equals to train_Y’s row *
模型训练
def train_all(self, train_X, train_Y):
pass
- 依次将分类算法进行训练,并保存各个分类算法模型到./models/目录下(当前路径无该目录时可自动生成),命名规则为:算法缩写.model(etc: KNN.model)
- 判断是否为二分类问题,如果是,打印precision(准确率)和recall(召回率)。利用交叉检验,默认为10-Fold 交叉检验,打印accuracy(精确率)。
- 将各个分类算法交叉检验的accuracy从大到小排序,存储对应分类算法下标到self.sortedIndex。为后期模型融合做准备
模型融合
def ensembling(self, train_x, train_y, test_x, n_folds=5, ensemble_num=3):
pass
- 将表现最好的ensemble_num=3个模型进行Stacking融合,用户可根据实际效果,判断模型融合的模型个数,
具体融合为规则为:- Base Model 之间的相关性要尽可能的小。这就是为什么非 Tree-based Model 往往表现不是最好
但还是要将它们包括在 Ensemble 里面的原因。Ensemble 的 Diversity 越大,最终 Model 的 Bias
就越低。 - Base Model 之间的性能表现不能差距太大。这其实是一个 Trade-off,在实际中很有可能表现相近的Model 只有寥寥几个而且它们之间相关性还不低。但是实践告诉我们即使在这种情况下 Ensemble 还是能大幅提高成绩。参考链接
stacking融合原理 - Base Model 之间的相关性要尽可能的小。这就是为什么非 Tree-based Model 往往表现不是最好
-
DecisonTree 算法原理
- 构造决策树通常包括三个步骤:
- 特征选择
- 决策树生成
- 决策树剪枝
伪代码逻辑
Check if every item in the dataset is in the same class:
If so return the class label
Else
find the best feature to split the data
split the dataset
create a branch node
for each split
call createBranch and add the result to the branch node
return branch node
- 查询传入的数据集是否都为同一类。是,则返回该类标签;否,对该自己进行划分。
- 对该自己进行划分后,创建新的节点,将划分后的所有类别添加到决策树中。
特征选择
- 特征选择目的是选取较强分类特征。特征选取根据划分集合中类别的数据纯度进行判别,常用的衡量节点数据集合的纯度有:信息增益(information gain)、基尼系数和方差
信息熵增益
信息熵的定义:
- 某个事件 i i的信息量:这个事件发生概率的负对数
Ti=−log(P(xi)) Ti=−log(P(xi))
-
信息熵即为信息量的期望值负数:
H=∑i=1nH(xi)=−∑i=1nP(xi)log(P(xi)) H=∑i=1nH(xi)=−∑i=1nP(xi)log(P(xi))
-
信息增益:设特征A是离散的,有 k k个不同的取值 a1 a1, a2 a2…… ak ak,根据特征A的取值将数据集D划分为 k k 个标签: D1 D1, D2 D2…… Dk Dk划分后的信息上为
Hsplited=∑j=1kP(Dj)H(Dj)=∑j=1klen(Dj)len(D)H(Dj) Hsplited=∑j=1kP(Dj)H(Dj)=∑j=1klen(Dj)len(D)H(Dj)
信息增益即为连个信息熵的差值:Gainsplited=H−Hsplited Gainsplited=H−Hsplited
熵越大,则表示越混乱;熵越小,则表示越有序。因此信息增益表示混乱的减小程度。
增益比率
增益比率是信息增益方法的一种扩展,是为了克服信息增益带来的弱泛化的缺陷。因为在极端情况下每个样本一对一到对应节点是,条件熵为0,此时获得的信息熵是最大的,但这种情况导致了过拟合。
故,引入引入信息增益比来作为一个更合适的衡量数据划分的标准,即增益比率。
SplitInfo(D)=∑j=1klen(Dj)len(D)log(len(Dj)len(D)) SplitInfo(D)=∑j=1klen(Dj)len(D)log(len(Dj)len(D))
课件,如果数据划分越多,对应的分裂信息的值也越大。这时候吧分裂信息放到坟墓上变回中和信息增益带来的弊端。
GianRatio=GainSplitInfo GianRatio=GainSplitInfo
决策树生成
典型的决策树生成算法有ID3和C4.5,这两种生成树过程大致相似。不同的是,ID3采用的是信息增益作为特征选取的度量,而C4.5采用的是信息增益比。
C4.5优缺点
- C4.5算法集成了ID3算法的有点,并在以下几个方面进行了改进:
- 采用信息增益率进行属性喧杂而,克服了采用信息增益选择属性偏向取值多的进行选择。
- 在树构造过程进行剪枝
- 对连续属性离散化处理
- 能够对不完整数据进行处理
- C4.5优点:产生的分类易于理解,准确率较高。
- C4.5缺点:需对数据集进行多次顺序扫描和排序,导致算法的低效。当训练集大时可能无法运行程序。
分类算法原理
SVM(Support Vector Machine)
训练数据集:
T={(x1,y1),(x2,y2),⋯,(xN,yN)}T={(x1,y1),(x2,y2),⋯,(xN,yN)}
其中,
xi∈X=Rn,yi∈Y={+1,−1},i=1,2,⋯,Nxi∈X=Rn,yi∈Y={+1,−1},i=1,2,⋯,N
xi xi 为第i 个特征向量, yi yi 为第 xi xi的标记,当 yi=+1 yi=+1 则 xi xi为正例;当 yi=−1 yi=−1 则 xi xi为负例。
线性支持可分向量
给定线性可分训练数据集,通过间隔最大化学习的分离超平面为:
w∗⋅x+b∗=0w∗⋅x+b∗=0
以及相应的分类决策函数为:
f(x)=sign(w∗⋅x+b∗) f(x)=sign(w∗⋅x+b∗)
超平面 (w,b) (w,b) 关于训练集T的函数间隔为:
γ^i=yi(w⋅xi+b)γ^i=yi(w⋅xi+b)
超平面 (w,b) (w,b) 关于训练集T的几何间隔为:
γi=yi(w∥w∥⋅xi+b∥w∥)γi=yi(w‖w‖⋅xi+b‖w‖)
函数间隔和几何间隔的关系:
γi=γ^i∥w∥γ=γ^∥w∥γi=γ^i‖w‖γ=γ^‖w‖
最大间隔分离超平面可转化为分类问题进行求解:
maxw,bγs.t.yi(w∥w∥⋅xi+b∥w∥)≥γ,i=1,2,⋯,Nmaxw,bγs.t.yi(w‖w‖⋅xi+b‖w‖)≥γ,i=1,2,⋯,N
进行等价转换为函数间隔进行约束,简化函数:
maxw,bγ^∥w∥s.t.yi(w⋅xi+b)≥γ^,i=1,2,⋯,Nmaxw,bγ^‖w‖s.t.yi(w⋅xi+b)≥γ^,i=1,2,⋯,N
函数间隔 γ^i γ^i并不影响最优化问题的解,为了简化函数,可令 γ^i=1 γ^i=1,将其等价转化为:
minw,b12∥w∥2s.t.yi(w⋅xi+b)−1≥0,i=1,2,⋯,Nminw,b12‖w‖2s.t.yi(w⋅xi+b)−1≥0,i=1,2,⋯,N
对上述方程构建拉格朗日乘子 αi≥0,i=1,2,⋯,N αi≥0,i=1,2,⋯,N
L(w,b,α)=12∥w∥2+∑i=1Nαi[−yi(w⋅xi+b)+1]=12∥w∥2−∑i=1Nαiyi(w⋅xi+b)+∑i=1NαiL(w,b,α)=12‖w‖2+∑i=1Nαi[−yi(w⋅xi+b)+1]=12‖w‖2−∑i=1Nαiyi(w⋅xi+b)+∑i=1Nαi
对拉格朗日乘子进行求导,从而求出 x x 最优解:
∇wL(w,b,α)=w−∑i=1Nαiyixi=0∇bL(w,b,α)=−∑i=1Nαiyi=0∇wL(w,b,α)=w−∑i=1Nαiyixi=0∇bL(w,b,α)=−∑i=1Nαiyi=0
可知,进行等价转化:
w=∑i=1Nαiyixi∑i=1Nαiyi=0w=∑i=1Nαiyixi∑i=1Nαiyi=0
带入拉格朗日乘子:
L(w,b,α)=12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαiyi[(∑j=1Nαjyjxj)⋅xi+b]+∑i=1Nαi=−12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαiyib+∑i=1Nαi=−12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)+∑i=1NαiL(w,b,α)=12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαiyi[(∑j=1Nαjyjxj)⋅xi+b]+∑i=1Nαi=−12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)−∑i=1Nαiyib+∑i=1Nαi=−12∑i=1N∑j=1Nαiαjyiyj(xi⋅xj)+∑i=1Nαi
线性支持向量机
在线性支持可分向量的基础上引入了了惩罚参数 C C:
minw,b,ξ12∥w∥2+C∑i=1Nξis.t.yi(w⋅xi+b)≥1−ξiξi≥0,i=1,2,⋯,Nminw,b,ξ12‖w‖2+C∑i=1Nξis.t.yi(w⋅xi+b)≥1−ξiξi≥0,i=1,2,⋯,N
每个松弛变量 xii xii都有对应的惩罚代价 Cxii Cxii,这里C>0代表惩罚参数。
- C值越大,对错误分类点的惩罚度越高,容忍度越低
- C值越小,对错误分类点的惩罚度越低,容忍度越高
非线性支持向量机
当分类问题难以进行线性分类时,利用高位的核函数将点映射到高维进行划分超平面。
设 X X是输入空间, H H是特征空间,存在 X X到 H H的映射:
ϕ(x):X→Hϕ(x):X→H
使得对所有 x x, z∈X z∈X, 函数 K(x,z) K(x,z)满足条件:
K(x,z)=ϕ(x)⋅ϕ(z)K(x,z)=ϕ(x)⋅ϕ(z)
常用的核函数:
1. 多项式核函数:
K(x,z)=(x⋅z+1)pK(x,z)=(x⋅z+1)p
- 高斯核函数:
K(x,z)=exp(−∥x−z∥22σ2)K(x,z)=exp(−‖x−z‖22σ2)
通过核函数和软间隔最大化,学习得到分类决策函数:
f(x)=sign(∑i=1Nα∗iyiK(x,xi)+b∗)f(x)=sign(∑i=1Nαi∗yiK(x,xi)+b∗)
SVM优缺点
- 优点:本质上是非线性方法,在样本较少时容易抓住数据和特征之间的非线性关系,避免神经网络结构选择和局部极小点问题、可以提高泛化性能、解决高维问题。
- 缺点:SVM对数据缺失敏感,对于样本数据较多时,复杂度为 O(n2) O(n2),复杂度较高