恶性间皮瘤(MM),又被称为弥漫性恶性胸膜间皮瘤。恶性间皮瘤是原发于胸膜、侵袭性高的恶性肿瘤。恶性胸膜间皮瘤是胸膜原发肿瘤中最多见的类型。临床表现与侵袭行为有关,它通常局部侵袭胸膜腔及周围结构。如果不治疗,中位生存期4~12个月。以下列出一些其发病的主要相关因素:+ 石棉接触;+ 猿肾病毒40(SV40)感染;+ 遗传倾向性的;+ 分子机制;+ 农村生活。对于诊断恶性间皮瘤,可以基于一些临床监测指标(例如:石棉接触、白细胞、血小板计数、血清乳酸脱氢酶等)作为特征,建立分类模型,然后对是否患病进行预测。由于本案例中的特征数量比较多(34个),我们会先使用主成分分析(PCA)对特征数据先进行降维处理。之后再利用决策树算法来进行模型训练,并对比降维前后的训练出的模型性能。
我们使用UCI数据库中的"Mesotheliomas disease data set Data Set"数据集,包含324个样本点。每个样本包含34个特征变量,1个类别变量即(诊断结果为健康/患病),变量列表如下:
列名 | 说明 | 类型 | 示例 |
---|---|---|---|
age | 年龄 | Int | 47 |
gender | 性别(0或1) | Int | 1 |
city | 城市(0到8) | Int | 0 |
asbestos exposure | 石棉接触(0或1) | Int | 1 |
type of MM | 恶性间皮瘤的种类(0、1或2) | Int | 0 |
duration of asbestos exposure | 石棉接触时间 | Int | 20 |
diagnosis method | 诊断方法(0或1) | Int | 1 |
keep side | 0、1或2 | Int | 0 |
cytology | 细胞学检查(0或1) | Int | 1 |
duration of symptoms | 症状持续时间 | Float | 24 |
dyspnoea | 呼吸困难(0或1) | Int | 1 |
ache on chest | 胸部疼痛(0或1) | Int | 1 |
weakness | 虚弱(0或1) | Int | 0 |
habit of cigarette | 吸烟习惯(0到3) | Int | 2 |
performance status | 体力状态(0或1) | Int | 1 |
white blood | 白细胞 | Int | 8050 |
cell count (WBC) | 细胞计数(白细胞) | Int | 9 |
hemoglobin (HGB) | 血红蛋白(0或1) | Int | 1 |
platelet count (PLT) | 血小板计数 | Int | 274 |
sedimentation | 沉降 | Int | 60 |
blood lactic dehydrogenise (LDH) | 血清乳酸脱氢酶 | Int | 258 |
…… | …… | …… | …… |
class of diagnosis | 0:Healthy;1: Mesothelioma | Int | 0 |
首先,使用pandas中的 read_excel() 函数将数据加载到数据框中:
import numpy as np
import pandas as pd
df = pd.read_csv("./input/Mesothelioma.csv")
df.head(5)
df_value_ravel = df.values.ravel()
print u'数据中的缺失值个数:', len(df_value_ravel[df_value_ravel==np.nan])
主成分分析必须从相同量纲的变量表格开始。由于需要将变量总方差分配给特征根,因此变量必须有相同的物理单位,方差和才有意义(方差的单位是变量单位的平方),或者变量是无量纲的数据,例如标准化或对数转化后的数据。因此在构建模型之前,我们需要进行数据标准化。常用的标准化方法有 min-max 标准化和 z-score 标准化等。在本例中,我们直接采用 z-score 标准化方法。
首先说明一下sklearn中preprocessing库里面的scale函数使用方法: sklearn.preprocessing.scale(X, axis=0, with_mean=True,with_std=True,copy=True) 根据参数的不同,可以沿任意轴标准化数据集。
参数解释:
X:数组或者矩阵
axis:int类型,初始值为0,axis用来计算均值 means 和标准方差 standard deviations. 如果是0,则单独的标准化每个特征(列),如果是1,则标准化每个观测样本(行)
with_mean: boolean类型,默认为True,表示将数据均值规范到0
with_std: boolean类型,默认为True,表示将数据方差规范到1
我们将采用默认参数
from sklearn import preprocessing
X = df.iloc[:,:-1]
y = df['class of diagnosis']
perm = np.random.permutation(len(X))
X= X.loc[perm]
y=y[perm]
X = preprocessing.scale(X)
PCA就是通过寻找高维空间中,数据变化最快(方差最大)的方向,对空间的基进行变换,然后选取重要的空间基来对数据降维,以尽可能的保持数据特征的情况下对数据进行降维。
这里,我们使用sklearn模块中的decomposition库中的PCA算法实现主成分分析。函数原形如下:
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)
参数说明:
n_components:
copy:
whiten:
fit(X,y=None) fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。
fit(X),表示用数据X来训练PCA模型。
函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。
fit_transform(X) 用X来训练PCA模型,同时返回降维后的数据。 newX=pca.fit_transform(X),newX就是降维后的数据。
inverse_transform() 将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)
transform(X) 将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。
我们建立PCA对象,选择需要保留的维数为22,代码如下:
from sklearn.decomposition import PCA
pca = PCA(copy=True, n_components=22, whiten=False)
X_new = pca.fit_transform(X)
print u'所保留的n个主成分的方差贡献率为:'
print pca.explained_variance_ratio_
print u'排名前3的主成分特征向量为:'
print pca.components_[0:2]
print u'累计方差贡献率为:'
print sum(pca.explained_variance_ratio_)
可以看出,从34个特征变量缩减为22个特征变量以后,累计方差贡献率为86.48%。表明新生成的特征综合描述原数据的能力较高。
为了检验使用PCA降维后的数据的分类表现,我们使用 sklearn 包中的 tree.DecisionTreeClassifier 类。将数据切分成80%的数据作为训练集,20%的数据作为测试集
from sklearn import tree
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_new, y, test_size=.2,random_state=0)
训练模型
clf = tree.DecisionTreeClassifier()
clf.fit(X_train,y_train)
print clf
首先,使用predict()函数得到上一节训练的支持向量机模型在测试集合上的预测结果,然后使用 sklearn.metrics中的相关函数对模型的性能进行评估。
from sklearn import metrics
y_predict = clf.predict(X_test)
print metrics.classification_report(y_test, y_predict)
print metrics.confusion_matrix(y_test,y_predict)
上述混淆矩阵中对角线的元素表示模型正确预测数,对角元素之和表示模型整体预测正确的样本数。
现在,让我们来通过这个来计算模型在测试集中的预测正确率。
print "Accuracy: ", metrics.accuracy_score(y_test, y_predict)
可见,训练得到的模型在原始集的20%的测试样本中,预测的正确率(Accuaray)为87.69%。
为了检验使用降维之后的数据训练出的模型与使用降维之前的数据训练出的模型相比,仍然能够保持较高的性能,对没有经过降维处理的数据进行模型训练,代码如下:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2,random_state=0)
clf2 = tree.DecisionTreeClassifier()
clf2.fit(X_train,y_train)
y_predict = clf2.predict(X_test)
print metrics.classification_report(y_test, y_predict)
print metrics.confusion_matrix(y_test,y_predict)
上述混淆矩阵中对角线的元素表示模型正确预测数,对角元素之和表示模型整体预测正确的样本数。 现在,让我们来通过这个来计算模型在测试集中的预测正确率。
print "Accuracy: ", metrics.accuracy_score(y_test, y_predict)
可见,训练得到的模型在原始集的20%的测试样本中,预测的正确率(Accuaray)为100%。
经过对比,降维后的precision为0.89,比降维前小0.11;降维后的recall为0.88,比降维前小0.12;降维后的f1-score为0.88,比降维前小0.12;降维后的正确率为0.88比降维前低0.12。可以得知,使用降维之后的数据训练出的模型与使用降维之前的数据训练出的模型相比,仍然能够保持较高的性能。