乳腺癌分类器及数据样本验证

By Toby

QQ:231469242

欢迎爱好者交流,并改进代码

数据下载地址 uci machine learing/breast cancer

词汇:

Malignancy 恶性

biopsy 活组织检查

benign 良性的

diagnosis 诊断

periodic examination定期检查

Clump Thickness    肿块厚度

Uniformity of Cell Size   细胞大小的均匀性

Uniformity of Cell Shape 细胞形状的均匀性

Marginal Adhesion   边缘粘

Single Epithelial Cell Size  单上皮细胞的大小

Bare Nuclei    裸核

Bland Chromatin  乏味染色体

Normal Nucleoli  正常核

Mitoses 有丝分裂

背景知识

isconsin Breast Cancer Database (WBCD)

January 8, 1991

Revised Nomeber 3, 1994

This is a description of the Wisconsin Breast Cancer Database, collected by Dr. William H. Wolberg, University of Wisconsin Hospitals, Madison. The actual database is contained in another file (datacum). Samples were collected periodically as Dr. Wolberg reported his clinical cases. The database therefore reflects this chronological grouping of the data. The samples consist of visually assessed nuclear features of fine needle aspirates (FNAs) taken from patients‘ breasts. Each sample has been assigned a 9-dimensional vector (attributes 3 to 9 below) by Dr. Wolberg. Each component is in the interval 1 to 10, with value 1 corresponding to a normal state and 10 to a most abnormal state. Attribute 1 is sample number, while attribute 2 designates whether the sample is benign or malignant. Malignancy 恶性is determined by taking a sample tissue from the patient‘s breast and performing a biopsy on it. A benign 良性的diagnosis 诊断is confirmed either by biopsy 活组织检查

or by periodic examination定期检查, depending on the patient‘s choice.

All groups are in the same file.  We have separated the groups

感谢

Wisconsin医学院的william H.Wolberg博士提供乳腺癌数据样本。所欲数据来自真实临床案例,每个案例有9个属性

这就是判断乳腺癌的9个属性(翻译非全部准确)

Field         Attribute

1             Sample code number   (病人ID)

2             Class: 2 for benign, 4 formalignant(恶性或良性分类)

3             Clump Thickness    肿块厚度

4             Uniformity of Cell Size   细胞大小的均匀性

5             Uniformity of Cell Shape 细胞形状的均匀性

6             Marginal Adhesion   边缘粘

7             Single Epithelial Cell Size  单上皮细胞的大小

8             Bare Nuclei    裸核

9             Bland Chromatin  乏味染色体

10             Normal Nucleoli  正常核

11             Mitoses 有丝分裂

数据样本示例说明:

病人ID    恶性或良性(2是良性,4是恶性)    剩下的是9个属性(field3-11),每个属性用数字表示

1000025,                     2,                                    5,1,1,1,2,1,3,1,1

NOTE:   16points with missing attributes (indicated by a 0)   有16个遗失的属性,会造成统计不准确,用0表示

classifier分类器

分类器是一种计算机程序。

他的设计目标是在通过学习后,可自动将数据分到已知类别。

应用在搜索引擎以及各种检索程序中。同时也大量应于数据分析与预测领域。

分类器是一种机器学习程序,因此归为人工智能的范畴中。人工智能的多个领域,包括数据挖掘,专家系统,模式识别都用到此类程序。

对于分类器,其实质为数学模型。针对模型的不同,目前有多种分支,包括:Bayes分类器,BP神经网络分类器,决策树算法,SVM(支持向量机)算法等。

参考数据挖掘的各类文章,其中会对各种分类器算法的设计,性能,做出更为详细与准确的评价

回到正题,每个患者有11个值,患者ID,9个肿瘤的属性值和最终诊断。通过研究这些属性,找到肿瘤预测模式,根据肿瘤属性来判定肿瘤性质。对没见过面的患者(甚至不知道她的诊断结论),我们希望根据肿瘤的属性来判定是否为恶性肿瘤。为了实现,就要用分类器。分类器要使用已知类别样本进行训练。在训练过程中,分类器寻找指示分类(例如恶性或良性模式)。模式确定后,在已知的新样本数据上进行测试。在已知类别的样本上进行测试可以判定分类器准确性。

在此例中,诊断结果(良性或恶性)是对患者肿瘤属性的分类结果。每个患者信息都可以用于建立一个模式的内部模型,模式用于区分良性或恶性。训练好分类器后,必须要测试分类器效果。将数据分成两个部分,即分类器训练数据和测试数据。在实践中,创建两个单独的文件,大部分数据放入训练文件,剩余数据放入测试文件。

现在要解决问题是:如何编写从训练数据中发现分类模式的程序?

利用分治原理,每次查看患者的一个肿瘤属性,然后结合所属的类别意见作出决定。例如一个肿瘤厚度值范围1-10。较厚的肿瘤(例如大于7),可预测为恶性肿瘤,最后评估每个属性,得出判定结果,分类结果遵循遵循少数服从多数原理。

举例(1000025 , 5,1,1,1,2,1,3,1,1) ,ID为1000025 的患者,先依次判定患者9个属性,分别为5,1,1,1,2,1,3,1,1 。总结患者9个属性,其中大部分都小于中值5,最后得出患者为良性肿瘤。

如何实现?对每个肿瘤属性设置两个平均值。第一个平均值是女性训练数据中,良性肿瘤患者平均值;第二个平均值是训练数据中,恶性肿瘤患者平均值。9个属性都训练后,应该得到18个平均值,即9个良性肿瘤平均值和9个恶性肿瘤平均值。

采用如下方法构造分类器:对每个属性的平均值,找出良性平均值和恶性平均值的中值。这个值就是分类值。分类器包括所有属性的分类值,即9个分类值。如果新样本的某个属性值低于该属性的分类值,预测为良性;反正为恶性。要得到整体的分类预测结果,需要将每个属性与该属性的分类值进行比较。根据属性值是大于或小于分类值对属性进行标记。在这例子中,小于分类值表示良性,大于分类值表示恶性。对于患者最后诊断,采用少数服从多数原则。9个属性中,占主导地位的类别即为患者的最终判定结果。

算法:

变量多用复制粘贴,否则大小写很容易出错,不容易检查

将全部699个例患者数据分成两个文件,训练分类器文件和测试分类器文件。采用简单方法,349个患者数据用作训练数据,350个患者数据用作测试数据。 0代表缺失的统计数据,应该忽略含0的病人

(1)从训练文件中创建训练集trainingSet

*打开文件

*初始化训练集为空

*对文件中每一行:将行内容解析成各组成部分

为患者创建元组

将元组添加到训练集列表中

(2)创建分类器classifier,使用训练集中确定每个属性的分类值

*函数参数是训练集。

*对每个训练集中的患者元组:

如果元组代表良性肿瘤,则将每个患者属性添加到良性属性总和中,对良性肿瘤患者计数

如果元组代表恶性肿瘤,则添加到恶性肿瘤属性总和中,对恶性肿瘤患者计数

最后,得到18个总和,分别为每种良性肿瘤患者属性和恶性肿瘤患者属性的总和。同时得到良性患者和恶性患者数量。

*计算9个良性属性和9个恶性属性的平均值(总和/总人数)

*计算9个属性的良性平均值和恶性平均值的平均值。这个中值为分类值,是该属性属于良性还是恶性的诊断标准。这9个分类值构成分类器。

*trainClassifier要保存很多个人的总和和平均值。18个总和的平均值包含了很多变量,因此可用列表来进行管理。例如benignSums,benignAverage等列表。使用列表代替单个列表,需要编写代码来添加两个列表。因此需要多次求总和,所以利用函数完成此任务更容易,此外还需要总和列表计算平均值列表。由于需要多次计算平均值,因此将这部分分离出来用函数方式实现更好。两个函数分别为sumList和makeAverages.

sumList函数有两个参数,参数是两个同样大小的列表。函数返回一个新列表,该列表包含两个参数列表中元素的总和,也就是说第一个参数列表中的第一个元素和第二个参数列表的第一个元素相加,并将和作为求和列表中的第一个元素,以此类推。

创建listOfSums用于存放总和。使用乘法运算符创建列表,初始化为9个0,对列表而言,乘法是重复运算。创建变量index,在三个列表中用作索引。使用索引遍历参数列表,将相同索引的两个元素相加,结果放入listOfSums 中。

makeAverages和sumLists函数差别不大,参数为列表和总和值,将列表中的每个元素除以总和,并将计算结果作为列表返回。

(3)从测试文件中创建测试集 classifyTestSet

判断定分类器能否只根据患者的肿瘤属性,正确预测出诊断结果。这项测试由classifyTestSet 函数完成。该函数读入测试数据集(带有确诊断结果的患者肿瘤数据)。将患者的每个属性值与相应分类器值进行比较。如果该属性值大于分类器平均值,则认为该属性是恶性的证据。如果属性值小于分类器平均值,表明是良性。对每个患者的良性和恶性属性进行计数,然后采用少数服从多数规则。也就是说那种类型属性多,则预测为该类型。

(4)使用分类器(分类值),对测试集进行分类,同时计算这些判定的准确性

(5)数据结构:

(a)trainingSet 和testSet:包含每个患者的信息。患者数据是永远不会修改的,因此可以作为元组的值。所有患者数据构成元组列表。元组格式:第一项:患者ID,字符串类型;第二项:患者诊断结果,但字母字符串(单个字母‘m’,‘b’);第三至十二项:肿瘤属性,按1-9顺序排列,整数类型。

(b)classifier:由9个不同值构成序列,因为这些值是不会改变的,所以构成元组,它包含9个浮点值,即每个良性平均值和恶性平均值的中值(两个平均值的中点)

(c)result:为元组列表

#生成训练数据集

def makeTrainingSet(fileName):

tSet=[]

trainingFile=open(fileName)

for line in trainingFile:

line=line.strip()

if ‘0‘ in line:   #0代表缺失的统计数据,应该忽略含0的病人

continue

id,diag,a1,a2,a3,a4,a5,a6,a7,a8,a9=line.split(‘,‘)

if diag==‘4‘: #diagnosis is malignant

diagMorB=‘m‘

else:

diagMorB=‘b‘

patientTuple=(id,diagMorB,int(a1),int(a2),int(a3),int(a4),int(a5),int(a6),\

int(a7),int(8),int(a9))

tSet.append(patientTuple)

return tSet

#求总和函数

def sumLists(list1,list2):

‘‘‘element-by-element sums of lists of 9 items‘‘‘

listOfSums=[0.0]*9    #注意0.0表示浮点数,否则python 2.7计算会出错

for index in range(9):

listOfSums[index]=list1[index]+list2[index]

return listOfSums

#求平均数

def makeAverages(listOfSums,total):

‘‘‘convert each list element into an average by dividing by the total‘‘‘

averageList=[0.0]*9

for index in range(9):

averageList[index]=listOfSums[index]/float(total)

return averageList

#用训练数据计算分类器

def trainClassifier(trainingSet):

‘‘‘build a classifier using the training set‘‘‘

benignSums=[0]*9 #lists of sums of benign attributes

benignCount=0  #count of benign patients

malignantSums=[0]*9#lists of sums of malignant attributes

malignantCount=0#count of malignant patients

for patientTup in trainingSet:

if patientTup[1]==‘b‘: #if benign

#add benign attributes to benign total

benignSums=sumLists(benignSums,patientTup[2:])

benignCount+=1

else:

#add malignant attributes to malignant total

malignantSums=sumLists(malignantSums,patientTup[2:])

malignantCount+=1

benignAvgs=makeAverages(benignSums,benignCount)

malignantAvgs=makeAverages(malignantSums,malignantCount)

classifier=makeAverages(sumLists(benignAvgs,malignantAvgs),2)

return classifier

#分类器测试集

def classifyTestSet(testSet,classifier):

results=[]

#for each patient

for patient in testSet:

benignCount=0

malignantCount=0

#for each attribute of the patient

for index in range(9):

#if actual patient attribute is greater than separator value

#note:the patient tuple has two extra element at the beginning

#so we add 2 to each patient index to only index attributes

if patient[index+2]>classifier[index]:

#predict malignant for that attribute

malignantCount+=1

else:

#predict benign for that attribute

benignCount+=1

#record patient id,both counts,and actual diganosis

resultTuple=(patient[0],benignCount,malignantCount,patient[1])

#add patient to list of result

results.append(resultTuple)

return results

#生成测试数据的报告,统计精确度

def reportResults(results):

‘‘‘determine accuracy of classifier and report‘‘‘

totalCount=0    #count of total number of results

inaccurateCount=0#count of incorrect results

inaccuracy_list=[]#存储不正确统计的ID号

for r in results:

totalCount+=1

#if benignCount>malignantCount,we should predict‘b‘

if r[1]>r[2]:

if r[3]==‘m‘: # this is the condition of inaccuracy

inaccurateCount+=1 #if malignantCount>benignCount,we should predict ‘m‘

inaccuracy_list.append(r[0])

if r[1]<r[2]:

if r[3]==‘b‘:

inaccurateCount+=1

inaccuracy_list.append(r[0])

print "of",totalCount,"patients,there were",inaccurateCount,‘inaccuracies‘

