机器学习算法综合应用


数据集及源码获取地址:
链接:https://pan.baidu.com/s/1Q64QqMUBB5PkvOPgBGI3bQ
提取码:tz2k


实验任务:

  • 对分类模型进行评估,计算各个模型的 准确率、ROC 曲线、AUG 以及混淆矩阵。
  • 学生必须选一个 Scikit-learn 自带的数据集用于本实验。

1.KNN算法

原理

knn算法就是采用测量不同特征值之间的距离方法进行分类。存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类对应的关系。输入没有标签的数据后,将新数据中的每个特征与样本集中数据对应的特征进行比较,提取出样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k近邻算法中k的出处,通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类作为新数据的分类。

优缺点

  • 优点:精度高、对异常值不敏感
  • 缺点:计算复杂度高、空间复杂度高

参考文章:https://blog.csdn.net/zf_14159265358979/java/article/details/89970803

数据集介绍

尾花数据集(Iris Dataset)

  • 该数据集包含了三种不同品种的鸢尾花(Setosa, Versicolour, 和 Virginica) 。

  • 我们的目标是建立一个基础的机器学习的模型预测鸢尾花的品种。

  • 每个鸢尾花样本上采集四个特征: 花瓣(petal)的长度,宽度 和 花萼(sepal)的长度,宽度,厘米为单位

  • 总共150个样本,所以最终的数据存储为 150x4 numpy.ndarray。

  • numpy.ndarray 的每一行对应一个样本,

  • 而四个特征构成的四列的顺序为: Sepal Length, Sepal Width, Petal Length , Petal Width .

  • 参考文章:https://blog.csdn.net/qq_15537309/article/details/89048496

1.数据分析与数据预处理

# 1、导入数据集,分析数据集
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

iris_dataset = load_iris()  # 返回字典类型数据
# print(iris_dataset)  # data是花的属性,target是品种编号(0,1,2)
# print(iris_dataset.keys())
# print(iris_dataset['data'])
data = iris_dataset['data']
Sepal= data[:,:2] # 萼片
Petal=data[:,2:4] # 花瓣
labels = iris_dataset['target'] # 品种编号
class_ = iris_dataset['target'] # 品种编号
# print(class_)
# print(Sepal)
# 画出点图查看分布
plt.figure(figsize=(10,7))
plt.subplot(211)
plt.scatter(Sepal[:,0],Sepal[:,1],c=class_,s=10,cmap='rainbow',label='Petal')
plt.legend(loc='upper right')

plt.subplot(212)
plt.scatter(Petal[:,0],Petal[:,1],c=class_,s=10,cmap='rainbow',label='Sepal')
plt.legend(loc='upper left')
plt.show()

#分析数据
import pandas as pd
X = pd.DataFrame(data)
X.head(10)
0 1 2 3
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
5 5.4 3.9 1.7 0.4
6 4.6 3.4 1.4 0.3
7 5.0 3.4 1.5 0.2
8 4.4 2.9 1.4 0.2
9 4.9 3.1 1.5 0.1

数据标准化

在实际应用中,样本的不同特征的单位不同,会在求距离时造成很大的影响。比如:在两个样本中肿瘤大小的分别为1cm和5cm,发现时间分别为100天和200天,那么在求距离时,时间差为100、大小差为4,那么其结果会被时间所主导,因为肿瘤大小的差距太小了。但是如果我们把时间用年做单位,0.27年与0.55年的差距又远小于肿瘤大小的差距,结果又会被大小主导了。

在量纲不同的情况下,以上的情况,不能反映样本中每一个特征的重要程度。一般来说,我们的解决方案是:把所有的数据都映射到同一个尺度(量纲)上

数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。

标准化数据通过减去均值然后除以方差(或标准差),这种数据标准化方法经过处理后数据符合标准正态分布,即均值为0,标准差为1

参考博客:https://blog.csdn.net/qq_27276951/java/article/details/103160576

from sklearn.preprocessing import StandardScaler
standardScaler = StandardScaler()
standardScaler.fit(X)
StandardScaler(copy=True, with_mean=True, with_std=True)
print(standardScaler.mean_) #均值
print(standardScaler.var_) #方差
print(standardScaler.scale_) #缩放比例
[5.84333333 3.05733333 3.758      1.19933333]
[0.68112222 0.18871289 3.09550267 0.57713289]
[0.82530129 0.43441097 1.75940407 0.75969263]
X_standard = standardScaler.transform(X)
X_standard = pd.DataFrame(X_standard)
X_standard.head(10)
0 1 2 3
0 -0.900681 1.019004 -1.340227 -1.315444
1 -1.143017 -0.131979 -1.340227 -1.315444
2 -1.385353 0.328414 -1.397064 -1.315444
3 -1.506521 0.098217 -1.283389 -1.315444
4 -1.021849 1.249201 -1.340227 -1.315444
5 -0.537178 1.939791 -1.169714 -1.052180
6 -1.506521 0.788808 -1.340227 -1.183812
7 -1.021849 0.788808 -1.283389 -1.315444
8 -1.748856 -0.362176 -1.340227 -1.315444
9 -1.143017 0.098217 -1.283389 -1.447076
# 画出点图查看分布
plt.figure(figsize=(10,7))
plt.subplot(211)
plt.scatter(X_standard[:][0],X_standard[:][1],c=class_,s=10,cmap='rainbow',label='Petal')
plt.legend(loc='upper right')

plt.subplot(212)
plt.scatter(X_standard[:][2],X_standard[:][3],c=class_,s=10,cmap='rainbow',label='Sepal')
plt.legend(loc='upper left')
plt.show()

2.数据划分与模型训练

KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30, p=2,
metric='minkowski', metric_params=None, n_jobs=1, **kwargs)

参数:

  • 1.n_neighbors: 一个整数,指定k值。
  • 2.weights: 一字符串或者可调用对象,指定投票权重类型。即这些邻居投票权可以为相同或者不同。
    • uniform: 本节点的所有邻居节点的投票权重都相等。
    • distance: 本节点的所有邻居节点的投票权重与距离成反比,即越近节点,其投票权重越大。
  • 3.algorithm: 一个字符串,指定最近邻的算法,可以为下:
    • ball_tree: 使用BallTree算法。
    • kd_tree: 使用KDTree算法。
    • brute: 使用暴力搜索算法。
    • auto: 自动决定最合适算法。
  • 4.leaf_size: 一个整数,指定BallTree或者KDTree叶节点的规模。它影响树的构建和查询速度。
  • 5.metric: 一个字符串,指定距离度量。默认为‘minkowski’(闵可夫斯基)距离。
  • 6.p: 整数值。
    • p=1: 对应曼哈顿距离。
    • p=2: 对应欧氏距离。
  • 7.n_jobs: 并行性。默认为-1表示派发任务到所有计算机的CPU上。

