SVM之乳腺癌檢測


SVM 是有監督的學習模型,我們需要事先對數據打上分類標簽,通過求解最大分類間隔來求解二分類問題。如果要求解多分類問題,可以將多個二分類器組合起來形成一個多分類器。

如何在 sklearn 中使用 SVM

# 導包
from sklearn import svm

SVM 既可以做回歸,也可以做分類器。

當用 SVM 做回歸的時候,我們可以使用 SVR 或 LinearSVR。SVR 的英文是 Support Vector Regression。

當做分類器的時候,我們使用的是 SVC 或者 LinearSVC。SVC 的英文是 Support Vector Classification。

從名字上你能看出 LinearSVC 是個線性分類器,用於處理線性可分的數據,只能使用線性核函數。SVM是通過核函數將樣本從原始空間映射到一個更高維的特質空間中,這樣就使得樣本在新的空間中線性可分。

如果是針對非線性的數據,需要用到 SVC。在 SVC 中,我們既可以使用到線性核函數(進行線性划分),也能使用高維的核函數(進行非線性划分)。

如何創建一個 SVM 分類器呢?

如何用 SVM 進行乳腺癌檢測

醫療人員采集了患者乳腺腫塊經過細針穿刺 (FNA) 后的數字化圖像,並且對這些數字圖像進行了特征提取,這些特征可以描述圖像中的細胞核呈現。腫瘤可以分成良性和惡性。部分數據截屏如下所示:

數據表一共包括了 32 個字段,代表的含義如下:

上面的表格中,mean 代表平均值,se 代表標准差,worst 代表最大值(3 個最大值的平均值)。每張圖像都計算了相應的特征,得出了這 30 個特征值(不包括 ID 字段和分類標識結果字段 diagnosis),實際上是 10 個特征值(radius、texture、perimeter、area、smoothness、compactness、concavity、concave points、symmetry 和fractal_dimension_mean)的 3 個維度,平均、標准差和最大值。這些特征值都保留了 4 位數字。字段中沒有缺失的值。在 569 個患者中,一共有 357 個是良性,212 個是惡性。

我們的目標是生成一個乳腺癌診斷的 SVM 分類器,並計算這個分類器的准確率。首先設定項目的執行流程:

  1. 首先我們需要加載數據源;

  2. 在准備階段,需要對加載的數據源進行探索,查看樣本特征和特征值,這個過程你也可以使用數據可視化,它可以方便我們對數據及數據之間的關系進一步加深了解。然后按照“完全合一”的准則來評估數據的質量,如果數據質量不高就需要做數據清洗。數據清洗之后,你可以做特征選擇,方便后續的模型訓練;

  3. 在分類階段,選擇核函數進行訓練,如果不知道數據是否為線性,可以考慮使用 SVC(kernel=‘rbf’) ,也就是高斯核函數的 SVM 分類器。然后對訓練好的模型用測試集進行評估。

加載數據並對數據做部分的探索:

# 加載數據集,你需要把數據放到目錄中
data = pd.read_csv("./data.csv")
# 數據探索
# 因為數據集中列比較多,我們需要把 dataframe 中的列全部顯示出來
# pd.set_option('display.max_columns', 10)        # 最多顯示10列,超過用省略號顯示
print(data.columns)
print(data.head(5))
print(data.describe())


# 部分運行結果:
Index(['id', 'diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean',
       'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean',
       'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean',
       'radius_se', 'texture_se', 'perimeter_se', 'area_se', 'smoothness_se',
       'compactness_se', 'concavity_se', 'concave points_se', 'symmetry_se',
       'fractal_dimension_se', 'radius_worst', 'texture_worst',
       'perimeter_worst', 'area_worst', 'smoothness_worst',
       'compactness_worst', 'concavity_worst', 'concave points_worst',
       'symmetry_worst', 'fractal_dimension_worst'],
      dtype='object')
         id diagnosis  radius_mean  texture_mean  perimeter_mean  area_mean  \
0    842302         M        17.99         10.38          122.80     1001.0   
1    842517         M        20.57         17.77          132.90     1326.0   
2  84300903         M        19.69         21.25          130.00     1203.0   
3  84348301         M        11.42         20.38           77.58      386.1   
4  84358402         M        20.29         14.34          135.10     1297.0 

數據清洗:

運行結果中,你能看到 32 個字段里,id 是沒有實際含義的,可以去掉。diagnosis 字段的取值為 B 或者 M,我們可以用 0 和 1 來替代。另外其余的 30 個字段,其實可以分成三組字段,下划線后面的 mean、se 和 worst 代表了每組字段不同的度量方式,分別是平均值、標准差和最大值。