print "the inaccurate ID are:",inaccuracy_list   #输出不准确的ID数据

#主函数

fileName=‘trainClassifierData.txt‘

trainingSet=makeTrainingSet(fileName)

classifier=trainClassifier(trainingSet)

fileName1=‘testClassifierData.txt‘

testSet=makeTrainingSet(fileName1)

results=classifyTestSet(testSet,classifier)

reportResults(results)

时间: 2024-11-05 17:39:34

乳腺癌分类器及数据样本验证的相关文章

spring+xml集成测试(准备数据和验证项的外部文件化)

Spring的集成测试 单位测试和集成测试,我想大家都做过,一般情况下,一般逻辑且不需要操作数据库的情况比较适合于单位测试了.而对于一个数据库应用来说,集成测试可能比单元测试更重要,你可以想象,一个互联网应用,不是增修数据,就是查询数据了,那么验证操作在数据记录上的影响就更为需要.如果在的应用中使用了spring,那么就可以利用spring集成测试框架了,其实它所做的工作就是加载配置文件并配置其中相关的信息,其中也包括数据源等,其次在验证完成之后,回滚对数据表的操纵,当然你也可以手动的设置为不回

模型、数据、验证相关点

1)model 模型 1 /** 2 * 模型类创建方法一 3 */ 4 // 注册一个模型类usersmodel 5 Ext.regModel('UserModel', { 6 fields : [ 7 // 定义模型类的相关字段时要注意添加类型 8 // 常用类型通常是:string,integer,boolean,float 9 { 10 name : 'name', 11 type : 'string' 12 }, { 13 name : 'age', 14 type : 'int' 1

KNN分类器(十折交叉验证)

k-近邻算法采用测量不同特征值之间的距离方法(上面写的公式)进行分类. 优点:精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 原理:1.存在一个训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系. 2.输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相思数据(最近邻)的分类标签. 3.一般的,我们只选择样本数据集中前k个最相似的数据,通常k是不大于20的整数,最后选择k个最

基于OAuth2.0协议 第三方登录与数据同步验证设计

前段时间,公司跟别的公司签订合作伙伴,搞了一个第三方登录与数据共享同步,是基于OAuth2.0协议,现在空闲了,做一下笔记. 到github下载一个OAuth2.0的PHP类库(当然,你也可以自己写一个^-^,但个人觉得没必要造轮子),有写好Mysql与Mongodb的Demo,参考一下,然后嵌套自己的业务代码,下面是客户端与服务端的交互流程: +-----------+ +-----------+| | 带client_id的URL请求获取code | || | ---------------

Python+Selenium 自动化实现实例-打开浏览器模拟进行搜索数据并验证

#导入模块 from selenium import webdriverfrom selenium.webdriver.common.keys import Keys #启动火狐浏览器driver = webdriver.Firefox() #打开urldriver.get("http://www.python.org") #添加断言assert "Python" in driver.title #开始定位elem = driver.find_element_by_

服务器端数据合法性验证:签名sign和口令token原理

有时候,你也许会想: 我写的接口,那别人要是知道url,并且知道其需要的数据结构和逻辑,那不是都可以访问了? 甚至是,客户点传递过来的数据,是不是被恶意修改了? 这时,我们可能需要"验证"一下.比如:登录验证,只有登录以后才能来到后台. 这里给出几种[验证]方式,大神勿喷: 1:sign验证法: 这种验证方式,一般过程是: 第一:给你一个[私钥][app_secret] 和[app_id] 第二:你要提交的所有数据都需要提供sign签名. 第三:sign签名的获取方式. 例如:给用户i

Django之form组件提交数据如何验证数据库中是否存在

方式一,直接判断 方式二,从源码入手 如果要验证username是否在数据库中存在,先查看源码,由于数据验证是从  obj.is_valid()方法开始验证,所以进入这个方法 依次查看 回到form类 必须要抛出ValidationError异常,导入这个异常 原文地址:https://www.cnblogs.com/zq8421/p/10439267.html

AspNetCore MVC页面数据提交验证

2019/05/14,AspNetCore 2.2.0 主要用到了jquery.validate(前端验证).数据注解(后端模型验证) 一.建立模型类User,使用数据注释 using System.ComponentModel.DataAnnotations; namespace Demo.Models { public class User { [Key] public int Id { get; set; } [Display(Name = "登录账号")] [Required(

MVC通过后台注解来添加对数据的验证。

Order.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; using System.Web.Mvc; namespace MusicStore.Models { /* 主要练习验证注解 */ /// <summary>