方法:

  • 1.fit(X,y): 训练模型。
  • 2.predict(X): 预测模型。
  • 3.score(X,y): 返回在(X,y)上预测的准确率(accuracy)。
  • 4.predict_proba(X): 返回样本为每种标记的概率。
  • 5.kneighbors([X,n_neighbors,return_distace]): 返回样本点的k邻近点。如果return_distance=True,同时还返回到这些近邻点的距离。
  • 6.kneighbors_graph([X,n_neighbors,mode]): 返回样本点的连接图。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_standard,labels, random_state=0, test_size=0.25)
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=3, p=2,
                     weights='uniform')
acc_train = knn.score(X_train,y_train)
acc_test = knn.score(X_test,y_test)
print('训练集准确率:',acc_train)
print('测试集准确率:',acc_test)
训练集准确率: 0.9732142857142857
测试集准确率: 0.9736842105263158
X_train, X_test, y_train, y_test = train_test_split(X,labels, random_state=0, test_size=0.25)
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
acc_train = knn.score(X_train,y_train)
acc_test = knn.score(X_test,y_test)
print('训练集准确率:',acc_train)
print('测试集准确率:',acc_test)
训练集准确率: 0.9642857142857143
测试集准确率: 0.9736842105263158

3.模型评估与参数调优

交叉验证

"交叉验证法" (cross alidation) 将数据分为k个大小相似的互斥子集,D = D1 U D2 U... U Dk, Di n Dj = ø (i!=j) 每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到.然后,每次用k-1个子集的并集作为训练集,余下的那个子集作用作试集;这样就可获得k组训练集/测试集,从而可进行k次训练和测试,最终返回的是这k个测试结果的均值,显然,交叉验证法评估结果的稳定性和保真性,在很大程度上取决于k的取值,为强调这一点,通常把交叉验证法称为 "k折交叉验证" (k-fold cross validation). 最常用k的取值为10,此时称为10折交叉验 其他常用5,20等

交叉验证优点

  • 1:交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。
  • 2:还可以从有限的数据中获取尽可能多的有效信息。

sklearn中的交叉验证

from sklearn.model_selection import cross_val_score ,通过在cross_val_score 指定参数来设定评测标准;

sklearn.model_selection.cross_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)

当cv指定为int 类型时,默认使用KFold 或StratifiedKFold 进行数据集打乱.

  • KFold
    • K折交叉验证,这是将数据集分成K份的官方给定方案,所谓K折就是将数据集通过K次分割,使得所有数据既在训练集出现过,又在测试集出现过,当然,每次分割中不会有重叠。相当于无放回抽样。
  • 或StratifiedKFold
    • 通过指定分组,对测试集进行无放回抽样。

除使用默认交叉验证方式外,可以对交叉验证方式进行指定,如验证次数,训练集测试集划分比例等

  • from sklearn.model_selection import ShuffleSplit
  • cv = ShuffleSplit(n_splits=3, test_size=0.3, random_state=0)
  • cross_val_score(clf, iris.data, iris.target, cv=cv)
from sklearn.model_selection import cross_val_score
from time import time
import datetime
X_train, X_test, y_train, y_test = train_test_split(X_standard,labels, random_state=0, test_size=0.25)
k_range = range(1,31,2)
cv_scores = []
time0 = time()
for n in k_range:
    knn = KNeighborsClassifier(n_neighbors=n)
    scores = cross_val_score(knn,X_train,y_train,cv=10,scoring='accuracy')
    cv_scores.append(scores.mean())
print('计算所用时长:%s' % (datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f")))
print('最高准确率:',max(cv_scores),',对应的k值为:',k_range[cv_scores.index(max(cv_scores))])
plt.plot(k_range,cv_scores)
plt.xlabel('K')
plt.ylabel('Accuracy')
plt.show()
计算所用时长:00:00:575065
最高准确率: 0.9651515151515152 ,对应的k值为: 7

best_knn = KNeighborsClassifier(n_neighbors=3)
best_knn.fit(X_train,y_train)
print('训练集准确率:',best_knn.score(X_train,y_train))
print('测试集准确率:',best_knn.score(X_test,y_test))
训练集准确率: 0.9732142857142857
测试集准确率: 0.9736842105263158
best_knn = KNeighborsClassifier(n_neighbors=7)
best_knn.fit(X_train,y_train)
print('训练集准确率:',best_knn.score(X_train,y_train))
print('测试集准确率:',best_knn.score(X_test,y_test))
训练集准确率: 0.9732142857142857
测试集准确率: 0.9736842105263158
best_knn = KNeighborsClassifier(n_neighbors=13)
best_knn.fit(X_train,y_train)
print('训练集准确率:',best_knn.score(X_train,y_train))
print('测试集准确率:',best_knn.score(X_test,y_test))
训练集准确率: 0.9553571428571429
测试集准确率: 0.9736842105263158

混淆矩阵

混淆矩阵是机器学习中总结分类模型预测结果的情形分析表,以矩阵形式将数据集中的记录按照真实的类别与分类模型预测的类别判断两个标准进行汇总。其中矩阵的行表示真实值,矩阵的列表示预测值。

  • precision:预测为对的当中,原本为对的比例(越大越好,1为理想状态)
  • recall:原本为对的当中,预测为对的比例(越大越好,1为理想状态)
  • accuracy:预测对的(包括原本是对预测为对,原本是错的预测为错两种情形)占整个的比例(越大越好,1为理想状态)

二分类

  • 精确率Precision=a/(a+c)=TP/(TP+FP),
  • 召回率recall=a/(a+b)=TP/(TP+FN),
  • 准确率accuracy=(a+d)/(a+b+c+d)=(TP+FN+FP+TN)

多分类

  • 精确率_类别1=a/(a+d+g)
  • 召回率_类别1=a/(a+b+c)

参考博客

ROC与AUC

为什么用ROC:

  • 因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化

很多学习器是为测试样本产生一个实值或概率预测,然后将这个预测值与一个分类阈值(threshold) 进行比较,若大于阈值值则分为正类,否则为反类.

根据学习器的预测结果对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次计算出两个重要量的值,分别以它们为横、纵坐标作图就得到了 "ROC 曲线"

  • 真正例(True Positive Rate,TPR),表示所有正例中,预测为正例的比例:TPR=TP/(TP+FN)
  • 假正例(False Positive Rate,FPR),表示所有负例中,预测为正例的比例:FPR=FP/(TN+FP)

ROC 曲线的纵轴是"真正例率" (True Positive Rate ,简称 TPR) ,横轴是"假正例率" (False Positive Rate ,简称 FPR)

一个学习器的 ROC 曲线被另一个学习器的曲线完全"包住", 则可断言后者的性能优于前者;若两个学习器的ROC曲线发生交叉,则难以-般性地断言两者孰优孰劣此时如果一定要进行比较则较为合理的判据是比较 ROC 线下的面积,即 AUC (Area UnderROC Curve)

首先AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率,就是AUC值。当然,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。

用AUC判断分类器(预测模型)优劣的标准:

  • AUC = 1 是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
  • 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
  • AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

多分类的roc

假设测试样本个数为m,类别个数为n(假设类别标签分别为:0,2,...,n-1)。在训练完成后,计算出每个测试样本的在各类别下的概率或置信度,得到一个[m, n]形状的矩阵P,每一行表示一个测试样本在各类别下概率值(按类别标签排序)。相应地,将每个测试样本的标签转换为类似二进制的形式,每个位置用来标记是否属于对应的类别(也按标签排序,这样才和前面对应),由此也可以获得一个[m, n]的标签矩阵L。

比如n等于3,标签应转换为:

  • 方法1:每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。
  • 方法2:首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。

上面的两个方法得到的ROC曲线是不同的,当然曲线下的面积AUC也是不一样的。 在python中,方法1和方法2分别对应sklearn.metrics.roc_auc_score函数中参数average值为'macro'和'micro'的情况。

参考博客

# y = label_binarize(labels, classes=[0, 1, 2])
y = labels
# n_classes = y.shape[1]
X = X_standard
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,random_state=0)
best_knn = KNeighborsClassifier(n_neighbors=7)
best_knn.fit(X_train,y_train)
print('训练集准确率:',best_knn.score(X_train,y_train))
print('测试集准确率:',best_knn.score(X_test,y_test))
训练集准确率: 0.9732142857142857
测试集准确率: 0.9736842105263158

混淆矩阵

# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = best_knn.predict(X_test)
c2= confusion_matrix(y_test, y_pred, labels=[0, 1, 2])
c2
array([[13,  0,  0],
       [ 0, 15,  1],
       [ 0,  0,  9]], dtype=int64)

ROC与AUC

# ROC
from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import label_binarize
import numpy as np
y = labels
X = X_standard
X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=0)
knn = KNeighborsClassifier(n_neighbors=11)
knn.fit(X_train, Y_train)
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=11, p=2,
                     weights='uniform')
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
knn_y_score = knn.predict_proba(X_test)
knn_y_score.shape
(38, 3)
print ("原始数据条数:%d;训练数据条数:%d;特征个数:%d;测试样本条数:%d" % (len(X), len(X_train), X_train.shape[1], X_test.shape[0]))
原始数据条数:150;训练数据条数:112;特征个数:4;测试样本条数:38
y_test_hot.ravel().shape
knn_y_score.ravel().shape
(114,)
114/9
12.666666666666666
knn_fpr, knn_tpr, _ = roc_curve(y_test_hot.ravel(),knn_y_score.ravel())
knn_fpr.shape
knn_tpr.shape
(13,)
knn_auc = auc(knn_fpr, knn_tpr)
knn_auc
0.9937673130193906
plt.plot(knn_fpr, knn_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('roc')
plt.show()

knn_auc = auc(knn_fpr, knn_tpr)
knn_auc
0.9937673130193906
X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)
k_range = range(1,31,2)
aucs = []
time0 = time()
for n in k_range:
    knn = KNeighborsClassifier(n_neighbors=n)
    knn.fit(X_train, Y_train)
    y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
    knn_y_score = knn.predict_proba(X_test)
    knn_fpr, knn_tpr, knn_threasholds = roc_curve(y_test_hot.ravel(),knn_y_score.ravel())
    knn_auc = auc(knn_fpr, knn_tpr)
    aucs.append(knn_auc)
