前面兩篇都是介紹性的文字,這篇詳細介紹完整的“良/惡性乳腺癌腫瘤預測”問題的Python原始碼。
根據前兩篇的描述,大家可以確定“良/惡性乳腺癌腫瘤預測”的問題屬於二分類任務。待預測的類別分別是良性乳腺癌腫瘤和惡性乳腺癌腫瘤。通常我們使用離散的整數來代表類別。如下表,“腫瘤類型”一列列出了腫瘤的類型;0代表良性,1代表惡性。
| |
腫塊厚度 |
細胞尺寸 |
腫瘤類型 |
|
腫塊厚度 |
細胞尺寸 |
腫瘤類型 |
| 0 |
1 |
1 |
0 |
3 |
8 |
8 |
0 |
| 1 |
4 |
4 |
0 |
4 |
1 |
1 |
0 |
| 2 |
1 |
1 |
0 |
5 |
10 |
10 |
1 |
完整的資料集腫瘤的特徵不止這兩個,但是在這個例子中我們只取這兩個特徵,並且測試集數量為175條。我們先看一下這175條腫瘤樣本在二維特徵空間的分布情況,如下圖所示。X代表惡性腫瘤,O代表良性腫瘤。
繪製這張圖的代碼如下:
# -*- coding:utf-8 -*-# 匯入pandas包,別名為pdimport pandas as pd# 使用pandas的read_csv函數,將訓練集讀取進來並存至變數df_traindf_train = pd.read_csv('breast-cancer-train.csv')# 使用pandas的read_csv函數,將測試集讀取進來並存至變數df_testdf_test = pd.read_csv('breast-cancer-test.csv')# 選取Clump Thickness和Cell Size作為特徵,構建測試集中的正負分類樣本df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]# 匯入matplotlib工具包中的pyplot並命名為pltimport matplotlib.pyplot as plt# 繪製圖中的良性腫瘤樣本點,標記為紅色的oplt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')# 繪製圖中的噁心腫瘤樣本點,標記為黑色的xplt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')# 繪製x,y軸說明plt.xlabel('Clump Thickness')plt.ylabel('Cell Size')# 顯示圖plt.show() 隨後我們隨機初始化一個二類分類器,這個分類器用一條直線來劃分良/惡性腫瘤。決定這條直線的走向有兩個因素:直線的斜率和截距。這些被我們稱為模型的參數,也是分類器需要通過學習從訓練資料中得到的。最初,隨機初始化參數的分類器的效能表現如下圖所示:
繪製這張圖的代碼如下:
# -*- coding:utf-8 -*-# 匯入pandas包,別名為pdimport pandas as pd# 匯入matplotlib工具包中的pyplot並命名為pltimport matplotlib.pyplot as plt# 使用pandas的read_csv函數,將訓練集讀取進來並存至變數df_traindf_train = pd.read_csv('breast-cancer-train.csv')# 使用pandas的read_csv函數,將測試集讀取進來並存至變數df_testdf_test = pd.read_csv('breast-cancer-test.csv')# 選取Clump Thickness和Cell Size作為特徵,構建測試集中的正負分類樣本df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]# 匯入numpy工具包,重新命名為npimport numpy as np# 利用numpy中的random函數隨機採樣直線的截距和係數intercept = np.random.random([1])coef = np.random.random([2])lx = np.arange(0, 12)ly = (-intercept - lx * coef[0]) / coef[1]# 繪製一條隨機直線plt.plot(lx, ly, c='yellow')plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')plt.xlabel('Clump Thickness')plt.ylabel('Cell Size')plt.show() 隨後我們使用一定量訓練樣本,分類器所表現的效能有了大幅度的提示,如下圖:
繪製這張圖的代碼如下:
# -*- coding:utf-8 -*-# 匯入pandas包,別名為pdimport pandas as pd# 匯入numpy工具包,重新命名為npimport numpy as np# 匯入matplotlib工具包中的pyplot並命名為pltimport matplotlib.pyplot as plt# 匯入sklearn中的邏輯斯蒂迴歸分類器from sklearn.linear_model import LogisticRegression# 使用pandas的read_csv函數,將訓練集讀取進來並存至變數df_traindf_train = pd.read_csv('breast-cancer-train.csv')# 使用pandas的read_csv函數,將測試集讀取進來並存至變數df_testdf_test = pd.read_csv('breast-cancer-test.csv')# 選取Clump Thickness和Cell Size作為特徵,構建測試集中的正負分類樣本df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]lr = LogisticRegression()# 使用前10條訓練樣本學習直線的係數和截距lr.fit(df_train[['Clump Thickness', 'Cell Size']][:10], df_train['Type'][:10])print 'Testing accuracy (10 training samples):', lr.score(df_test[['Clump Thickness', 'Cell Size']], df_test['Type'])intercept = lr.intercept_coef = lr.coef_[0, :]lx = np.arange(0, 12)# 原本這個分類面應該是lx*coef[0] + ly*coef[1] + intercept=0 映射到2維平面上之後,應該是:ly = (-intercept - lx * coef[0]) / coef[1]plt.plot(lx, ly, c='green')plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')plt.xlabel('Clump Thickness')plt.ylabel('Cell Size')plt.show()
print的值為:Testing accuracy (10 training samples): 0.868571428571
如上圖所示,當學習了10條訓練樣本時,分類器的效能改進了一些,測試集上的分類準確性為86.9%;我們繼續學習所有訓練樣本,分類器的效能進一步提升,在測試集上的分類準確性最終達到93.7%,如下圖:
繪製這張圖的代碼如下:
# -*- coding:utf-8 -*-# 匯入pandas包,別名為pdimport pandas as pd# 匯入numpy工具包,重新命名為npimport numpy as np# 匯入matplotlib工具包中的pyplot並命名為pltimport matplotlib.pyplot as plt# 匯入sklearn中的邏輯斯蒂迴歸分類器from sklearn.linear_model import LogisticRegression# 使用pandas的read_csv函數,將訓練集讀取進來並存至變數df_traindf_train = pd.read_csv('breast-cancer-train.csv')# 使用pandas的read_csv函數,將測試集讀取進來並存至變數df_testdf_test = pd.read_csv('breast-cancer-test.csv')# 選取Clump Thickness和Cell Size作為特徵,構建測試集中的正負分類樣本df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]lr = LogisticRegression()# 使用前10條訓練樣本學習直線的係數和截距lr.fit(df_train[['Clump Thickness', 'Cell Size']], df_train['Type'])print 'Testing accuracy (10 training samples):', lr.score(df_test[['Clump Thickness', 'Cell Size']], df_test['Type'])intercept = lr.intercept_coef = lr.coef_[0, :]lx = np.arange(0, 12)# 原本這個分類面應該是lx*coef[0] + ly*coef[1] + intercept=0 映射到2維平面上之後,應該是:ly = (-intercept - lx * coef[0]) / coef[1]plt.plot(lx, ly, c='green')plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')plt.xlabel('Clump Thickness')plt.ylabel('Cell Size')plt.show() print的值為Testing accuracy (10 training samples): 0.937142857143
這份代碼只是幫大家理清一下最為基礎的python編程要素,方便對後面的執行個體進行理解和實踐。
資料地址http://pan.baidu.com/s/1jI00k8Q,大家可以去下載。