【问题标题】:Why does splitWithProportion change the amount in each set whenever it is called?为什么 splitWithProportion 每次调用时都会更改每个集合中的数量?
【发布时间】:2014-02-03 10:28:28
【问题描述】:

使用Python 2.7.6 和Pybrain 0.3...

这是我编写的一个函数,用于创建一个数据集来训练我的神经网络。

这是一个sequential data set,我希望其中 75% 是训练数据和 25% 测试数据(我相信这是一个公认的合理划分):

from pybrain.datasets import SequentialDataSet

def create_data_sets(rows):

    ds = SequentialDataSet(13, 1)
    last_id = -1
    count = 0

    for row in rows:

        current_id = int(row[14])
        if current_id != last_id:
            count += 1
            ds.newSequence()
        last_id = current_id

        ds.appendLinked(
            [int(row[0]) / 10000.0, 
             int(row[1]) / 10000.0, 
             int(row[2]) / 20.0, 
             int(row[3]) / 9.0, 
             int(row[4]) / 9.0, 
             int(row[5]) / 6.0, 
             int(row[6]) / 6.0,
             float(row[7]), 
             float(row[8]), 
             float(row[9]), 
             float(row[10]), 
             int(row[11]) / 6.0,
             int(row[12]) / 6.0], 
             [float(row[13])])

    test_data, train_data = ds.splitWithProportion(0.25)        
    return (test_data, train_data, count)

现在我调用该函数两次,使用相同的数据(掩盖了查询,因为表名和列名有点敏感,抱歉):

import sqlite3

connection = sqlite3.connect('database.sqlite')
cursor = connection.cursor()
cursor.execute('select A,B,C,D,E,F,G,H,I,J,K,L,M,N,O from P order by O,A')
rows = cursor.fetchall()
connection.close()

test_data, train_data, count = create_data_sets(rows)   
print str(len(test_data)) + " " + str(len(train_data)) + " " + str(count)

test_data, train_data, count = create_data_sets(rows)   
print str(len(test_data)) + " " + str(len(train_data)) + " " + str(count)

查看输出我得到了这个(实际上,每次我运行它时,它都会改变):

400 1222 203
386 1236 203

这让我很困惑 - 为什么每次都以不同的方式拆分数据?

由于数据集顺序没有改变,我希望它每次调用它时都会做同样的事情。这里面是不是发生了什么神奇的事情?


更新

这是另一个更简单的例子:

from pybrain import datasets

d = datasets.SequentialDataSet(0, 1)
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.newSequence()
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.newSequence()
d.addSample([],[0])
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.newSequence()
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])
d.addSample([],[0])
d.addSample([],[1])

for _ in range(2):
    test, train = d.splitWithProportion(0.25)
    print str(len(test)) + " " + str(len(train))

我有时会得到输出

5 18
6 17

似乎每次调用splitWithProportion 时,它都会以不同的方式对集合进行舍入,所以我猜它一定是随机化序列或其他什么东西——正如你所看到的,我没有调整数据。我很困惑为什么它需要这样做。

【问题讨论】:

    标签: python python-2.7 neural-network pybrain


    【解决方案1】:

    我认为您的问题与您创建新序列的方式有关

            if current_id != last_id:
            count += 1
            ds.newSequence()
    

    我已经验证了以下每次调用都会返回一致的结果“6 18”。

    from pybrain import datasets
    
    d = datasets.SequentialDataSet(0, 1)
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.newSequence()
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.newSequence()
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.newSequence()
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    d.addSample([],[0])
    d.addSample([],[1])
    test, train = d.splitWithProportion(0.25)
    print str(len(test)) + " " + str(len(train))
    

    编辑: 使用 SequentialDataSet 要记住的是,拆分是沿着序列而不是单个样本。因此,对于 4 个序列,0.25 的分割将恰好给出 1 个用于测试的序列和 3 个用于训练的序列。如果序列的长度不同,那么您最终会得到不同的 len() 结果来进行测试和训练。对于顺序数据集,一切都按预期工作。

    【讨论】:

    • 感谢您的回答。不过,您的序列大小都相同(每个 6 个)。如果你稍微改变它们,你也会看到这种现象。我已将您的代码版本作为示例添加到我的问题中,以便您查看
    • 我已经澄清了答案,现在应该对你有意义了。
    • 谢谢 - 我知道我会得到 1 用于测试和 3 用于训练的一组 4 个序列,当然,由于四舍五入,如果该组不能被 4 整除,我希望两组中只有整数个序列,但我想问的问题,虽然很糟糕,但我猜(抱歉)是为什么拆分数据集中的序列不一致 - 请注意,我只是调用 splitWithProportion 两次完全相同的数据集,但两个结果集的大小不同。我认为那里一定有一些随机性,但我不明白为什么需要它。
    • 因为它正在拆分序列。因此,如果您有 4 个序列,则其中 3 个序列有 4 个项目,一个序列有 3 个项目。您的项目总数为 15。现在,当您以 0.25 的比例拆分时,您最终会得到 3 个用于训练的序列和 1 个用于测试的序列。随机部分进入序列,如果选择用于测试的序列是具有 3 个项目的序列,那么您最终会得到 12 个用于训练的项目和 3 个用于测试的项目。如果选择用于测试的序列是 4 个项目序列之一,您将有 11 个项目用于训练和 4 个用于测试。希望澄清。
    • 太好了,谢谢,所以你证实了我的怀疑,它是随机的。但是,我的问题是,为什么它随机选择用于测试和训练的序列?这在机器学习中很常见吗?我希望如果我希望它是随机的,我会在数据集上调用 randomize 但它只是在我调用 split 函数时为我随机化它,这就是我要问的 - 为什么它为我这样做? (我想我应该学会更清楚地问我的问题!感谢您的坚持)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2017-12-27
    • 1970-01-01
    相关资源
    最近更新 更多