print('计算所用时长:%s' % (datetime.datetime.fromtimestamp(time()-time0).strftime("%M:%S:%f")))
print('最高auc:',max(aucs),',对应的k值为:',k_range[aucs.index(max(aucs))])
plt.plot(k_range,aucs)
plt.xlabel('K')
plt.ylabel('auc')
plt.show()
计算所用时长:00:00:089758
最高auc: 0.9875346260387812 ,对应的k值为: 13

knn = KNeighborsClassifier(n_neighbors=13)
knn.fit(X_train, Y_train)
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
knn_y_score = knn.predict_proba(X_test)
knn_fpr, knn_tpr, knn_threasholds = roc_curve(y_test_hot.ravel(),knn_y_score.ravel())
knn_auc = auc(knn_fpr, knn_tpr)
plt.plot(knn_fpr, knn_tpr,
         label='micro-average ROC curve',
         color='g', linestyle=':', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('roc')
plt.show()
print("auc:",knn_auc)

auc: 0.9875346260387812

总结

知识点:

  • 1.knn原理
  • 2.数据标准化
  • 3.交叉验证
  • 4.混淆矩阵
  • 5.roc曲线与auc

knn分类鸢尾花数据(数据太少,不同的random可能有不同的结果):

  • 最好的k为7
  • 最高准确率为0.9736842105263158
  • 最高的auc值:0.9937673130193906

2.决策树算法

原理:

决策树是一类常见的机器学习方法,通过历史数据得到的树结构模型对新数据进行分类决策。

树中的每个非叶子节点记录了使用哪个特征来进行类别的判断,每个叶子节点则代表了最后判断的类别。根节点到每个叶子节点均形成一条分类的路径规则。

每次判断都是对某个属性的测试,每次判断都会缩小考虑的范围。

一棵决策树包含一个根节点、若干个内部结点和若干个叶节点;叶节点对应于决策结果,其他每个节点则对应于一个属性测试;每个节点包含的样本集合根据属性测试的结果被划分到子节点;

根节点包含样本全集。从根节点到每个叶节点的路径对应了一个判断测试序列。

特征选择:

  • 1.信息增益
  • 2.基尼指数

sklearn中的决策树:

from sklearn.tree import DecisionTreeClassifier

DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None,min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None,
random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=1e-07, class_weight=None, presort=False)