# 將特征字段分成 3 組
features_mean= list(data.columns[2:12])
features_se= list(data.columns[12:22])
features_worst=list(data.columns[22:32])
# 數據清洗
# ID 列沒有用,刪除該列
data.drop("id",axis=1,inplace=True)
# 將 B 良性替換為 0,M 惡性替換為 1
data['diagnosis']=data['diagnosis'].map({'M':1,'B':0})

然后我們要做特征字段的篩選,首先需要觀察下 features_mean 各變量之間的關系,這里我們可以用 DataFrame 的 corr() 函數,然后用熱力圖幫我們可視化呈現。同樣,我們也會看整體良性、惡性腫瘤的診斷情況。

# 將腫瘤診斷結果可視化
sns.countplot(data['diagnosis'],label="Count")
plt.show()
# 用熱力圖呈現 features_mean 字段之間的相關性
corr = data[features_mean].corr()
plt.figure(figsize=(14,14))
# annot=True 顯示每個方格的數據
sns.heatmap(corr, annot=True)
plt.show()

# 特征選擇
features_remain = ['radius_mean','texture_mean', 'smoothness_mean','compactness_mean','symmetry_mean', 'fractal_dimension_mean'] 

對特征進行選擇之后,我們就可以准備訓練集和測試集:

# 抽取 30% 的數據作為測試集,其余作為訓練集
train, test = train_test_split(data, test_size = 0.3)# in this our main data is splitted into train and test
# 抽取特征選擇的數值作為訓練和測試數據
train_X = train[features_remain]
train_y=train['diagnosis']
test_X= test[features_remain]
test_y =test['diagnosis']

在訓練之前,我們需要對數據進行規范化,這樣讓數據同在同一個量級上,避免因為維度問題造成數據誤差:

# 采用 Z-Score 規范化數據,保證每個特征維度的數據均值為 0,方差為 1
ss = StandardScaler()
train_X = ss.fit_transform(train_X)
test_X = ss.transform(test_X)

最后我們可以讓 SVM 做訓練和預測了:

# 創建 SVM 分類器
model = svm.SVC()
# 用訓練集做訓練
model.fit(train_X,train_y)
# 用測試集做預測
prediction=model.predict(test_X)
print('准確率: ', metrics.accuracy_score(prediction,test_y))
# 運行結果
准確率:  0.9181286549707602

from sklearn import svm
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn import metrics

def train_func(func, features_remain, desc):
    #分類階段:模型訓練
    #抽取30%的數據作為測試集,其余作為訓練集
    train, test = train_test_split(data, test_size=0.3)
    train_x = train[features_remain]
    train_y = train['diagnosis']
    test_x = test[features_remain]
    test_y = test['diagnosis']

    ss = StandardScaler()
    train_x = ss.fit_transform(train_x)
    test_x = ss.transform(test_x)

    #創建SVM分類器
    if(func == "linear"):
        model = svm.LinearSVC()
    else:
        model = svm.SVC()
    #用訓練集做訓練
    model.fit(train_x, train_y)
    #用測試集做預測

    #分類階段:模型評估
    predict_y = model.predict(test_x)
    infos1 = "測試集准確率:" + str(metrics.accuracy_score(predict_y, test_y))

    predict_yy = model.predict(train_x)
    infos2 = "訓練集准確率:" + str(metrics.accuracy_score(predict_yy, train_y))
    print(desc + ":" + infos1 + " " + infos2)


#准備階段:數據探索
data = pd.read_csv('./breast_cancer_data-master/data.csv')
#把所有的列都顯示出來(在打印的時候)
pd.set_option('display.max_columns', None)

features_mean = list(data.columns[2:12])
features_se = list(data.columns[12:22])
features_worst = list(data.columns[22:32])

#准備階段:數據清洗,id列沒有用,刪除該列
data.drop("id", axis=1, inplace=True)
# 將B良性替換為0,M惡性替換為1
data['diagnosis']=data['diagnosis'].map({'M': 1, 'B': 0})

#准備階段:數據可視化
sns.countplot(data['diagnosis'], label='Count')
plt.show()
corr = data[features_mean].corr()
plt.figure(figsize=(14,14))
sns.heatmap(corr, annot=True)
plt.show()

#分類階段:特征選擇
features_remain = ['radius_mean', 'texture_mean', 'smoothness_mean', 'compactness_mean', 'symmetry_mean', 'fractal_dimension_mean']

#分類階段:模型訓練+模型評估
train_func('svc', features_remain, 'svc_six')
train_func('svc', features_mean, 'svc_all')
train_func('linear', features_remain, 'linearsvc_six')
train_func('linear', features_mean, 'linearsvc_all')

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM