机器学习实战一:逻辑回归实现乳腺癌肿瘤预测

一、内容

基于乳腺癌肿瘤数据使用逻辑回归分析肿瘤是良性还是恶性

二、目标

  • 熟悉逻辑回归原理
  • 掌握sklearn逻辑回归相关API

三、环境

  • 操作系统:Windows10
  • 工具软件:jupyter notebook、Python 3.6.13
  • 硬件环境:无特殊要求
  • 核心库:
    • pandas 1.1.5
    • matplotlib 3.3.4
    • numpy 1.19.5
    • scikit-learn 0.24.2

四、原理

回归,用于处理和预测连续型标签的算法。线性回归完成的是回归拟合任务,而对于分类任务,我们同样需要一条线,但不是去拟合每个数据点,而是把不同类别的样本区分开来。Logistic回归分析是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。Logistic回归在二十世纪初用于生物科学, 随后被用于许多社会科学应用中。

1. 逻辑回归

逻辑回归(Logistic Regression)是一种预测分析,解释因变量与一个或多个自变量之间的关系,与线性回归不同之处就是它的目标变量有几种类别,所以逻辑回归主要用于解决分类问题。

按照逻辑回归的基本原理,求解过程可以分为以下三步。

(1)找一个合适的预测分类函数,用来预测输入数据的分类结
果,一般表示为h函数,需要对数据有一定的了解或分析,然后确定函
数的可能形式。

(2)构造一个损失函数,该函数表示预测输出(h)与训练数据类
别(y)之间的偏差,一般是预测输出与实际类别的差,可对所有样本
的偏差求R2值等作为评价标准,记为J(θ)函数。

(3)找到J(θ)函数的最小值,因为值越小表示预测函数越准确。求解损失函数的最小值是采用梯度下降法(Gradient Descent)。
二分类问题中一般使用Sigmoid函数作为预测分类函数,其函数公式为mlch2-1 ,对应的函数图像是一条取值在0和1之间的S形曲线,如图所示:
mlch2-2
与线性回归相比,它是用概率的方式实现预测,预测出属于某一分类的概率值。如果概率值超过50%,则属于某一分类。此外,它的可解释强,可控性高,并且训练速
度快,特别是经过特征工程之后效果更好。

3. 威斯康辛乳腺癌数据集

本案例使用“良/恶性乳腺癌肿数据集”。该数据集来自南斯拉夫卢布尔雅那大学医疗中心肿瘤研究所。下载地址下载的数据为data格式,直接改名为csv查看数据内容即可。该数据集收集了699条病人样本,共11列数据。第一列为检索的患者id,后9列包括了与癌症相关的9个特征指标,分别为肿块厚度(Clump Thickness),细胞大小的均匀性(Uniformity of Cell Size),细胞形状的均匀性(Uniformity of Cell Shape),边际附着力(Marginal Adhesion),单个上皮细胞大小(Single Epithelial Cell Size),裸核(Bare Nuclei),淡色染色质(Bland Chromatin),正常核(Normal Nucleoli),核分裂(mitoses)。类别(class)代表良性/恶性肿瘤,分别以2,4代替。数据中包含16个缺失值,以"?"标出。

mlch2-3

五、步骤

打开notebook 开发环境,新建ipynb文件,命名为逻辑回归实现乳腺癌肿瘤预测.ipynb保存在当前项目根目录下的code文件夹中。

1. 导入数据

我们将预测乳腺癌肿瘤的良\恶性。

import pandas as pd

column_names = ['Sample code number','Clump Thickness','Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion','Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class']
dataFrame = pd.read_csv("../data/breast-cancer-wisconsin.data",names = column_names)
dataFrame.head()

mlch2-4

2. 数据预处理

将数据集中带"?"的数据替换成np.nan,再利用Pandas库的dropna函数便能快速地将缺失值删除。

import numpy as np
# 将?替换成标准缺失值表示
dataFrame = dataFrame.replace('?',value = np.nan)
# 丢弃带有缺失值的数据
dataFrame = dataFrame.dropna(how='any')
dataFrame.shape

3. 准备训练测试数据

分析上述数据集,第一列(Sample code number)是我们不需要的,应将其舍去;最后一列(Class)是我们的预测分类结果。利用sklearn.model_selection库中的train_test_split方法,实现训练集与测试集的划分。利用训练集训练模型,用测试集测试模型的预测结果与预测精度。

from sklearn.model_selection import train_test_split

X = dataFrame[column_names[1:10]]
y = dataFrame[column_names[10]]
    
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.25,random_state=2)

其中,各变量及参数的含义如下:

变量 含义
x_train 训练集中的文本数据
x_test 测试集中的文本数据
y_train 训练集中的数据特征对应的分类结果
y_test 测试集中的数据特征对应的分类结果
test_size 用于设定测试集占数据集的样本比例,test_size=0.25表示测试集占总数据集比例的25%
random_state 使用由给定整数作为种子的新随机数生成器。使用 int 将在不同的调用中产生相同的结果。但是,检查您的结果在许多不同的不同随机种子中是否稳定可能是值得的。流行的整数随机种子是 0 和42

4. 标准化数据

为避免异常值对模型拟合产生影响,对每个特征进行标准化。导入sklearn.preprocessing.StandardScaler,可以方便地对数据集按列进行标准化操作。标准化的公式与代码如下:

# 标准化数据,保证每个维度的特征数据方差为1,均值为0。使得预测结果不会被某些维度过大的特征值而主导
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

5. 逻辑回归模型

导入sklearn.linear_model中的Logistic Regression方法,实例化一个Logistic分类器,传入训练集供分类器学习。值得注意的是,在该案例中,我们需要关注的是查全率而非查准率(放过一个恶性癌症患者所带来的成本与风险要比误诊一个良性癌症患者所带来的成本高得多),因此我们利用sklearn.metrics中的classification_report方法,通过查看其查全率来观察该分类器的预测效果。在预测之前,我们按住ctrl+B定位到LogisticRegression的源码中,可以看到sklearn库中LogisticRegression默认设置的正则化项系数为l2(岭回归),且正则化力度为1.0。如下图所示:

以下是代码实现:

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
lr = LogisticRegression()
lr.fit(X_train, y_train)
y_predict = lr.predict(X_test)
print("预测模型的系数为:",lr.coef_)
print("测试集的预测结果为:",y_predict)
print("准确率为:",lr.score(X_test,y_test))
print("查准率与查重率:",classification_report(y_test, y_predict, labels=[2,4], target_names=["良性","恶性"],))

输出结果:

预测模型的系数为: [[ 0.51563451 -0.02337304  0.33591511  0.30823961  0.12577085  0.37531754
   0.39173273  0.19988932  0.46906672]]
测试集的预测结果为: [2 2 4 2 2 4 2 2 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2 2 2
 4 4 4 2 2 2 2 2 2 2 2 2 4 4 2 2 2 2 2 2 2 2 2 4 2 2 2 2 4 4 4]
准确率为: 1.0
查准率与查重率:               precision    recall  f1-score   support

          良性       1.00      1.00      1.00        55
          恶性       1.00      1.00      1.00        13

    accuracy                           1.00        68
   macro avg       1.00      1.00      1.00        68
weighted avg       1.00      1.00      1.00        68

从结果可以看出,模型拟合的十分完美,其中恶性肿瘤的查全率(recall)已经到了100%。

6.性能分析

lr.score(X_test,y_test)
"""
输出:
0.9473684210526315
"""

7. 十折交叉验证

score = 0
#进行十折交叉验证
kf = KFold(n_splits=10)

for train_index, test_index in kf.split(X):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    lr.fit(X_train, y_train)
    score += lr.score(X_test,y_test)
    
print("模型的平均精确率为:",score/10)

输出结果:

模型的平均精确率为: 0.9678601875532822

模型平均准确率达到96%。

六、总结

Logistic回归分析往往在预测癌症,预测广告点击率,电商购物等领域表现良好。Logistic回归与朴素贝叶斯分类器都作为有监督学习,其算法都涉及到预测概率,具有一定的相同之处,但是有如下区别:

  • Logistic回归属于判别模型,朴素贝叶斯分类器属于生成模型。
  • Logistic回归只能解决二分类问题(多分类问题需依赖softmax与神经网络),朴素贝叶斯分类器可以解决多分类问题。
  • Logistic回归具有超参数(如带有岭回归的线性模型中的正则化项系数),其模型可以通过交叉验证法不断优化,朴素贝叶斯分类器则不行。
  • Logistic回归在预测患病,广告点击等方面应用广泛,朴素贝叶斯分类器常用于于文本分类中。

七、资源下载

posted @ 2022-06-13 23:36  一归AI  阅读(2796)  评论(0编辑  收藏  举报