'''
参数:

  • 1.criterion : 一个字符串,指定切分质量的评价标准。可以为:
    ‘gini’ :表示切分标准是Gini系数。切分时选取基尼系数小的属性切分。
    ‘entropy’ : 表示切分标准是熵。
  • 2.splitter : 一个字符串,指定切分原则,可以为:
    best : 表示选择最优的切分。
    random : 表示随机切分。
    默认的"best"适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐"random"。
  • 3.max_features : 可以为整数、浮点、字符或者None,指定寻找best split时考虑的特征数量。
    如果是整数,则每次切分只考虑max_features个特征。
    如果是浮点数,则每次切分只考虑max_features*n_features个特征(max_features指定了百分比)。
    如果是字符串‘auto’,则max_features等于n_features。
    如果是字符串‘sqrt’,则max_features等于sqrt(n_features)。
    如果是字符串‘log2’,则max_features等于log2(n_features)。
    如果是字符串None,则max_features等于n_features。
  • 4.max_depth : 可以为整数或者None,指定树的最大深度,防止过拟合
    如果为None,表示树的深度不限(知道每个叶子都是纯的,即叶子结点中的所有样本点都属于一个类,
    或者叶子中包含小于min_sanples_split个样本点)。
    如果max_leaf_nodes参数非None,则忽略此项。
  • 5.min_samples_split : 为整数,指定每个内部节点(非叶子节点)包含的最少的样本数。
  • 6.min_samples_leaf : 为整数,指定每个叶子结点包含的最少的样本数。
  • 7.min_weight_fraction_leaf : 为浮点数,叶子节点中样本的最小权重系数。
  • 8.max_leaf_nodes : 为整数或None,指定叶子结点的最大数量。
    如果为None,此时叶子节点数不限。
    如果非None,则max_depth被忽略。
  • 9.min_impurity_decrease=0.0 如果该分裂导致不纯度的减少大于或等于该值,则将分裂节点。
  • 10.min_impurity_split=1e-07, 限制决策树的增长,
  • 11.class_weight : 一个字典、字典的列表、字符串‘balanced’或者None,他指定了分类的权重。
    权重形式为:{class_label:weight} 如果为None,则每个分类权重都为1.
    字符串‘balanced’表示每个分类的权重是各分类在样本出现的频率的反比。
  • 12.random_state : 一个整数或者一个RandomState实例,或者None。
    如果为整数,则它指定了随机数生成器的种子。
    如果为RandomState实例,则指定了随机数生成器。
    如果为None,则使用默认的随机数生成器。
  • 13.presort : 一个布尔值,指定了是否要提前排序数据从而加速寻找最优切分的过程。设置为True时,对于大数据集会减慢总体训练过程,但对于小数据集或者设定了最大深度的情况下,则会加速训练过程。

属性:

  • 1.classes_ : 分类的标签值。
  • 2.feature_importances_ : 给出了特征的重要程度。该值越高,则特征越重要(也称为Gini importance)。
  • 3.max_features_ : max_feature的推断值。
  • 4.n_classes_ : 给出了分类的数量。
  • 5.n_features_ : 当执行fit后,特征的数量。
  • 6.n_outputs_ : 当执行fit后,输出的数量。
  • 7.tree_ : 一个Tree对象,即底层的决策树。

方法:

  • 1.fit(X,y) : 训练模型。
  • 2.predict(X) : 用模型预测,返回预测值。
  • 3.predict_log_proba(X) : 返回一个数组,数组元素依次为X预测为各个类别的概率值的对数值。
  • 4.predict_proba(X) : 返回一个数组,数组元素依次为X预测为各个类别的概率值。
  • 5.score(X,y) : 返回在(X,y)上预测的准确率(accuracy)。
    '''

1.导入数据集

y = labels
X = X_standard

2.划分数据集

X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)

3.模型训练及预测

from sklearn.tree import DecisionTreeClassifier

'''
DecisionTreeClassifier() 模型方法中也包含非常多的参数值。例如:
criterion = gini/entropy 可以用来选择用基尼指数或者熵来做损失函数。
splitter = best/random 用来确定每个节点的分裂策略。支持“最佳”或者“随机”。
max_depth = int 用来控制决策树的最大深度,防止模型出现过拟合。
min_samples_leaf = int 用来设置叶节点上的最少样本数量,用于对树进行修剪。
'''

dt_model= DecisionTreeClassifier()  # 所以参数均置为默认状态
dt_model.fit(X_train, Y_train)  # 使用训练集训练模型
predict_results = dt_model.predict(X_test)  # 使用模型对测试集进行预测
print(predict_results)
score = dt_model.score(X_test,Y_test)
print(score)
[2 0 1 1 1 1 2 1 0 0 2 2 0 2 2 0 1 1 2 0 0 1 2 0 2 1 1 2 0 0 2 0 0 0 2 0 0
 1]
0.8947368421052632

4.调参与评估

网格搜索

Grid Search:一种调参手段;穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)

交叉验证经常与网格搜索进行结合,作为参数评价的一种方法,这种方法叫做grid search with cross validation。sklearn因此设计了一个这样的类GridSearchCV,这个类实现了fit,predict,score等方法,被当做了一个estimator,使用fit方法,该过程中:(1)搜索到最佳参数;(2)实例化了一个最佳参数的estimator;

eg:
from sklearn.model_selection import GridSearchCV

把要调整的参数以及其候选值 列出来;

param_grid = {"gamma":[0.001,0.01,0.1,1,10,100],
"C":[0.001,0.01,0.1,1,10,100]}

print("Parameters:{}".format(param_grid))

grid_search = GridSearchCV(SVC(),param_grid,cv=5) #实例化一个GridSearchCV类

X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=10)

grid_search.fit(X_train,y_train) #训练,找到最优的参数,同时使用最优的参数实例化一个新的SVC estimator。

print("Test set score:{:.2f}".format(grid_search.score(X_test,y_test)))

print("Best parameters:{}".format(grid_search.best_params_))

print("Best score on train set:{:.2f}".format(grid_search.best_score_))

from sklearn.model_selection import GridSearchCV

param_grid = {"criterion":["gini","entropy"], "max_depth":[2,3,4,5,6],"min_samples_leaf":[1,2,3]}
grid_search = GridSearchCV(DecisionTreeClassifier(),param_grid,cv=5) #实例化一个GridSearchCV类
grid_search.fit(X_train, Y_train)
GridSearchCV(cv=5, error_score=nan,
             estimator=DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None,
                                              criterion='gini', max_depth=None,
                                              max_features=None,
                                              max_leaf_nodes=None,
                                              min_impurity_decrease=0.0,
                                              min_impurity_split=None,
                                              min_samples_leaf=1,
                                              min_samples_split=2,
                                              min_weight_fraction_leaf=0.0,
                                              presort='deprecated',
                                              random_state=None,
                                              splitter='best'),
             iid='deprecated', n_jobs=None,
             param_grid={'criterion': ['gini', 'entropy'],
                         'max_depth': [2, 3, 4, 5, 6],
                         'min_samples_leaf': [1, 2, 3]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring=None, verbose=0)
print("Test set score:{:.2f}".format(grid_search.score(X_test,Y_test)))

print("Best parameters:{}".format(grid_search.best_params_))

print("Best score on train set:{:.2f}".format(grid_search.best_score_))
Test set score:0.92
Best parameters:{'criterion': 'gini', 'max_depth': 3, 'min_samples_leaf': 1}
Best score on train set:0.97

混淆矩阵

dt = DecisionTreeClassifier(criterion= 'gini', max_depth= 3, min_samples_leaf= 1)
dt.fit(X_train, Y_train)
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                       max_depth=3, max_features=None, max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, presort='deprecated',
                       random_state=None, splitter='best')
# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = dt.predict(X_test)
c2= confusion_matrix(Y_test, y_pred, labels=[0, 1, 2])
c2
array([[15,  0,  0],
       [ 0,  9,  2],
       [ 0,  1, 11]], dtype=int64)

ROC与AUC

