机器学习08经典算法

选择推荐标准:

一, KNN
K最近邻算法,简称KNN。K-Nearest Neighbor,意思是K个最近的邻居。
思路特别简单,就是随⼤流。对于需要贴标签的数据样本,它总是会找⼏个和⾃⼰离得最近的样本,也就是邻居,看看邻居的标签是什么。如果它的邻居中的⼤多数样本都是某⼀类样本,它就认为⾃⼰也是这⼀类样本。
距离的远和近看特征向量在特征空间中的距离。在KNN和其他机器学习算法中,常⽤的距离计算公式包括欧⽒距离和曼哈顿距离。
欧⽒距离:
曼哈顿距离:

因此,KNN算法的结果和K的取值有关系。
from sklearn.neighbors import KNeighborsClassifier # 导⼊KNN模型
K = 5 # 设定初始K值为5
KNN = KNeighborsClassifier(n_neighbors = K) # KNN模型
KNN.fit(X_train, y_train) # 拟合KNN模型
y_pred = KNN.predict(X_test) # 预测⼼脏病结果
from sklearn.metrics import (f1_score, confusion_matrix) # 导⼊评估指标
二,支持向量机SVM
超平⾯,就是⽤于特征空间根据数据的类别切分出来的分界平⾯。
⽀持向量,就是离当前超平⾯最近的数据点。
下图实例:H0就是⽬前的超平⾯。与之平⾏的H1H2线上的特征点就是⽀持向量。

SVM算法就是要在⽀持向量的帮助之下,通过类似于梯度下降的优化⽅法,找到最优的分类超平⾯——具体的⽬标就是令⽀持向量到超平⾯之间的垂直距离最宽,称为“最宽街道”。
from sklearn.svm import SVC # 导⼊SVM模型
svm = SVC(random_state = 1)
svm.fit(X_train, y_train)
y_pred = svm.predict(X_test) # 预测⼼脏病结果
svm_acc = svm.score(X_test, y_test)*100
print("SVM预测准确率:: {:.2f}%".format(svm.score(X_test, y_test)*100))print("SVM预测F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))print('SVM混淆矩阵:\n', confusion_matrix(y_pred, y_test))
普通的SVM分类超平⾯只能应对线性可分的情况,对于⾮线性的分类,SVM要通过核⽅法(kernel method)解决。⾸先通过某种⾮线性映射(核函数)对特征粒度进⾏细化,将原始数据的特征嵌⼊合适的更⾼维特征空间;然后,利⽤通⽤的线性模型在这个新的空间中分析和处理模式,这样,将
在⼆维上线性不可分的问题在多维上变得线性可分。
三,朴素贝叶斯
朴素⻉叶斯是⼀个通过条件概率进⾏分类的算法。所谓条件概率,就是在事件A发⽣的概率下B发⽣的概率。
⽐如:男,80岁,⾎压150mmHg,这3个已发⽣的事件,就是样本已知的特征。下⾯就需要进⾏⼆分类,确定患病还是未患病。怎么办呢?看⼀下训练数据集中满⾜这3个条件的数据有多少个,然后计算概率和计算分布。假如还有3个同样是80岁的男⼈,⾎压也是150mmHg,两个有⼼脏病,⼀个健康。此时算法就告诉我们,应该判断这个⼈也有⼼脏病的概率⽐较⼤。
数学公式即为:

在机器学习实践中,可以将上⾯的公式拆分成多个具体的特征:

from sklearn.naive_bayes import GaussianNB # 导⼊朴素⻉叶斯模型
nb = GaussianNB()
nb.fit(X_train, y_train)
y_pred = nb.predict(X_test) # 预测⼼脏病结果
当没有太多数据并且需要快速得到结果时,朴素⻉叶斯算法可以说是解决分类问题的良好选择。
四,决策树DT(了解概念,实际少用)
决策树(Decision Trees,DT),可以应⽤于回归或者分类问题,所以有时候也叫分类与回归树。将⼀⼤堆的if…else语句进⾏连接,直到最后得到想要的结果。
决策树中最看重什么,先看什么。

在信息学中,熵(entropy),度量着信息的不确定性,信息的不确定性越⼤,熵越⼤。信息熵和事件发⽣的概率成反⽐。
信息熵代表随机变量的复杂度,也就是不确定性。条件熵代表在某⼀个条件下,随机变量的复杂度。
信息增益等于信息熵减去条件熵,它代表了在某个条件下,信息复杂度(不确定性)减少的程度。
如果⼀个特征从不确定到确定,这个过程对结果影响⽐较⼤的话,熵(不确定性)减少得最多,也就是信息增益最⼤,就最先判断。书中例子先看脸是因为觉得脸好不好看这一特征从不确定到确定对相亲结果界定最大,结果的不确定性大幅减少。
决策树的深度和剪枝:
决策树算法⾮常容易过拟合。也就是说,在训练集上,只要分得⾜够细,就能得到100%的正确结果,然⽽在测试集上,准确率会显著下降。因为将训练集的一些特例数据也学习到了条件中,导致测试集不对劲。
解决的⽅法是为决策树进⾏剪枝(pruning),有以下两种形式。
- 先剪枝:分⽀的过程中,熵减少的量⼩于某⼀个阈值时,就停⽌分⽀的创建。
- 后剪枝:先创建出完整的决策树,然后尝试消除多余的节点。
但是还是容易过拟合,泛化能力差,决策树很少独⽴作为⼀种算法被应⽤于实际问题。实际常用决策树经过集成的各种升级版的算法——随机森林、梯度提升树算法等。
from sklearn.tree import DecisionTreeClassifier # 导⼊决策树模型
dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)
dtc_acc = dtc.score(X_test, y_test)*100
y_pred = dtc.predict(X_test) # 预测⼼脏病结果
print("Decision Tree Test Accuracy {:.2f}%".format(dtc_acc))
print("决策树 预测准确率: {:.2f}%".format(dtc.score(X_test, y_test)*100))print("决策树 预测F1分数: {:.2f}%".format(f1_score(y_test, y_pred)*100))print('决策树 混淆矩阵:\n', confusion_matrix(y_pred, y_test))
五,随机森林(决策树升级)
决策树很容易过拟合,⽽随机森林的思路是把很多棵决策树的结果集成起来,以避免过拟合,同时提⾼准确率。其中,每⼀棵决策树都是在原始数据集中抽取不同⼦集进⾏训练的,尽管这种做法会⼩幅度地增加每棵树的预测偏差,但是最终对各棵树的预测结果进⾏综合平均之后的模型性能通常会⼤⼤提⾼。
构造过程
假设我们有⼀个包含N个训练样本的数据集,特征的维度为M,随机森林通过下⾯算法构造树。
- 1)从N个训练样本中以有放回抽样(replacement
sampling)的⽅式,取样N次,形成⼀个新训练集(这种⽅法也叫bootstrap取样),可⽤未抽到的样本进⾏预测,评估其误差。 - 2)对于树的每⼀个节点,都随机选择m个特征(m是M的⼀个⼦集,数⽬远⼩于M),决策树上每个节点的决定都只是基于这些特征确定的,即根据这m个特征,计算最佳的分裂⽅式。
- 3)默认情况下,每棵树都会完整成⻓⽽不会剪枝。
算法有两个关键点:⼀个是有放回抽样,⼆是节点⽣成时不总是考量全部特征。
from sklearn.ensemble import RandomForestClassifier
# 导⼊随机森林模型
rf = RandomForestClassifier(n_estimators = 1000, random_state = 1)
rf.fit(X_train, y_train)
rf_acc = rf.score(X_test, y_test)*100
y_pred = rf.predict(X_test) # 预测⼼脏病结果
随机森林算法⼴泛适⽤于各种问题,尤其是针对浅层的机器学习任务,随机森林算法很受欢迎。
六,选择合适机器学习算法

