簡體   English   中英

Keras:如何正確地將文本轉換為數值數組以輸入順序 model:錯誤“XXX 不在索引中”

[英]Keras: How to properly convert text to numeric array for input into sequential model: error 'XXX not in index'

我有一個這樣的 DNA 序列數據框:

Feature         Label
GCTAGATGACAGT   0
TTTTAAAACAG     1
TAGCTATACT      2    
TGGGGCAAAAAAAA  0
AATGTCG         3
AATGTCG         0
AATGTCG         1

其中有一列帶有 DNA 序列,而 label 可以是 0、1、2、3(即該 DNA 序列的類別)。 我想開發一個 NN 來預測每個序列分類為 1,2 或 3 類別的概率(不是 0,我不關心 0)。 每個序列可以在數據框中出現多次,並且每個序列有可能出現在多個(或所有)類別中。 所以 output 應該是這樣的:

GCTAGATGACAGT   (0.9,0.1,0.2)
TTTTAAAACAG     (0.7,0.6,0.3)
TAGCTATACT      (0.3,0.3,0.2)    
TGGGGCAAAAAAAA  (0.1,0.5,0.6)

其中元組中的數字是在類別 1,2 和 3 中找到序列的概率。

我遇到了將文本轉換為數字數組以輸入到 keras Sequential() 的基本問題:

import numpy
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence
from sklearn.model_selection import StratifiedKFold
from keras.callbacks import EarlyStopping, ModelCheckpoint
import os
from random import random
from numpy import array
from numpy import cumsum
import pandas as pd
from keras.layers import TimeDistributed
from keras.layers import Bidirectional
from keras.preprocessing.text import Tokenizer
os.environ['KMP_DUPLICATE_LIB_OK']='True'
%matplotlib
from sklearn.feature_extraction.text import CountVectorizer


# fix random seed for reproducibility
seed = numpy.random.seed(7)
max_words = 10000

# load the data set into a data frame
df = pd.read_csv("test_dataset.csv")


# define 10-fold cross validation test harness
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
X = df.iloc[:,[0]]
y = df.iloc[:,-1]
kf = kfold.get_n_splits(X)
cvscores = []


for train, test in kfold.split(X, y):

    X_train, X_test = X[train], X[test]
    y_train, y_test = y[train], y[test]

#    sequences = tokenizer.texts_to_sequences(X_train)
#    data = sequence.pad_sequences(sequences, maxlen= 100000) 


    tokenizer = Tokenizer(num_words=max_words)
    x_train = tokenizer.sequences_to_matrix(X_train, mode='binary')
    x_test = tokenizer.sequences_to_matrix(X_test, mode='binary')

#    y_train = keras.utils.to_categorical(y_train, num_classes)
#    y_test = keras.utils.to_categorical(y_test, num_classes)


The error: KeyError: '[    0     1     3 ... 62286 62287 62288] not in index'

你可以在這里看到我嘗試了幾種方法(1)使用 tokenizer.sequences_to_matrix (你得到上面的錯誤)或(2)使用 texts_to_sequences (但你得到同樣的錯誤)

有人可以告訴我如何將每個序列轉換為適合 keras 的輸入(這是我的第一個 NN,所以一個例子會很棒)。 我計划接下來使用 go 的地方是這樣的(但這是未經測試的,因為正在努力將序列讀入 model):

  # create model
    model = Sequential()
#    model.add(Embedding(3000, 32, input_length=30))
#    model.add(Bidirectional(LSTM(20, return_sequences=True), input_shape=(n_timesteps, 1)))
    model.add(Dense(1, activation='sigmoid'))

    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

    # Monitor val accuracy and perform early stopping
#    es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=200)
#    mc = ModelCheckpoint('best_model.h5', monitor='val_accuracy', mode='max', verbose=1, save_best_only=True)

    # Fit the model
    model.fit(X_train, y_train, epochs=150, batch_size=10, verbose=0)


    # Evaluate the model
#    scores = model.evaluate(X[test], Y[test], verbose=0)
#    print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
#    cvscores.append(scores[1] * 100)
#print("%.2f%% (+/- %.2f%%)" % (numpy.mean(cvscores), numpy.std(cvscores)))

更新 1:我想知道我是否打算將序列轉換為 kfold 循環之外的矩陣,如下所示:

# define 10-fold cross validation test harness
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
X = df.iloc[:,[0]].values
y = df.iloc[:,-1].values
kf = kfold.get_n_splits(X)
cvscores = []

tokenizer = Tokenizer(num_words=1000000)
X = tokenizer.sequences_to_matrix(X, mode='binary')


for train, test in kfold.split(X, y):

    X_train, X_test = X[train], X[test]
    y_train, y_test = y[train], y[test]

    print(X_train[0:10])

但我得到了錯誤:

TypeError: '>=' not supported between instances of 'str' and 'int'

編輯 2:嘗試了此處描述的方法

kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
X = df.iloc[:,[0]].values
y = df.iloc[:,-1].values
kf = kfold.get_n_splits(X)
cvscores = []

le = LabelEncoder()
Y = le.fit_transform(y)
Y = Y.reshape(-1,1)


max_words = 1000
max_len = 150

for train, test in kfold.split(X, Y):

    X_train, X_test = X[train], X[test]
    y_train, y_test = y[train], y[test]

    tok = Tokenizer(num_words=max_words)
    tok.fit_on_texts(X_train)
    sequences = tok.texts_to_sequences(X_train)

出現錯誤:

AttributeError: 'numpy.ndarray' object has no attribute 'lower'

首先是一個小代碼示例,如何在您的情況下使用Tokenizer class:

data = ['GCTAGATGACAGT','TTTTAAAACAG','TAGCTATACT',
'TGGGGCAAAAAAAA','AATGTCG','AATGTCG','AATGTCG']
tokenizer = Tokenizer(num_words=5,char_level=True)
tokenizer.fit_on_texts(data)
data_encoded = tokenizer.texts_to_matrix(data,mode='count')
print(data_encoded)
print(tokenizer.word_index)

Output:

[[0., 4., 3., 4., 2.],
 [0., 5., 4., 1., 1.],
 [0., 3., 4., 1., 2.],
 [0., 8., 1., 4., 1.],
 [0., 2., 2., 2., 1.],
 [0., 2., 2., 2., 1.],
 [0., 2., 2., 2., 1.]]

 {'a': 1, 't': 2, 'g': 3, 'c': 4}

我希望這應該已經解決了你問題的大部分。 由於您使用 DNA 序列,因此您應該將num_words設置為有意義的值。 在您的情況下是 5,因為您有 A、C、G 和 T,並且標記器 class 將使用最常見的num_words - 1字( keras 文檔)。 此外,您應該使用char_level=True因為您操作的是字符序列而不是句子。 還有許多其他編碼序列的模式(tfidf、freq、二進制)。

將序列轉換為向量后,應該直接將數據拆分為訓練/測試集並將它們提供給 model。 我希望這能解決你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM