• svm.SVC应用实践1--乳腺癌检测


    决策边界绘制函数封装

    参考书籍:《scikit-learn机器学习:常用算法原理及编程实战》
    参考博客:基于支持向量机的数据分类以及绘制决策边界(超平面)

    代码

    import matplotlib.pyplot as plt
    import numpy as np
    def plot_hyperplane(clf, X, y,
                        h=0.02,
                        draw_sv=True,
                        title='hyperplan'):
    
        x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
        y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
        # 生成网格点坐标矩阵,其中参数h控制间距
        xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                             np.arange(y_min, y_max, h))
    
        plt.title(title)
        plt.xlim(xx.min(), xx.max())
        plt.ylim(yy.min(), yy.max())
        plt.xticks(())
        plt.yticks(())
    
        Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # SVM的分割超平面
    
        Z = Z.reshape(xx.shape)
        # 为坐标矩阵的不同类别的点填充不同的颜色
        plt.contourf(xx, yy, Z, cmap='hot', alpha=0.5)
        plt.scatter(X[:,0],X[:,1],c=y)
    
    	# 是否将支持向量突出表示
        if draw_sv:
            sv = clf.support_vectors_
            plt.scatter(sv[:, 0], sv[:, 1], c='r', marker='.',s=1)
        plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    该函数基于matplotlib库中的contourf()函数,可以画出等高线并填充颜色的函数

    预测示例

    1. 简单的数据点

    import numpy as np
    from sklearn.pipeline import make.pipeline
    from sklearn.preprocessing import StandardScaler
    from sklearn.svm import SVC
    x=np.array([[-1,-1],[-2,-1],[1,1],[2,1]])
    y=np.array([1,1,2,2])
    clf=make_pipeline(StandardScaler(),SVC(gamma='atuo'))
    clf.fit(x,y)
    clf.predict([[-0.8,-1]])
    >>> [1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    此处我们要注意make_pipeline()函数与StandardScaler()函数的联合使用,常用于构建管道pipeline,数据预处理、模型拟合等操作“一条龙”!

    2. 生成数据点

    接下来我们首先生成一个有两个特征、三种类别的数据集

    from sklean.datasets import make_blobs
    x,y=make_blobs(n_samples=100,centers=3,random_state=0,cluster_std=0.8)
    
    • 1
    • 2

    然后使用线性核函数、三阶多项式核函数、 g a m m a gamma gamma=0.5、 g a m m a gamma gamma=0.1等4个SVC模型来拟合数据集,分别观察拟合效果

    from sklearn.svm import SVC
    clf_linear=svm.SVC(C=1.0,kernel='linear')
    clf_poly=svm.SVC(C=1.0,kernel='poly',degree=3)
    clf.rbf=svm.SVC(C=1.0,kernel='rbf',gamma=0.5)
    clf_rbf2=svm.SVC(C=1.0,kernel='rbf',gamma=0.1)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    最后将4个模型拟合出来的超平面画出来

    plt.figure(figsize=(10,10),dpi=144)
    clfs=[clf_linear,clf_poly,clf_rbf,clf_rbf2]
    title=['linear','poly','rbf','rbf2']
    for clf,i in zip(clfs,range(len(clfs))):
        clf.fit(x,y)
        plt.subplot(2,2,i+1)
        plot_hyperplane(clf,x,y,title=title[i])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果
    在这里插入图片描述通过上面例子我们发现,当支持向量机使用不同的核函数进行分类时候,绘制出的决策边界也会随着改变
    对于高斯核函数,gamma值过大会造成过拟合,过小则会使得高斯核函数退化为线性核函数,我们可以通过调节gamma的值来调整分隔超平面的形状

    3. 乳腺癌数据集

    首先我们加载出数据集

    from sklearn.datasets import load_breast_cancer
    cancer=load_breast_cancer()
    x=cancer.data
    y=cancer.target
    
    • 1
    • 2
    • 3
    • 4

    分割出训练集与测试集

    from sklearn.model_selection import train_test_split
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2)
    
    • 1
    • 2

    接下来我们使用不同的核函数对应的模型对数据进行拟合

    高斯核函数

    我们首先尝试使用高斯核函数训练模型,分别得到训练集得分和测试集得分

    from sklearn.svm import SVC
    clf=SVC(C=1.0,kernel='rbf',gamma=0.1)
    clf.fit(x_train,y_train)
    train_score=clf.score(x_train,y_train)
    test_score=clf.score(x_test,y_test)
    train_score,test_score
    >>> (0.98778345781,0.52631578949)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过观察实验结果,我们发现训练集接近满分,测试集评分很低,典型的过拟合现象!由于我们使用的是高斯核函数,所以我们可以尝试改变gamma参数值来调整模型的表现

    from sklearn.model_selection import GridSearchCV
    gammas=np.linspace(0,0.0003,30)
    grid={'gamma':gammas}
    clf=GridSearchCV(SVC(),grid,cv=5)
    clf.fit(x,y)
    clf.best_params_,clf.best_score_
    >>> ({'gamma': 0.00011379310344827585}, 0.9367334264865704)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    此处注意GridSearchCV()函数的常用于参数选择

    在最好的gamma参数下,平均最优得分也只有0.93…,说明该核函数对于该问题并非最合适的。

    但是我们同样可以通过学习曲线观察模型的拟合情况,取gamma=0.01

    import matplotlib.pyplot as plt
    from sklearn.model_selection import learning_curve
    from sklearn.model_selection import ShuffleSplit
    cv=ShuffleSplit(n_splits=10,test_size=0.2,random_state=0)
    title='gaussian kernel'
    plt.figure(figsize=(10,4),dpi=144)
    plot_learning_curve(SVC(C=1.0,gamma=0.01),title,x,y,cv=cv)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行结果
    在这里插入图片描述

    学习曲线的封装请参考sklearn官方api:plot_learning_curve()函数
    也可以参考笔者的博客:学习曲线的封装–learning_curve()函数

    交叉验证得分过低,明显的过拟合现象,下面我们尝试改变核函数

    多项式核函数

    from sklearn.svm import SVC
    clf=SVC(C=1.0,kernel='poly',degree=2)
    clf.fit(x_train,y_train)
    train_score=clf.score(x_train,y_train)
    test_score=clf.score(x_test,y_test)
    train_score,test_score
    >>> (0.9186813186813186, 0.9122807017543859)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    训练集和测试集两者的得分都比较高,看起来结果还可以,接下来我们分别画出一阶多项式、二阶多项式学习曲线

    from sklearn.model_selection import learning_curve
    cv=ShuffleSplit(n_splits=5,test_size=0.2,random_state=0)
    degrees=[1,2]
    plt.figure(figsize=(12,4),dpi=144)
    for i in range(len(degrees)):
    	plt.subplot(1,len(degrees),i+1)
    	title='degree_{}'.format(degrees[i])
    	plot_learning_curve(SVC(C=1.0,kernel='poly',degree=degrees[i]),title,x,y,cv=cv)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们可以看出,与一阶多项式相比,二阶多项式核函数的拟合效果较好,但仍然不是最理想的情况

    在这里插入图片描述
    实际上,从模型拟合结果以及运算效率等方面来看,支持向量机模型对于乳腺癌检测的问题或许并非是最优选择,其他模型在解决这一问题时或许能够达到更加理想的结果,因为在针对实际问题时,前期模型的选择非常重要

  • 相关阅读:
    DevChat助手:在数据库及数据分析上面的应用实践
    9.22 QT作业
    不知道照片加水印怎么弄?这三个方法让你轻松实现
    DO、DTO、BO、VO、POJO 的区别
    任务分配——斜率优化dp——运输小猫
    Java IO流与文件(一)
    Hazelcast系列(三):hazelcast管理中心
    首先要学习什么:Docker 还是 Kubernetes?
    可见性检测-unity掌握常见的可见性检测算法实现原理
    Linux防火墙之iptables(上)
  • 原文地址:https://blog.csdn.net/m0_54510474/article/details/125898294