from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import label_binarize
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
dt_y_score = dt.predict_proba(X_test)
dt_y_score.shape
(38, 3)
y_test_hot.ravel()
dt_y_score.ravel().shape
(114,)
dt_fpr, dt_tpr, _ = roc_curve(y_test_hot.ravel(),dt_y_score.ravel())
dt_fpr.shape
dt_tpr.shape
(5,)
plt.plot(dt_fpr, dt_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('dt roc')
plt.show()

dt_auc = auc(dt_fpr, dt_tpr)
dt_auc
0.9397506925207757

总结

知识点:

  • 网格搜索

决策树在分类鸢尾花数据集上:

  • 最好的参数 :
    • Test set score:0.92
    • Best parameters:{'criterion': 'gini', 'max_depth': 3, 'min_samples_leaf': 1}
    • Best score on train set:0.97
  • 最高的auc值:0.9397506925207757

3.朴素贝叶斯算法

原理

条件概率是指事件A在另外一个事件B已经发生条件下的发生概率。 条件概率表示为: P(A|B), 读作“在B条件下A的概率”。若只有两个事件A, B, 那么:
P(AB)=P(A∣B)P(B)=P(B∣A)P(A)

那么:

贝叶斯公式是将全概率公式带入到条件概率公式当中, 对于事件Ak和事件B有:

朴素:假设各个事件是相互独立的

朴素贝叶斯公式:

from sklearn.naive_bayes import GaussianNB

1.导入数据集

y = labels
X = X_standard

2.划分数据集

X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)

3.模型训练及预测

g_bayes = GaussianNB()
bayes = g_bayes.fit(X_train,Y_train)
predict_result = bayes.predict(X_test)
score = bayes.score(X_train,Y_train)
print('训练集预测准确率:',score)
print('测试集预测结果:',predict_result)
score = bayes.score(X_test,Y_test)
print('测试集预测准确率:',score)
训练集预测准确率: 0.9910714285714286
测试集预测结果: [2 0 1 1 1 1 2 1 0 0 2 1 0 2 2 0 1 1 2 0 0 1 2 0 2 1 1 2 0 0 2 0 0 0 2 0 0
 1]
测试集预测准确率: 0.868421052631579

4.参数调优与评估

混淆矩阵

from sklearn.metrics import confusion_matrix
y_pred = bayes.predict(X_test)
c2= confusion_matrix(Y_test, y_pred, labels=[0, 1, 2])
c2
array([[15,  0,  0],
       [ 0,  9,  2],
       [ 0,  3,  9]], dtype=int64)

ROC与AUC

from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import label_binarize
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
bayes_y_score = bayes.predict_proba(X_test)
bayes_y_score.shape
(38, 3)
y_test_hot.ravel()
bayes_y_score.ravel().shape
(114,)
dt_fpr, dt_tpr, _ = roc_curve(y_test_hot.ravel(),bayes_y_score.ravel())
dt_fpr.shape
dt_tpr.shape
(18,)
plt.plot(dt_fpr, dt_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('bayes roc')
plt.show()

dt_auc = auc(dt_fpr, dt_tpr)
dt_auc
0.9823407202216066

总结

朴素贝叶斯在分类鸢尾花数据集上:

  • 最好的准确率 :
    • 训练集预测准确率:0.9910714285714286
    • 测试集预测准确率: 0.868421052631579
  • 最高的auc值:0.9823407202216066

出现了训练准确率很高,测试准确率很低的过拟合现象

4.逻辑回归

原理

逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,虽然名字中带有回归,但是它与回归之间有一定的联系。由于算法的简单和高效,在实际中应用非常广泛。

输入:

激活函数:

判断标准:

  • 回归的结果输入到sigmoid函数当中
  • 输出结果:[0, 1]区间中的一个概率值,默认为0.5为阈值

sklearn中的逻辑回归

from sklearn.linear_model import LogisticRegression

LogisticRegression(penalty='l2', dual=False, tol=1e-4, C=1.0, fit_intercept=True, intercept_scaling=1,
class_weight=None, random_state=None, solver='liblinear', max_iter=100,
multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
'''

参数含义:

  • 1.penalty:字符串,指定了正则化策略。默认为"l2"
    (1)如果为"l2",则优化的目标函数为:0.5||w||^2_2+CL(w),C>0,
    L(w)为极大似然函数。
    (2)如果为"l1",则优化的目标函数为||w||_1+C*L(w),C>0,
    L(w)为极大似然函数。
  • 2.dual:布尔值。默认为False。如果等于True,则求解其对偶形式。只有在penalty="l2"并且solver="liblinear"时才有对偶形式。如果为False,则求解原始形式。当n_samples > n_features,偏向于dual=False。
  • 3.tol:阈值。判断迭代是否收敛或者是否满足精度的要求。
  • 4.C:float,默认为1.0.指定了正则化项系数的倒数。必须是一个正的浮点数。他的值越小,正则化项就越大。
  • 5.fit_intercept:bool值。默认为True。如果为False,就不会计算b值。
  • 6.intercept_scaling:float, default 1。只有当solver="liblinear"并且 fit_intercept=True时,才有意义。在这种情况下,相当于在训练数据最后一列增加一个特征,该特征恒为1。其对应的权重为b。
  • 7.class_weight:dict or 'balanced', default: None。
    (1)如果是字典,则给出每个分类的权重。按照{class_label: weight}这种形式。
    (2)如果是"balanced":则每个分类的权重与该分类在样本集中出现的频率成反比。
    n_samples / (n_classes * np.bincount(y))
    (3)如果未指定,则每个分类的权重都为1。
  • 8.random_state: int, RandomState instance or None, default: None
    (1):如果为整数,则它指定了随机数生成器的种子。
    (2):如果为RandomState实例,则它指定了随机数生成器。
    (3):如果为None,则使用默认的随机数生成器。
  • 9.solver: 字符串,指定求解最优化问题的算法。{'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'},default: 'liblinear'
    (1)solver='liblinear',对于小数据集,'liblinear'是很好的选择。
    对于大规模数据集,'sag'和'saga'处理起来速度更快。
    (2)solver='newton-cg',采用牛顿法
    (3)solver='lbfgs',采用L-BFGS拟牛顿法。
    (4)solver='sag',采用Stochastic Average Gradient descent算法。
    (5)对于多分类问题,只有'newton-cg','sag','saga'和'lbfgs'处理多项损失;
    'liblinear'仅限于'ovr'方案。
    (6)newton-cg', 'lbfgs' and 'sag' 只能处理 L2 penalty,
    'liblinear' and 'saga' 能处理 L1 penalty。
  • 10.max_iter: 指定最大迭代次数。default: 100。只对'newton-cg', 'sag' and 'lbfgs'适用。
  • 11.multi_class:{'ovr', 'multinomial'}, default: 'ovr'。指定对分类问题的策略。
    (1)multi_class='ovr',采用'one_vs_rest'策略。
    (2)multi_class='multinomal',直接采用多分类逻辑回归策略。
  • 12.verbose: 用于开启或者关闭迭代中间输出日志功能。
  • 13.warm_start: 布尔值。如果为True,那么使用前一次训练结果继续训练。否则从头开始训练。
  • 14.n_jobs: int, default: 1。指定任务并行时的CPU数量。如果为-1,则使用所有可用的CPU。

属性

  • 1.coef_:权重向量。
  • 2.intercept_:截距b值。
  • 3.n_iter_:实际迭代次数。

方法

  • 1.fit(X,y): 训练模型。
  • 2.predict(X): 用训练好的模型进行预测,并返回预测值。
  • 3.predict_log_proba(X): 返回一个数组,数组元素依次是X预测为各个类别的概率的对数值。
  • 4.predict_proba(X): 返回一个数组,数组元素依次是X预测为各个类别的概率值。
  • 5.score(X,y): 返回预测的准确率。
    '''
from sklearn.linear_model import LogisticRegression
y = labels
X = X_standard
X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)
from sklearn.model_selection import GridSearchCV
param_grid = {"solver":['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'], "max_iter":[50,100,150,200],"penalty":['l1','l2']}
grid_search = GridSearchCV(LogisticRegression(),param_grid,cv=5) #实例化一个GridSearchCV类
grid_search.fit(X_train, Y_train)
GridSearchCV(cv=5, error_score=nan,
             estimator=LogisticRegression(C=1.0, class_weight=None, dual=False,
                                          fit_intercept=True,
                                          intercept_scaling=1, l1_ratio=None,
                                          max_iter=100, multi_class='auto',
                                          n_jobs=None, penalty='l2',
                                          random_state=None, solver='lbfgs',
                                          tol=0.0001, verbose=0,
                                          warm_start=False),
             iid='deprecated', n_jobs=None,
             param_grid={'max_iter': [50, 100, 150, 200],
                         'penalty': ['l1', 'l2'],
                         'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag',
                                    'saga']},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring=None, verbose=0)
print("Test set score:{:.2f}".format(grid_search.score(X_test,Y_test)))

print("Best parameters:{}".format(grid_search.best_params_))

print("Best score on train set:{:.2f}".format(grid_search.best_score_))
Test set score:0.87
Best parameters:{'max_iter': 50, 'penalty': 'l1', 'solver': 'saga'}
Best score on train set:0.98
log = LogisticRegression(penalty= 'l1', max_iter= 50, solver= 'saga')
log.fit(X_train, Y_train)
D:\programming_software_install\Anaconda3\lib\site-packages\sklearn\linear_model\_sag.py:330: ConvergenceWarning: The max_iter was reached which means the coef_ did not converge
  "the coef_ did not converge", ConvergenceWarning)





LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=50,
                   multi_class='auto', n_jobs=None, penalty='l1',
                   random_state=None, solver='saga', tol=0.0001, verbose=0,
                   warm_start=False)

混淆矩阵

# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = log.predict(X_test)
c2= confusion_matrix(Y_test, y_pred, labels=[0, 1, 2])
c2
array([[15,  0,  0],
       [ 0,  9,  2],
       [ 0,  3,  9]], dtype=int64)

ROC与AUC

from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.preprocessing import label_binarize
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
dt_y_score = log.predict_proba(X_test)
dt_y_score.shape
(38, 3)
dt_fpr, dt_tpr, _ = roc_curve(y_test_hot.ravel(),dt_y_score.ravel())
plt.plot(dt_fpr, dt_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('LogisticRegression roc')
plt.show()

dt_auc = auc(dt_fpr, dt_tpr)
dt_auc
0.9882271468144045

总结

逻辑回归在分类鸢尾花数据集上:

  • 最好的参数 :
    Best parameters:{'max_iter': 50, 'penalty': 'l1', 'solver': 'saga'}
  • 最高的准确率:
    Test set score:0.87
  • 最高的auc值:0.9882271468144045

5.支持向量机

原理

支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。

对于输入空间中的非线性分类问题,可以通过非线性变换将它转化为某个维特征空间中的线性分类问题,在高维特征空间中学习线性支持向量机。由于在线性支持向量机学习的对偶问题里,目标函数和分类决策函数都只涉及实例和实例之间的内积,所以不需要显式地指定非线性变换,而是用核函数替换当中的内积。核函数表示,通过一个非线性转换后的两个实例间的内积。

sklearn中的svc

SVC实现了非线性分类支持向量机

from sklearn.svm import SVC

SVC(C=1.0, kernel='rbf', degree=3, gamma='auto_deprecated', coef0=0.0, shrinking=True,
probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False,
max_iter=-1, decision_function_shape='ovr', random_state=None)
'''

参数

  • 1.C:惩罚参数,默认值是1.0
    C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,
    这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。
  • 2.kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’,
    ‘precomputed’(表示使用自定义的核函数矩阵)
  • 3.degree :多项式poly函数的阶数,默认是3,选择其他核函数时会被忽略。
  • 4.gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
  • 5.coef0 :核函数的常数项。对于‘poly’和 ‘sigmoid’有用。
  • 6.probability :是否采用概率估计.这必须在调用fit()之前启用,并且会fit()方法速度变慢。默认为False
  • 7.shrinking :是否采用启发式收缩方式方法,默认为True
  • 8.tol :停止训练的误差值大小,默认为1e-3
  • 9.cache_size :指定训练所需要的内存,以MB为单位,默认为200MB。
  • 10.class_weight :类别的权重,字典形式传递。设置第几类的参数C为weight*C(SVC中的C)
  • 11.verbose :用于开启或者关闭迭代中间输出日志功能。
  • 12.max_iter :最大迭代次数。-1为无限制。
  • 13.decision_function_shape :‘ovo’, ‘ovr’ or None, default=‘ovr’
  • 14.random_state :数据洗牌时的种子值,int值

属性

  • 1.support_ 支持向量的索引
  • 2.support_vectors_ 支持向量
  • 3.n_support_ 每个类别的支持向量的数目
  • 4.dual_coef_ : 一个数组,形状为[n_class-1,n_SV]。对偶问题中,在分类决策函数中每一个支持向量的系数。
  • 5.coef_ : 一个数组,形状为[n_class-1,n_features]。原始问题中,每个特征的系数。只有在linear kernel中有效。
  • 6.intercept_ : 一个数组,形状为[n_class*(n_class-1)/2]。决策函数中的常数项。
  • 7.fit_status_ : 整型,表示拟合的效果,如果正确拟合为0,否则为1
  • 8.probA_ : array, shape = [n_class * (n_class-1) / 2]
  • 9.probB_ : array, shape = [n_class * (n_class-1) / 2]
  • 10.probability: If probability=True, the parameters learned in Platt scaling to produce probability
    estimates from decision values.
    If probability=False, an empty array. Platt scaling uses the logistic function
    1 / (1 + exp(decision_value * probA_ + probB_)) where probA_ and probB_ are learned from the dataset.
    For more information on the multiclass case and training procedure see section 8 of LIBSVM:
    A Library for Support Vector Machines (in References) for more.

用法

  • 1.decision_function(X): 样本X到决策平面的距离
  • 2.fit(X, y[, sample_weight]): 训练模型
  • 3.get_params([deep]): 获取参数
  • 4.predict(X): 预测
  • 5.score(X, y[, sample_weight]): 返回预测的平均准确率
  • 6.set_params(**params): 设定参数
    '''

1.导入数据集

y = labels
X = X_standard

2.划分数据集

X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)

3.模型训练及预测

from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
param_grid = {"C":[0.6,0.8,1.0], "kernel":['linear', 'poly', 'rbf', 'sigmoid'],"max_iter":[-1,50,100,150,200,250],"gamma":np.logspace(-5, 1, 30)}
grid_search = GridSearchCV(SVC(),param_grid,cv=5) #实例化一个GridSearchCV类
grid_search.fit(X_train, Y_train)
GridSearchCV(cv=5, error_score=nan,
             estimator=SVC(C=1.0, break_ties=False, cache_size=200,
                           class_weight=None, coef0=0.0,
                           decision_function_shape='ovr', degree=3,
                           gamma='scale', kernel='rbf', max_iter=-1,
                           probability=False, random_state=None, shrinking=True,
                           tol=0.001, verbose=False),
             iid='deprecated', n_jobs=None,
             param_grid={'C': [0.6, 0.8, 1.0],
                         'gamma': array([1.000000...
       2.04335972e-02, 3.29034456e-02, 5.29831691e-02, 8.53167852e-02,
       1.37382380e-01, 2.21221629e-01, 3.56224789e-01, 5.73615251e-01,
       9.23670857e-01, 1.48735211e+00, 2.39502662e+00, 3.85662042e+00,
       6.21016942e+00, 1.00000000e+01]),
                         'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],
                         'max_iter': [-1, 50, 100, 150, 200, 250]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring=None, verbose=0)
print("Test set score:{:.2f}".format(grid_search.score(X_test,Y_test)))

print("Best parameters:{}".format(grid_search.best_params_))

print("Best score on train set:{:.2f}".format(grid_search.best_score_))
Test set score:0.87
Best parameters:{'C': 0.6, 'gamma': 0.1373823795883264, 'kernel': 'rbf', 'max_iter': -1}
Best score on train set:0.99

混淆矩阵

svc = SVC(C= 0.6, gamma= 0.1373823795883264, kernel= 'rbf', max_iter= -1).fit(X_train,Y_train)
# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = svc.predict(X_test)
c2= confusion_matrix(Y_test, y_pred, labels=[0, 1, 2])
c2
array([[15,  0,  0],
       [ 0,  9,  2],
       [ 0,  3,  9]], dtype=int64)
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
svc_y_score = svc.decision_function(X_test)
svc_y_score.shape
(38, 3)
svc_fpr, svc_tpr, _ = roc_curve(y_test_hot.ravel(),svc_y_score.ravel())
plt.plot(svc_fpr, svc_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('SVC roc')
plt.show()

svc_auc = auc(svc_fpr, svc_tpr)
svc_auc
0.9747229916897506

总结

svm分类鸢尾花数据:

  • 最好的参数:Best parameters:{'C': 0.6, 'gamma': 0.1373823795883264, 'kernel': 'rbf', 'max_iter': -1}
  • 最高准确率为Test set score:0.87
  • 最高的auc值:0.9747229916897506

6.Adaboost增强算法

Adaboost与原始的boosting过程不同,它使用整个训练集来训练弱学习机,其中训练样本在每次迭代中都会被重新赋予一个权重,在上一弱学习机错误的基础上进行学习,进而构建一个更加强大的分类器。

  • 1、训练过程:

    对于每一个新的学习器,AdaBoost改变训练数据的权值,也就是样本的概率分布,
    其思想是将关注点放在被错误分类的样本上,减小上一轮被正确分类的样本权值,提高那些被错误分类的样本权值。
    然后,再根据所采用的一些基本机器学习算法进行学习。

  • 2、集成过程:

    AdaBoost采用加权多数表决的方法,加大分类误差率小的弱分类器的权重,减小分类误差率大的弱分类器的权重。
    使正确率更高的分类器有更大的发言权

  • 3、参数:

    • 1、 base_estimator:
      我们的弱分类学习器或者弱回归学习器,理论上可以选择任何一个分类或者回归学习器,
      不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,
    • 2、 algorithm:
      scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。
      两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,
      即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。
      由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。
      我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R,
      则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。
    • 3、n_estimators:
      弱学习器的最大迭代次数,或者说最大的弱学习器的个数。
      一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。
      默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
    • 4、learning_rate:
      每个弱学习器的权重缩减系数。
      对于同样的训练集拟合效果,较小的意味着我们需要更多的弱学习器的迭代次数。
      通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
      一般来说,可以从一个小一点的开始调参,默认是1。

基于决策树的Adaboost预测鸢尾花

from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
y = labels
X = X_standard
X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=10)
# 通过改变参数求的最佳分类效果和最佳参数
depths = np.linspace(1, 10, 10)
estimators = [50, 100, 150, 200, 250, 300, 400, 500, 600]
algorithms = ['SAMME', 'SAMME.R']
scores = []
param = []
for depth in depths:
    for estimator in estimators:
        for algorithm in algorithms:
            bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=int(depth)), algorithm=algorithm,
                                     n_estimators=int(estimator))
            bdt.fit(X_train, Y_train)
            score = bdt.score(X_test, Y_test)
            scores.append(score)
            if score == max(scores):
                param = []
                param.append(depth)
                param.append(estimator)
                param.append(algorithm)

print('最高准确率:',max(scores))
print('最佳参数:',param)
最高准确率: 1.0
最佳参数: [3.0, 300, 'SAMME.R']
# 测试
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=3), algorithm='SAMME.R',n_estimators=600)
bdt.fit(X_train, Y_train)
score_train = bdt.score(X_train, Y_train)
score_test = bdt.score(X_test, Y_test)
print('训练准确率:',score_train)
print('测试准确率:',score_test)
训练准确率: 1.0
测试准确率: 1.0

混淆矩阵

# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred = bdt.predict(X_test)
c2= confusion_matrix(Y_test, y_pred, labels=[0, 1, 2])
c2
array([[11,  0,  0],
       [ 0, 15,  0],
       [ 0,  0, 12]], dtype=int64)

ROC与AUC

y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
dt_y_score = bdt.predict_proba(X_test)
dt_y_score.shape
(38, 3)
dt_fpr, dt_tpr, _ = roc_curve(y_test_hot.ravel(),dt_y_score.ravel())
plt.plot(dt_fpr, dt_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('dt roc')
plt.show()

dt_auc = auc(dt_fpr, dt_tpr)
dt_auc
1.0

总结

基于决策树的Adaboost在分类鸢尾花数据集上:

  • 最好的参数 :
    • 训练准确率: 1.0
    • 测试准确率: 1.0
    • Best parameters: [3.0, 600, 'SAMME.R']
  • 最高的auc值:1.0

7.随机森林

随机森林是非常具有代表性的Bagging集成算法,它的所有基评估器都是决策树,分类树组成的森林就叫做随机森
林分类器,回归树所集成的森林就叫做随机森林回归器。

from sklearn.ensemble import RandomForestClassifier

RandomForestClassifier(n_estimators='warn', criterion='gini', max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto',
max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None,
bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0,
warm_start=False, class_weight=None)

'''

参数:

  • 1.n_estimators :一个整数,指定基础决策树的数量(默认为10).
  • 2.criterion:字符串。指定分裂的标准,可以为‘entory’或者‘gini’。
  • 3.max_depth:一个整数或者None,指定每一个基础决策树模型的最大深度。如果max_leaf_nodes不是None,则忽略此参数。
  • 4.min_samples_split:一个整数,指定了每个基础决策树模型分裂所需最小样本数。
  • 5.min_samples_leaf:一个整数,指定了每个基础决策树模型叶节点所包含的最小样本数。
  • 6.min_weight_fraction_leaf:一个浮点数。叶节点的最小加权权重。当不提供sample_weight时,样本的权重是相等的。
  • 7.max_features:一个整数,浮点数或者None。代表节点分裂是参与判断的最大特征数。整数为 个数,浮点数为所占比重。
  • 8.max_leaf_nodes:为整数或者None,指定了每个基础决策树模型的最大叶节点数量。
  • 9.bootstrap:为布尔值。如果为True,则使用采样法bootstrap sampling来产生决策树的训练数据。
  • 10.oob_score:为布尔值。如果为True,则使用包外样本来计算泛化误差。
  • 11.n_jobs:一个整数,指定并行性。如果为-1,则表示将训练和预测任务派发到所有CPU上。
  • 12.verbose:一个整数,如果为0则不输出日志,如果为1,则每隔一段时间输出日志,大于1输出日志会更频繁。
  • 13.warm_start:布尔值。当为True是,则继续使用上一次训练结果。否则重新开始训练。
  • 14.random_state:一个整数或者一个RandomState实例,或者None。
    如果为整数,指定随机数生成器的种子。
    如果为RandomState,指定随机数生成器。
    如果为None,指定使用默认的随机数生成器。
  • 15.class_weight:一个字典,或者字典的列表,或者字符串‘balanced’,或者字符串
    ‘balanced_subsample’,或者为None。
    如果为字典,则字典给出每个分类的权重,如{class_label:weight}
    如果为字符串‘balanced’,则每个分类的权重与该分类在样本集合中出现的频率成反比。
    如果为字符串‘balanced_subsample’,则样本为采样法bootstrap sampling产生的决策树的训练数据,
    每个分类的权重与该分类在样本集合中出现的频率成反比。
    如果为None,则每个分类的权重都为1。

属性:

  • 1.estimators_:一个数组,存放所有训练过的决策树。
  • 2.classes_:一个数组,形状为[n_classes],为类别标签。
  • 3.n_classes_:一个整数,为类别数量。
  • 4.n_features_:一个整数,在训练时使用的特征数量。
  • 5.n_outputs_:一个整数,在训练时输出的数量。
  • 6.feature_importances_:一个数组,形状为[n_features]。如果base_estimator支持,则他给出每个特征的重要性。
  • 7.oob_score_:一个浮点数,训练数据使用包外估计时的得分。

方法:

  • 1.fit(X,y):训练模型。
  • 2.predict(X):用模型进行预测,返回预测值。
  • 3.predict_log_proba(X):返回一个数组,数组的元素依次是X预测为各个类别的概率的对数值。
  • 4.predict_proba(X):返回一个数组,数组的元素依次是X预测为各个类别的概率值。
  • 5.score(X,y):返回在(X,y)上预测的准确度。
    '''
from sklearn.ensemble import RandomForestClassifier
y = labels
X = X_standard
X_train,X_test,Y_train,Y_test = train_test_split(X, y, test_size=0.25, random_state=2020)
from sklearn.model_selection import GridSearchCV

param_grid = {"n_estimators":np.arange(10,30,1),"criterion":['entory','gini'], "max_depth":[2,3,4,5,6],"min_samples_leaf":[1,2,3]}
grid_search = GridSearchCV(RandomForestClassifier(),param_grid,cv=5) #实例化一个GridSearchCV类
grid_search.fit(X_train, Y_train)
GridSearchCV(cv=5, error_score=nan,
             estimator=RandomForestClassifier(bootstrap=True, ccp_alpha=0.0,
                                              class_weight=None,
                                              criterion='gini', max_depth=None,
                                              max_features='auto',
                                              max_leaf_nodes=None,
                                              max_samples=None,
                                              min_impurity_decrease=0.0,
                                              min_impurity_split=None,
                                              min_samples_leaf=1,
                                              min_samples_split=2,
                                              min_weight_fraction_leaf=0.0,
                                              n_estimators=100, n_jobs=None,
                                              oob_score=False,
                                              random_state=None, verbose=0,
                                              warm_start=False),
             iid='deprecated', n_jobs=None,
             param_grid={'criterion': ['entory', 'gini'],
                         'max_depth': [2, 3, 4, 5, 6],
                         'min_samples_leaf': [1, 2, 3],
                         'n_estimators': array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
       27, 28, 29])},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring=None, verbose=0)
print("Test set score:{:.2f}".format(grid_search.score(X_test,Y_test)))

print("Best parameters:{}".format(grid_search.best_params_))

print("Best score on train set:{:.2f}".format(grid_search.best_score_))
Test set score:0.87
Best parameters:{'criterion': 'gini', 'max_depth': 2, 'min_samples_leaf': 1, 'n_estimators': 26}
Best score on train set:1.00

ROC与AUC

rfc = RandomForestClassifier(criterion= 'gini', max_depth= 2, min_samples_leaf= 1, n_estimators= 17).fit(X_train,Y_train)
y_test_hot = label_binarize(Y_test, classes=(0, 1, 2))
dt_y_score = rfc.predict_proba(X_test)
dt_y_score.shape
(38, 3)
dt_fpr, dt_tpr, _ = roc_curve(y_test_hot.ravel(),dt_y_score.ravel())
plt.plot(dt_fpr, dt_tpr,
         label='micro-average ROC curve',
         color='g', linewidth=4)
plt.plot([0, 1], [0, 1], 'k--', lw=2,c='r')
plt.title('RandomForestClassifier roc')
plt.show()

dt_auc = auc(dt_fpr, dt_tpr)
dt_auc
0.9802631578947368

总结

随机森林在分类鸢尾花数据集上:

  • 最好的参数 :
    • Test set score:0.87
    • Best parameters:{'criterion': 'gini', 'max_depth': 2, 'min_samples_leaf': 1, 'n_estimators': 17}
    • Best score on train set:0.97
  • 最高的auc值:0.9847645429362881

结论

在鸢尾花数据集上,使用基于决策树的Adaboost算法有最好的效果,knn次之

posted @ 2020-06-19 15:45  曾强  阅读(60)  评论(0编辑  收藏