sklearn-SVM-乳腺癌诊断分类
支持向量机(SVM)是一种用于分类和回归的机器学习算法。它通过找到一个最优的超平面来最大化不同类之间的间隔。在乳腺癌诊断中,SVM用于分析特征数据(如mean、se、worst值),通过标准化和特征选择优化模型性能,并使用网格搜索选择最优参数以提高分类准确率。
目录
01 | SVM简介
02 | 乳腺癌诊断
1.导入必要的库包
2.配置seaborn绘图环境并调整pycharm窗口行高
3.基于线性核函数构建SVM模型
4.进行数据准备
5.实施数据预处理流程
6.进行数据特征分析
7.详细阐述模型训练流程
01 | SVM简介
SVM(支持向量机)算法通过数据训练实现间隔最大化以确定最佳分离超平面。
为了说明这一过程我们创建了一个基于男女身高体重的数据集。
对于二维空间而言我们可以通过直线将数据分割对于三维空间则使用平面进行划分而更高维度的空间则采用超平面来实现分类。
具体来说在二维空间中我们可以画一条直线将已知点分为两部分直线以上区域对应男性样本直线以下区域对应女性样本。
在三维空间中这条直线变为一个平面而在更高维度的空间中则被称为超平面。
我们需要找到能够将不同类别样本完全分开的面其中最为合适的就是最优分离超平面。
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    women_heigth = [155,145,157,160,167]
    women_weigth = [50,54,69,52,60]
    men_heigth = [164,170,173,180,185]
    men_weigth = [77,80,72,64,79]
    
    sns.scatterplot(x = women_heigth,y = women_weigth,markers = '+',color = 'orange',label = 'women')
    sns.scatterplot(x = men_heigth,y = men_weigth,markers = '^',color = 'blue',label = 'men')
    plt.xlabel('cm')
    plt.ylabel('kg',rotation = '0')
    plt.legend()
    plt.show()
        

02 | 乳腺癌诊断
数据集:
https://github.com/cystanford/breast_cancer_data/首先加载必要的库包。常用的Python数据分析工具包pandas和numpy用于数据预处理操作,并配合图库matplotlib和seaborn来展示数据分布情况。此外,在支持向量机算法相关的模块 sklearn.svm中包含了我们需要的分类器实现。为了提高模型泛化能力,在训练前会对特征进行标准化处理(采用 sklearn.preprocessing模块),并使用 train_test_split 方法将数据集划分为训练集和测试集两部分。为了使模型表现更加稳定,在模型性能评估过程中会调用 metrics 模块中的相关函数,并通过 GridSearchCV 方法优化模型超参数设置。
    from sklearn import svm
    import pandas as pd
    import sklearn.preprocessing
    import seaborn as sns
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn import metrics
    from sklearn.model_selection import GridSearchCV
    import numpy as np
        2.设置seabon,matplotlib中文显示,pycharm显示行数扩大
    pd.set_option('display.max_columns',1000)
    pd.set_option('display.width',1000)
    pd.set_option('display.max_colwidth',1000)
    plt.rcParams['font.sans-serif'] = ['SimHei']
    sns.set_style('whitegrid',{'font.sans-serif':['simhei','Arial']})
        3.svm实例化
① kernel参数用于设置核函数的具体类型。可选类型包括多项式核、径向基函数(rbf)、拉普拉斯径向基函数等,默认使用rbf核函数
② C参数定义了目标函数中的惩罚系数,默认值设为1.0
③ gamma参数设定核函数的缩放因子,默认取值是样本特征数量的倒数
    model = svm.SVC(kernel = 'rbf',C = 1.0,gamma = '0.001')
        - 数据集准备
不考虑id字段。
具体包括:
① 将以"mean"结尾的字段标记为平均值;以"se"结尾的标记为标准差;以"worst"结尾标记为最坏值(此处特指肿瘤特征的最大值)。
② diagnosis表示特征 
    df = pd.read_csv(r'D:\pycharm\data\breast_cancer_data-master\data.csv')
    print(df.info())
    print(df.head())
        

5.数据预处理
① 在放入模型前需将特征diagnosis的数据类型从字符串转换为数值型。
② 其中, mean能够充分反映特征的整体情况。
    le = sklearn.preprocessing.LabelEncoder()
    le.fit(df['diagnosis'])
    df['diagnosis'] = le.transform(df['diagnosis'])
    print(df['diagnosis'])
    
    df_X = df.filter(regex = '_mean')
    df_Y = pd.DataFrame(data = df['diagnosis'],columns = ['diagnosis'])
        6.描述分析
① 考察mean各项特征之间的关联性
② 利用热力图分析可知, radius_mean、perimeter_mean及area_mean这三项特征间呈现强相关性,因此建议仅选取其中表现最为显著的perimeter_mean
③ 由于这些数值均为连续型数据,推荐采用preprocessing.StandardScaler()对其进行归一化处理
    plt.figure(figsize = (8,15))
    sns.heatmap(df_X.corr(),linewidths = 0.1,vmax=1.0,square=True,cmap=sns.color_palette('RdBu', n_colors=256),
            linecolor='white', annot=True)
    plt.xticks(fontsize = 5)
    plt.yticks(fontsize = 5)
    plt.title('各特征之间的相关性')
    plt.show()
    
    df_X.drop(['radius_mean', 'area_mean'], axis=1)
    # 进行特征归一化/缩放
    df_X = sklearn.preprocessing.StandardScaler().fit_transform(df_X)
    df_Y = sklearn.preprocessing.LabelEncoder().fit_transform(df['diagnosis'])
    print(df_X)
    print(df_Y)
        


7.模型训练
① 方法一:LinearSVC 自动调参
② 方法二:主动调参
    '''
    # 方法①
    X_train, X_test, y_train, y_test = train_test_split(df_X,df_Y,test_size = 0.3,random_state = 0)
    svm_model = svm.LinearSVC().fit(X_train,y_train)
    pred = svm_model.predict(X_test)
    print('准确率:',metrics.accuracy_score(pred,y_test))
    '''
    
    # ② 方法二通过网格搜索寻找最优参数
    parameters = {
        'gamma': np.linspace(0.0001, 0.1),
        'kernel': ['linear', 'poly', 'rbf', 'sigmoid'],
    }
    svm_model1 = svm.SVC()
    # 寻找最优参数
    grid_model = GridSearchCV(svm_model1,parameters,cv=10,return_train_score=True)
    X_train, X_test, y_train, y_test = train_test_split(df_X,df_Y,test_size = 0.2)
    grid_model.fit(X_train,y_train)
    pred_label = grid_model.predict(X_test)
    # 模型最优参数
    print(grid_model.best_params_)
    # 输出准确率
    print('准确率:',metrics.accuracy_score(pred_label,y_test))
        
