Python 检测类的sigmoid输出返回不正确的性能

Python 检测类的sigmoid输出返回不正确的性能,python,machine-learning,neural-network,pylearn,Python,Machine Learning,Neural Network,Pylearn,我的问题摘要:我有一个检测(二进制分类,不平衡问题)。我用乙状结肠对样本进行分类。报告的F分数,精度和召回似乎考虑这两个类,例如真阳性似乎是正确分类的样本总数,而不是属于正确分类的“1”类的样本总数。 更详细的解释:在我的实验中,我有关于人的人口统计数据,我必须预测他们是否购买了产品。我使用PCA将初始特征减少为4个,数据存储在csv文件中(第一列有类标签“0”和“1”)。请注意,大多数人没有购买,然后这两个类是非常不平衡的。我使用CSVDataset类来读取它: dataset: &t

我的问题摘要:我有一个检测(二进制分类,不平衡问题)。我用乙状结肠对样本进行分类。报告的F分数,精度和召回似乎考虑这两个类,例如真阳性似乎是正确分类的样本总数,而不是属于正确分类的“1”类的样本总数。 更详细的解释:在我的实验中,我有关于人的人口统计数据,我必须预测他们是否购买了产品。我使用PCA将初始特征减少为4个,数据存储在csv文件中(第一列有类标签“0”和“1”)。请注意,大多数人没有购买,然后这两个类是非常不平衡的。我使用CSVDataset类来读取它:

dataset: &train !obj:pylearn2.datasets.csv_dataset.CSVDataset {
        path: 'input.csv',
        task: 'classification'
}
我想从一个简单的分类模型开始,并使用f分数作为性能度量。因此,我的第一个想法是使用带有单个sigmoid层的MLP模型(默认监视器“检测”提供召回率、精确度和f分数):

我最初的想法是将dim设置为1(决策规则是:如果输出>0.5,选择类“1”,如果<0.5,选择类“0”)。但是,我得到了错误值error:无法转换为dim 1的向量空间。预期dim=2(合并一个HOT)或2(连接一个HOT),然后我决定将dim设置为2(决策规则为:如果out1>out0选择“1”,如果out1 在我的train.yaml中,我或多或少遵循了文档中提供的softmax示例笔记本。例如,我使用BGD算法并将批大小设置为训练集中的示例总数(74164个示例,一个小数据集!),以避免手动检查性能时出现混淆

该模型是使用提供的train.py脚本进行训练的,在我查看结果之前,一切似乎都很好。如前所述,要检测的类(“1”)很少发生,这是一个检测问题。因此,我非常惊讶地看到报告的train_y_f1的高值(一个历元后,最佳结果约为94%)

为了检查这一点,我使用提供的脚本predict_csv.py手动计算了f分数,然后加载预测。我发现实际上只有未命中(所有“1”被分类为“0”),因此精度、召回率和f分数都应该为零。为什么检测监视器报告更高的值

经过一些调查,我发现MLP对每个类都有一个输出,我验证(手动计算并得到相同的数字)在get_detection_channels_from_state()中定义的真阳性和假阳性实际上指的是两个类“1”和“0”,例如,真正数是属于“1”分类为“1”的向量数与属于“0”分类为“0”的向量数之和。因此MLP将所有向量分类为“0”,并且由于几乎所有向量都属于“0”,因此性能良好。这是不平衡的已知问题ED检测问题,其中正确的分类率不是一个合适的度量,这就是为什么我们有度量F-分数或AUC的原因。然而,如果在GET*Debug SnChulnsSx从FuffStand()中考虑TP和FP,考虑这两个类,那么所报告的F分数是没有用的(至少不是对我来说)。 我可以想象这是Sigmoid类的设计者所知道的,所以我只能假设我做错了什么。希望有人能给我一个提示:)


注意:我已将此问题提交给Pyrearn2用户邮件列表。如果我得到答案,我会将其复制到这里。

Pyrearn监视器计算每个批次的f1分数,%misclass等,而不是整个历元。生成报告时,f1分数是历元中所有批次的f1分数的平均值。Repo当您查看misclass之类的数量时,对所有批次的平均值进行RTI很好:

misclass[n]是第n批的分数
杂项记录=平均值(杂项记录[0]+杂项记录[1]+…杂项记录[n])

但是,不能为f1分数构造相同的语句:
f1_epoch!=平均值(f1[0]+f1[1]+…f1[n])
其中f1[n]=2*精度[n]*召回率[n]/(精度[n]+召回率[n])

出于演示目的,请尝试将批次大小设置为数据集的大小(在mnist示例中,您可以忽略此问题)。然后f1分数将是正确的


因此,最好的建议是关注监视器中的数量,如misclass,其中批次的平均值与历元的值相同。一旦您训练了nn,您就可以对整个验证集进行预测,并在该点计算f1分数。

问题不在于性能差(这可归咎于数据集不平衡)。问题是Pylearn2报告的结果(检测监视器通道的值)不是人们对二元分类问题的期望。例如,报告的F分数似乎不正确,它似乎是每个类的F分数的平均值,这对我来说没有意义。再次阅读你的答案,我发现我理解错误。如果你阅读了我的原始问题“我使用BGD算法,并将批处理大小设置为训练集中的示例总数(74164个示例,一个小数据集!),以避免手动检查性能时出现混淆。”。
model: !obj:pylearn2.models.mlp.MLP {
        layers: [
                 !obj:pylearn2.models.mlp.Sigmoid {
                     layer_name: 'y',
                     dim: 2,
                     irange: .005
                 }
                ],
        nvis: 4,
    }