乳腺癌良恶性预测--逻辑回归
一、问题背景
基于机器学习算法构建乳腺癌数据集的二分类模型以实现对乳腺癌肿瘤的良性与恶性状态进行预测
二、数据集分析
该乳腺癌数据集的获取途径为:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/。
在乳腺癌数据集中共有699个样本,并分为11个属性维度。每个样本都包含10个特征指标以及一个分类标记。
其中包含16个缺失记录,并用问号予以标识。
| 属性 | 含义 |
|---|---|
| Sample code number | 索引ID |
| 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为恶性 |
该数据集的具体信息可通过以下链接获取:https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data
打开breast-cancer-wisconsin.data,数据格式如下:

三、代码实现
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression,SGDClassifier
from sklearn.model_selection import train_test_split,KFold,cross_val_score
from sklearn.metrics import classification_report,accuracy_score,confusion_matrix
from sklearn.tree import DecisionTreeClassifier
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
warnings.filterwarnings('ignore')
pd.options.display.max_rows = None
pd.options.display.max_columns = None
# 设置字段名,原始数据重没有每一维数据代表的含义
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','mitnoses','class']
data = pd.read_csv(r"C:\Users\bo.chen\Desktop\breast-cancer-wisconsin.data",header=None,names=column_names)
# 显示前四条记录
print(data.head(4))
# 显示数据维度
print(data.shape)
# 查看数据信息
print(data.info())
# 显示数据统计描述
print(data.describe())
# 显示数据分布情况
print(data.groupby('class').size())
# 缺失值处理,在bare nuclei列中有缺失值,以?表示的
'''
mean_value = data[data["bare nuclei"]!="?"]["bare nuclei"].astype(np.int).mean()# 计算异常值列的平均值
data = data.replace('?',mean_value)
data["bare nuclei"] = data["bare nuclei"].astype(np.int64)
'''
data = data.replace(to_replace='?',value=np.nan) #非法字符的替代
data = data.dropna(how='any')
# print(data.head(25))
# 拆分数据集
#将样本按照3:1划分训练集和测试集,参数解释:
# train_data:所要划分的样本特征集 1~9为特征值
# train_target:所要划分的样本结果 10表示label
# test_size:样本占比,如果是整数的话就是样本的数量
# random_state:是随机数的种子。
X_train,X_test,y_train,y_test = train_test_split(data[column_names[1:10]],\
data[column_names[10]],\
test_size=0.25,\
random_state=5)
# 查看训练样本的数量和类别分布
print(y_train.value_counts())
print(y_test.value_counts())
#标准化数据,保证每一个维度的特征数据方差为1,均值为0.使得预测结果不会被某些维度过大的特征值所主导
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)
'''
preprocessing.StandardScaler中fit、fit_transform、transform的区别
1、fit
用于计算训练数据的均值和方差, 后面就会用均值和方差来转换训练数据
2、fit_transform
不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转换成标准的正太分布
3、transform
很显然,它只是进行转换,只是把训练数据转换成标准的正态分布
一般使用方法:
a) 先用fit
scaler = preprocessing.StandardScaler().fit(X)
这一步可以得到scaler,scaler里面存的有计算出来的均值和方差
b) 再用transform
scaler.transform(X)
这一步再用scaler中的均值和方差来转换X,使X标准化
c) 那么在预测的时候, 也要对数据做同样的标准化处理,即也要用上面的scaler中的均值和方差来对预测时候的特征进行标准化
注意:测试数据和预测数据的标准化的方式要和训练数据标准化的方式一样, 必须用同一个scaler来进行transform
'''
# 模型一:线性分类模型逻辑回归
# LR = LogisticRegression()
LR = LogisticRegression(C=1.0,penalty='l2',tol=0.1)
# c:正则化系数λ的倒数,float类型,默认为1.0。必须是正浮点型数。像SVM一样,越小的数值表示越强的正则化。
# penalty:惩罚项,str类型,可选参数为l1和l2,默认为l2。用于指定惩罚项中使用的规范。newton-cg、sag和lbfgs求解算法只支持L2规范。L1G规范假设的是模型的参数满足拉普拉斯分布,L2假设的模型参数满足高斯分布,所谓的范式就是加上对参数的约束,使得模型更不会过拟合(overfit),但是如果要说是不是加了约束就会好,这个没有人能回答,只能说,加约束的情况下,理论上应该可以获得泛化能力更强的结果。
# tol:停止求解的标准,float类型,默认为1e-4。就是求解到多少的时候,停止,认为已经求出最优解。
LR.fit(X_train,y_train)
LR_y_predict = LR.predict(X_test)
#使用线性分类模型中的classification_report模块对肿瘤预测模型的性能进行分析
print('预测结果为:{}'.format(LR.score(X_test,y_test)))
print('预测结果为:{}'.format(accuracy_score(y_test,LR_y_predict)))
#利用classification_report模块获得LR的其他三个指标(pression,recall,f1 score)
#print(classification_report(y_test,LR_y_predict,target_names=['Bebign','Malignat']))
print(classification_report(y_test,LR_y_predict,target_names=['良性','恶性']))
# 模型二:线性分类模型SGD
SGDC = SGDClassifier()
SGDC.fit(X_train,y_train)
SGDC_y_predict = SGDC.predict(X_test)
print('Accuracy Of SGD:',SGDC.score(X_test,y_test))
print(classification_report(y_test,SGDC_y_predict,target_names=['Bebign','Malignat']))
# 多种模型比较
models = {}
models['LR'] = LogisticRegression()
models['LDA'] = LinearDiscriminantAnalysis()
models['KNN'] = KNeighborsClassifier()
models['CART'] = DecisionTreeClassifier()
models['NB'] = GaussianNB()
models['SVM'] = SVC()
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
# 评估算法
results = []
for name in models:
result = cross_val_score(models[name], X_train, y_train, cv=kfold, scoring='accuracy')
results.append(result)
msg = '%s: %.3f (%.3f)' % (name, result.mean(), result.std())
print(msg)
# 图表显示
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(models.keys())
plt.show()
AI助手
1、整个算法的过程符合机器学习的一般流程,包括:
确定目标:在应用机器学习时首先要明确目标是什么。运用机器学习技术解决实际问题的过程中, 明确目标任务是选择合适算法的基础, 是选择合适算法的关键因素。当前任务属于监督学习范畴内的定性分析类型, 主要采用分类算法进行求解。对于定量分析的情况, 则可考虑使用回归方法。
获取数据:本任务的数据集源自威斯康辛乳腺癌数据库,并通过网络途径获取;文件中附带提供下载链接。
③整理预处理:在获取数据之后,无需立即着手模型构建,应在获取完全部原始数据之后,对之进行全面分析和研究,以进一步掌握其内在特征.完成数据分析阶段后,需执行一系列预处理工作.本任务中包含以下几个方面:一是缺失值填充与剔除工作;二是确定特征与目标变量的具体内容(其中前10项特征建议剔除编号属性);三是完成训练集与测试集的有效分割;四是实施标准化处理的技术方案.
④数据建模:每个模型都有其适用场景,在面对特定问题时无法保证对所有情况都表现最佳,这被称为“无免费午餐定理”。在实际应用中,通常会采用多种训练策略进行模型训练,并通过多维度评估指标比较它们的性能表现,最终选出性能最优的那个模型。
⑤模型训练 :在模型训练的过程中,需要对模型超参进行优化;如果缺乏深入的理解,则难以迅速找到决定模型性能的关键参数。
模型评估:基于训练数据构建完成后,需运用测试数据对模型进行检验,以检验其对新输入数据的泛化能力.在实际应用中,过拟合与欠拟合的判断通常是进行模型诊断的重要环节.常用的检测手段包括交叉验证和学习曲线分析.对于过拟合问题,可以通过增加数据量来改善其表现,同时提升模型的简单性.而针对欠拟合现象,可以通过增加和优化特征来缓解该问题,并提升其复杂度.
在工程实践中具有重要价值的是模型应用这一环节与算法开发之间的紧密关联。从工程实践的角度来看是以结果为导向的,在实际应用中只有确保线上运行效果才能够保证模型的质量。值得注意的是这不仅需要考虑其准确性以及误差范围还需综合评估多个关键指标包括但不限于以下几点:一是运行效率(时间复杂度)二是资源消耗情况(空间复杂度)三是系统的稳定性是否达标等多维度因素共同作用才能全面评估一个模型的价值与可行性。
2、关键函数
KFold()函数归类于sklearn中的model_selection模块。该算法的初始化参数包括:n_splits(用于将数据划分为指定数量的块)、shuffle(表示是否随机打乱划分,默认情况下不打乱)以及random_state(用于固定随机起点,在shuffling被启用时会被使用)。其中n_splits必须大于等于2。
cross_val_score()函数:交叉验证方法用于评估机器学习模型的预测能力尤其适用于检验经过训练后的模型对新数据的泛化能力通过交叉验证可以在一定程度上减小过拟合的风险同时还能在有限的数据资源下尽可能多地提取有效信息其调用格式为cross_val_score(estimator, X, y=None, scoring=None,cv=None,n_jobs=1,verbose=0,fit_params=None,pre_dispatch='2*n_jobs')其中estimator表示待评估的估计器如分类器X代表输入特征数据y表示目标标签scoring指定评估指标如accuracy或mean_squared_errorcv定义交叉验证的方式n_jobs指明并行计算的工作单元数量(-1表示使用全部可用处理器)verbose控制输出信息量的大小fit_params允许传递给估计器的参数值pre_dispatch规定任务分配到各处理器的数量以平衡内存使用
四、算法分析
1、定义
逻辑回归(Logistic Regression)是一种预测模型,揭示因变量与其一个或多个自变量之间的关系。其主要区别在于目标变量具有多个类别属性,在这种情况下它常被用来解决分类问题。虽然被称为回归分析,但其本质是在一个线性模型基础上引入了映射函数Sigmoid(σ函数),将连续输出值转换为离散类别。这种方法特别适用于二分类场景,在面对多分类问题时则扩展为Softmax函数形式。
2、逻辑回归算法优缺点
优点:该方法具有以下特点:其一是代码规模较小;其二是具有较高的可解释性;其三是控制能力较强;其四是训练速度较快;其五是计算成本较低;其六是所需的存储资源有限
缺点:该方法可能存在以下不足:容易出现欠拟合问题;分类精度可能会相对较低
适用数据类型
3、分类函数
在二分类问题中常用Sigmoid函数作为判别函数。其公式形式为:sigmoid = \frac{1}{1+e^{-x}}其中自变量可取所有实数值输出范围限定在0到1之间。如图所示

该函数具有S型曲线特征,并且其取值范围限定在[0,1]之间。当输入远离零时,该函数的输出迅速趋近于零或一。这一特性对于二分类问题具有重要意义。
该算法的假设函数形式为:
h_\theta(x) = g(\theta^Tx), \quad g(z) = \frac{1}{1 + e^{-z}}
从而得出:
h_\theta(x) = \frac{1}{1 + e^{-\theta^Tx}}
其中x为输入样本特征向量,\theta为待估计参数向量(即权重系数)。
假设逻辑回归模型中的概率P(y=1|x;\theta)被定义为g(\theta^Tx)的形式,并进一步表示为\frac{1}{1+e^{-\theta^Tx}}。这一假设表示,在给定输入x和参数θ的情况下(即给定输入样本及其相关的参数),该模型预测其属于类别y=1的概率值。这种形式的选择不仅简化了后续的计算过程,并且保证了其良好的数学性质(如S型曲线)。逻辑回归的学习目标就是通过最小化数据集上的损失函数来优化参数θ的取值。
通过经典的梯度下降算法反复计算参数更新方向,模型参数θ将趋近于其最优解;从而使得模型的损失达到最小值。
在对逻辑回归算法的效果进行评估时, 通常使用AUC值作为量化标准.
