用Pandas记录10次5折交叉验证的结果并求平均值写入csv文件中

本文介绍了使用MedMNIST库训练病灶区域分类模型的过程,包括图像预处理、5折交叉验证和结果平均。通过Pandas进行数据管理,详细展示了如何创建DataFrame、转置数据、计算平均值以及保存结果到CSV文件。
摘要由CSDN通过智能技术生成

Introduction

最近在训练一个病灶区域的分类模型,代码用的是MedMNIST。先是把MRI图像中的病灶区域抠出来保存成图片,然后resize到28*28的大小,再制作成.npz格式的数据集送入模型中进行训练并分类。

按照5-folds-cross-validation 的方法,把数据集分成了5个部分,因为.npz格式的特殊性,label和image必须在ndarray中的索引值一一对应上,所以在选取val-sets时只得按照步长来选取图片作为验证集,每隔10step选取一张图片。

从最终实验结果来看,波动还是挺大的,所以决定对每次的训练结果进行求平均,然而操作繁琐,毕竟要保存1056的结果并且求平均,再进行分析,所以决定直接写两个for循环嵌套,自动完成10-times-5-folds交叉验证
,并用pandas进行数据分析和保存

Pandas中两种数据类型

Pandas中分为两种数据结构,Series和DataFrame,类似于Python中的list,dict之类

  • Series 带标签的一维同构数组
  • DataFrame 带标签的,大小可变的,二维异构表格

Pandas 数据结构就像是低维数据的容器。比如,DataFrame 是 Series 的容器,Series 则是标量的容器。使用这种方式,可以在容器中以字典的形式插入或删除对象。

Series

带有轴标签的一维ndarray,可存储整数、浮点数、字符串、Python 对象等类型的数据。轴标签统称为索引,索引可以是字典中的key

import pandas as pd
s = pd.Series(['a',2,'c','www'])
In:s
Out:
0      a
1      2
2      c
3    www
dtype: object

Series中常用的两个属性:index和values,分别显示索引值和元素值

DataFrame

  • 二维的表格型数据结构。
  • 在DataFrame中行和列的表示不再是axis 0 和axis 1,而是index(行)和columns(列)

因为我在分类训练时,是用二维的嵌套字典生成了DataFrame,所以只介绍这种生成方式

import numpy as np
import pandas as pd
x = {'1': {'train_auc': 1.0, 'train_acc': 1.0, 'val_auc': 0.9987129987129987, 'val_acc': 0.98, 'test_auc': 0.9948529411764705, 'test_acc': 0.9568106312292359}, '2': {'train_auc': 1.0, 'train_acc': 1.0, 'val_auc': 0.9978549978549979, 'val_acc': 0.97, 'test_auc': 0.9434397163120568, 'test_acc': 0.7541528239202658}, '3': {'train_auc': 1.0, 'train_acc': 1.0, 'val_auc': 0.9995709995709996, 'val_acc': 0.99, 'test_auc': 0.9751622418879056, 'test_acc': 0.9501661129568106}, '4': {'train_auc': 1.0, 'train_acc': 1.0, 'val_auc': 0.9987129987129987, 'val_acc': 0.96, 'test_auc': 0.986545100469151, 'test_acc': 0.7574750830564784}, '5': {'train_auc': 1.0, 'train_acc': 1.0, 'val_auc': 0.9867009867009867, 'val_acc': 0.91, 'test_auc': 0.6762710244648318, 'test_acc': 0.6245847176079734}}
df = pd.DataFrame(x)
print(df)
-------------------------------out----------------------------------
                  1         2         3         4         5
test_acc   0.956811  0.754153  0.950166  0.757475  0.624585
test_auc   0.994853  0.943440  0.975162  0.986545  0.676271
train_acc  1.000000  1.000000  1.000000  1.000000  1.000000
train_auc  1.000000  1.000000  1.000000  1.000000  1.000000
val_acc    0.980000  0.970000  0.990000  0.960000  0.910000
val_auc    0.998713  0.997855  0.999571  0.998713  0.986701

如果把嵌套字典传给DataFrame,Pandas就会被解释为外层字典的键作为列,内层字典键则作为行索引

转置DataFrame

因为后续需要对表格中的数据求平均,而自带的方法.mean()是对列即columns中的数据进行求平均的,所以需要先对表格进行转置,将index_label和columns_label进行互换,具体做法很简单,加一个.T就ok了

df = df.T
print(df)
-------------------------------out----------------------------------
   test_acc  test_auc  train_acc  train_auc  val_acc   val_auc
1  0.956811  0.994853        1.0        1.0     0.98  0.998713
2  0.754153  0.943440        1.0        1.0     0.97  0.997855
3  0.950166  0.975162        1.0        1.0     0.99  0.999571
4  0.757475  0.986545        1.0        1.0     0.96  0.998713
5  0.624585  0.676271        1.0        1.0     0.91  0.986701

对各列中的数值进行求平均

转置之后就可以按列对数据进行求平均了,方法也很简单.mean()即可,但是需要注意的是,.mean()方法返回的数据类型是Series,不能直接添加到表格的最后一行,所以需要改变数据类型,类似于tensor和numpy互换,调用.to_frame()就行了

df.mean()
-------------------------------out----------------------------------
test_acc     0.808638
test_auc     0.915254
train_acc    1.000000
train_auc    1.000000
val_acc      0.962000
val_auc      0.996311
dtype: float64
# 输出的是Series类型的数据,所以需要先对其转换
df_mean = df.mean().to_frame()
-------------------------------out----------------------------------
                  0
test_acc   0.808638
test_auc   0.915254
train_acc  1.000000
train_auc  1.000000
val_acc    0.962000
val_auc    0.996311
# 然而这个输出还需要进行一次转置才能和df相匹配

对df和df_mean进行拼接

df_mean = df_mean.T
df = pd.concat([df,df_mean]) # 注意要先把待拼接的参数加个[]
-------------------------------out----------------------------------
   test_acc  test_auc  train_acc  train_auc  val_acc   val_auc
1  0.956811  0.994853        1.0        1.0    0.980  0.998713
2  0.754153  0.943440        1.0        1.0    0.970  0.997855
3  0.950166  0.975162        1.0        1.0    0.990  0.999571
4  0.757475  0.986545        1.0        1.0    0.960  0.998713
5  0.624585  0.676271        1.0        1.0    0.910  0.986701
0  0.808638  0.915254        1.0        1.0    0.962  0.996311

改index名并且写入csv中

rename方法可以更改index和columns的名称,且不改变数据。用法类似于更改字典中的键值

df.to_csv

  • 第一个参数是保存的文件名,没有指定路径的话,保存目录为默认目录,即os.getcwd()下的目录,可以使用绝对路径指定其保存目录和文件名
  • sep是隔开每个数据的符号,这里用的空格隔开
  • mode是写入模式,因为要持续对csv进行写操作,且不能破坏上次写入的数据,用mode=‘a’可以跟在上次写入后面继续写。default为’w’
df = df.rename(index = {0:'mean'})
df.to_csv('results.csv', sep=' ', mode='a')  # 写入csv中 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值