调参与优化:
内容参数是算法内部的权重和偏置,⽽超参数是算法的参数,例如逻辑回归中的C值、神经⽹络的层数和优化器、KNN中的K值,都是超参数。算法的内部参数,是算法通过梯度下降⾃⾏优化,⽽超参数通常依据经验⼿⼯调整。利⽤Sklearn的⽹格搜索(Grid Search)功能,可以为特定机器学习算法找到每⼀个超参数指定范围内的最佳值。
from sklearn.model_selection import StratifiedKFold # 导⼊K折验证⼯具
from sklearn.model_selection import GridSearchCV # 导⼊⽹格搜索⼯具
kfold = StratifiedKFold(n_splits=10) # 10折验证
rf = RandomForestClassifier() # 随机森林模型
# 对随机森林算法进⾏参数优化
rf_param_grid = {"max_depth": [None],
"max_features": [3, 5, 12],
"min_samples_split": [2, 5, 10],
"min_samples_leaf": [3, 5, 10],
"bootstrap": [False],
"n_estimators" :[100,300],
"criterion": ["gini"]}
rf_gs = GridSearchCV(rf,param_grid = rf_param_grid, cv=kfold,
scoring="accuracy", n_jobs= 10, verbose = 1)
rf_gs.fit(X_train, y_train) # ⽤优化后的参数拟合训练数据集
10个“后台⼯作者”开始分批同步对54种参数组合中的每⼀组参数,⽤10折验证的⽅式对训练集进⾏训练(因为是10折验证,所以共需训练540次)并⽐较,试图找到最佳参数。
更多推荐


所有评论(0)