为什么splitWithProportion会在每次调用时更改每个集合中的金额?

时间:2014-02-03 10:28:29

标签: python python-2.7 neural-network pybrain

使用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被调用它都可以不同地对集合进行舍入,所以我猜它必须随机化序列或者其他东西 - 正如你所看到的那样我不是在调整数据。我很困惑为什么需要这样做。

1 个答案:

答案 0 :(得分:0)

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

        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()结果用于测试和训练。一切都按顺序数据集的预期工作。