Keras数据集的训练和测试集的向量长度不同

时间:2018-07-14 01:32:33

标签: python list keras dataset numpy-ndarray

我正在尝试使用keras.datasets中的路透社和imdb数据集。标准呼叫是:

(x_train, y_train), (x_test, y_test) = imdb.load_data(path="imdb.npz",
                                                  num_words=None,
                                                  skip_top=0,
                                                  maxlen=None,
                                                  seed=113,
                                                  start_char=1,
                                                  oov_char=2,
                                                  index_from=3)

当我检查尺寸时,火车数据集给出(25000,10922),这很有意义。但是测试给出(25000,)。如果转储x_test[0]之类的单个测试数据集元素,它将给出一个列表,而不是numpy.array。麻烦的是,列表维的每一行都会发生变化,并且总是与火车矢量维不同。您应该如何将其用作测试数据?

1 个答案:

答案 0 :(得分:1)

好吧,正如您提到的,x_trainx_test中的每个元素都是一个列表。该列表包含句子(或段落,在此情况下为评论)的单词索引,并且由于句子可能具有不同数量的单词,因此此对应表示形式的长度也可变。让我们解码其中一个句子以查看其外观并更加熟悉数据集:

from keras.datasets import imdb

(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)

# a mapping from words to their indices, for example `human`: 403
word_index = imdb.get_word_index()

# create the reverse mapping i.e. from indices to words
rev_word_index = {idx:w for w,idx in word_index.items()}

def decode_sentence(s):
    # index 0 to 2 are reserved for things like padding, unknown word, etc.
    decoded_sent = [rev_word_index.get(idx-3, '[RES]') for idx in s]
    return ' '.join(decoded_sent)

print(decode_sentence(x_train[100]))

以可读格式输出所选评论:

  

[RES]我是David Lynch的忠实粉丝,拥有他所拥有的一切   用DVD制作,除了酒店房间,还有2小时的双峰电影,所以当   我发现了这个,我立即抓住了它,这是什么   这是一堆[RES]绘制的黑白卡通,声音很大,而且   嘴巴不舒服,也许我不知道有什么好处,但是也许这   只是一群[RES]在公众名下的废话   大卫·林奇(David Lynch)也赚了几美元,让我说清楚我没有   关心肮脏的语言部分,但必须保留[RES]声音   因为我的邻居可能全部拥有这一切   令人失望的发布,很可能只剩下[RES]   出于好奇而设置的包装盒我强烈建议您不要花钱   在这10之2

此数据的使用完全取决于您以及您要解决的问题。您可以将句子直接馈入网络,该网络可以处理长度可变的句子。通常由一维卷积层或LSTM层或两者的混合组成。另一种方法是通过将所有句子编码为固定长度编码,使所有句子具有相同的长度。这是一个示例,将所有句子一词热编码为一个0和1的向量,所有句子的长度都是固定的:

from keras.datasets import imdb
import numpy as np

# you can limit the vocabulary size by passing `num_words` argument 
# to ignore rare words and make data more manageable
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)

def encode_sentences(sentences, dim):
    encodings = np.zeros((len(sentences), dim))
    for idx, sentence in enumerate(sentences):
        encodings[idx, sentence] = 1.0
    return encodings

x_train = encode_sentences(x_train, 10000)
x_test = encode_sentences(x_test, 10000)

print(x_train.shape)
print(x_test.shape)

输出:

(25000, 10000)
(25000, 10000)

所有句子已被编码为长度为10000的向量,其中该向量的第i个元素指示相应的句子中是否存在带有索引i的单词。

另一种方法是截断或填充句子以使其长度相同。这是一个示例:

from keras.datasets import imdb
from keras import preprocessing

n_feats = 10000   # maximum number of words we want to consider in our vocabulary
max_len = 500     # maximum length of each sentence (i.e. truncate those longer
                  # than 500 words and pad those shorter than 500 words)

# you can limit the vocabulary size by passing `num_words` argument
# to ignore rare words and make it more manageable
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=n_feats)

# preprocess the sequences (i.e. truncate or pad)
x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=max_len)
x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=max_len)

print(x_train.shape)
print(x_test.shape)

输出:

(25000, 500)
(25000, 500)

现在,所有25000个句子的长度都相同,可以使用了。

我强烈建议您阅读the Keras documentation on this dataset