从Keras的imdb数据集中恢复原始文本
我想从Keras的imdb数据集中恢复imdb的原始文本。
首先,当我加载Keras的imdb数据集时,它返回了单词索引序列。
>>> (X_train, y_train), (X_test, y_test) = imdb.load_data()
>>> X_train[0]
[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 22665, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 21631, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 19193, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 10311, 8, 4, 107, 117, 5952, 15, 256, 4, 31050, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 12118, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]
我找到了imdb.get_word_index方法(),它返回单词索引字典,如{'create':984,'make':94,...}。为了转换,我创建索引词字典。
>>> word_index = imdb.get_word_index()
>>> index_word = {v:k for k,v in word_index.items()}
然后,我尝试恢复原始文本,如下所示。
>>> ' '.join(index_word.get(w) for w in X_train[5])
"the effort still been that usually makes for of finished sucking ended cbc's an because before if just though something know novel female i i slowly lot of above freshened with connect in of script their that out end his deceptively i i"
我不擅长英语,但我知道这句话很奇怪。
为什么会这样?如何恢复原始文本?
答案 0 :(得分:30)
你的例子是愚蠢的,它比一些缺失的单词更糟糕。
如果您重新阅读[start_char
]的oov_char
,index_from
和keras.datasets.imdb.load_data
参数的文档(https://keras.io/datasets/#imdb-movie-reviews-sentiment-classification
)他们解释发生了什么的方法:
start_char
:int。序列的开头将标有此字符。设置为1,因为0通常是填充字符。
oov_char
:int。由于num_words或skip_top限制而被删除的单词将被替换为此字符。
index_from
:int。使用此索引和更高的索引实际单词。
您反转的词典假设词索引从1
开始。
但索引返回我的keras有<START>
和<UNKNOWN>
作为索引1
和2
。 (并假设您将0
用于<PADDING>
)。
这对我有用:
import keras
NUM_WORDS=1000 # only use top 1000 words
INDEX_FROM=3 # word index offset
train,test = keras.datasets.imdb.load_data(num_words=NUM_WORDS, index_from=INDEX_FROM)
train_x,train_y = train
test_x,test_y = test
word_to_id = keras.datasets.imdb.get_word_index()
word_to_id = {k:(v+INDEX_FROM) for k,v in word_to_id.items()}
word_to_id["<PAD>"] = 0
word_to_id["<START>"] = 1
word_to_id["<UNK>"] = 2
id_to_word = {value:key for key,value in word_to_id.items()}
print(' '.join(id_to_word[id] for id in train_x[0] ))
缺少标点符号,但这就是全部:
"<START> this film was just brilliant casting <UNK> <UNK> story
direction <UNK> really <UNK> the part they played and you could just
imagine being there robert <UNK> is an amazing actor ..."
答案 1 :(得分:6)
您可以使用keras.utils.data_utils中的get_file删除没有停用词的原始数据集:
path = get_file('imdb_full.pkl',
origin='https://s3.amazonaws.com/text-datasets/imdb_full.pkl',
md5_hash='d091312047c43cf9e4e38fef92437263')
f = open(path, 'rb')
(training_data, training_labels), (test_data, test_labels) = pickle.load(f)
信用 - 杰里米霍华德fast.ai course lesson 5
答案 2 :(得分:1)
这是因为基本的NLP
数据准备。从文本中删除了所谓的停用词的负载,以使学习变得可行。通常 - 在预处理期间,也会从文本中删除大部分的短语和不常用的单词。我认为恢复原始文本的唯一方法是使用例如IMDB在IMDB上找到最匹配的文本。谷歌的浏览器API。
答案 3 :(得分:1)
此编码将与标签一起使用:
from keras.datasets import imdb
(x_train,y_train),(x_test,y_test) = imdb.load_data()
word_index = imdb.get_word_index() # get {word : index}
index_word = {v : k for k,v in word_index.items()} # get {index : word}
index = 1
print(" ".join([index_word[idx] for idx in x_train[index]]))
print("positve" if y_train[index]==1 else "negetive")
如果有帮助,请投票。 :)
答案 4 :(得分:0)
索引偏移3,因为0、1和2是“填充”,“序列开始”和“未知”的保留索引。以下应该起作用。
imdb = tf.keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
review = [reverse_word_index.get(i-3, "?") for i in train_data[0]]
答案 5 :(得分:0)
这对我有用:
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, "") for i in train_data[0]])
答案 6 :(得分:0)
要获得所有评论的等效数组:
def decode_imdb_reviews(text_data):
result = [0 for x in range(len(text_data))]
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
for review in range(0,len(text_data)):
for index in enumerate(text_data[review]):
decoded_review = ' '.join([reverse_word_index.get(index - 3, '#') for index in text_data[review]])
result[review] = decoded_review
return result
text_data = []
text_data = decode_imdb_reviews(train_data)
答案 7 :(得分:0)
从keras.datasets导入imdb NUM_WORDS = 1000#只使用前1000个字
(x_train,y_train),(x_test,y_test)= imdb.load_data(num_words = NUM_WORDS)
word_to_id = keras.datasets.imdb.get_word_index()
id_to_word = {键的值:key,word_to_id.items()中的值}
print(''.join(x_train [0]中id的id_to_word [id]))
答案 8 :(得分:0)
尝试以下代码。该代码有效。
public class ATMModifiedReasonViewModel : INotifyPropertyChanged
{
private List<LabelFileModel> _reasonLabels;
public List<LabelFileModel> ReasonLabels { get { return _reasonLabels; } set { _reasonLabels = value; } }
public ATMModifiedReasonViewModel(){
GetReasonLabels();
}
public void GetReasonLabels()
{
LabelFileProvider lfProvider = new LabelFileProvider();
LabelFileModelFilter filter = new LabelFileModelFilter() {LabelDefinition = "ModifiedReason"};
lfProvider.GetFiltered(filter,10, getResult => GetReasonLabelsCallback(getResult));
}
private void GetReasonLabelsCallback(Func<IEnumerable<LabelFileModel>> getResult)
{
try
{
_reasonLabels = (List<LabelFileModel>) getResult();
}
catch (Exception ex)
{
Messenger.Default.Send(new UnhandledExceptionMessage(this, ex));
}
}
}