LINUX.ORG.RU

Сообщения Pepel

 

Вывод неправильно распознанных текстов

Форум — Development

Здравствуйте, есть нейронная сеть написанная на питоне с помощью keras. Распознает хороший отзыв или плохой(использовал датасет imdb). Проблема в том, что я не могу вывести неправильно распознанные тексты после работы сети. Пробовал написать свою функцию, но она в результате выводит всю тестовую выборку, что неверно. Возникла идея уже на обученную модель подать снова тестовую выборку для определения сентимента(в результате модель выводит значения с плавающей точкой от 0 до 1, если больше 0.5 - отзыв положительный, и отрицательный в обратном случае. После округлить эти значения и сравнить y_test(где собственно лежат 0 и 1), Но т.к модель выдает все значения в разнобой, то сравнение может быть ошибочным. Может знает кто как это реализовать? Собственно это модель:

def get_data(path):
    p = Path(path)
    train = pd.concat([pd.read_csv(f, sep='\t', index_col=0)
                       for f in p.glob('train_???.tsv*')],
                      ignore_index=True)
    test = pd.concat([pd.read_csv(f, sep='\t', index_col=0)
                      for f in p.glob('test_???.tsv*')],
                      ignore_index=True)
    return ((train['Text'], train['Sentiment']),
           (test['Text'], test['Sentiment']))

# read data
(X_train, y_train), (X_test, y_test) = get_data(r'C:\NLP1')

# build vocabulary
t = Tokenizer(num_words=10000)
t.fit_on_texts(X_train)
t.fit_on_texts(X_test)
early_stopping = EarlyStopping(monitor='val_acc', # go through epochs as long as accuracy on validation set increases
                               patience=2,
                               mode='max')




# build a model
model = Sequential()
model.add(Dense(500, activation='relu', input_dim=10000))
model.add(Dropout(0.5))
model.add(Dense(250,activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(250,activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(250,activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

optimiz = optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss = 'binary_crossentropy',optimizer = optimiz ,metrics = ['accuracy'])
X_train = t.texts_to_matrix(X_train, mode='tfidf')
X_test = t.texts_to_matrix(X_test, mode='tfidf')
hist = model.fit(X_train,y_train,validation_data = (X_test,y_test),epochs = 3,batch_size = 32,callbacks=[early_stopping])
А это функция вывода неправильный текстов.
y_pred_vect = model.predict(X_test)
# bolean mask
mask = (y_pred_vect != y_test).any(axis=1)
print(mask)
print(len(mask))
num_words=5000 # only use top 1000 words
INDEX_FROM=3   # word index offset
# этот шаг нужен чтобы получить `test_x` в изначальном виде (до токенизации):
(train_x, _), (test_x, _) = imdb.load_data(num_words=num_words, index_from=INDEX_FROM)
x_wrong = test_x[mask]

word_to_id = 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()}
all_wrong_sents = [' '.join(id_to_word[id] for id in sent) for sent in x_wrong]
print(all_wrong_sents[:10])

 ,

Pepel
()

Вывод неправильно распознанных текстов

Форум — Development

Привет всем. По сабжу: есть сеть, написанная на keras, её задача - распознать сентимент текста, а именно - хороший комментарий к фильму, или плохой(использовал дата сет imdb). Точность на выходе очевидно не 100%, значит есть тексты, которые классифицируются неверно. Офк я попробовал вывести те самые тексты, и даже есть кое-какие результаты, но тексты постоянно одни и те же, что и настораживает меня. Скорее всего я где-то ошибся, но где? Вот сам скрипt

pos_train_data = pd.read_csv('train_pos.tsv',sep = '\t')
neg_train_data = pd.read_csv('train_neg.tsv',sep = '\t')
pos_test_data = pd.read_csv('test_pos.tsv',sep = '\t')
neg_test_data = pd.read_csv('test_neg.tsv',sep = '\t')

pos_train_data = pos_train_data[['Text','Sentiment']]
neg_train_data = neg_train_data[['Text','Sentiment']]
pos_test_data = pos_test_data[['Text','Sentiment']]
neg_test_data = neg_test_data[['Text','Sentiment']]


data_train = pd.concat([pos_train_data,neg_train_data],ignore_index = True)
data_train = data_train.sample(frac=1).reset_index(drop=True)
#print(data_train.head())

data_test = pd.concat([pos_test_data,neg_test_data],ignore_index = True)
data_test = data_test.sample(frac=1).reset_index(drop=True)
#print(data_test.head())

stop_words = set(stopwords.words('english'))
table = str.maketrans('', '', punctuation)

def textclean(text):
    #tokens = word_tokenize(text)
    tokens = (text.lower()).split()
    tokens = [word for word in tokens if word.isalpha()]
    tokens = [w.translate(table) for w in tokens]
    tokens = [word for word in tokens if not word in stop_words]
    tokens = [word for word in tokens if len(word) > 1]
    return tokens


def review_to_words(text):
    clean_text = BeautifulSoup(text, "html5lib").get_text()
    clean_text = re.sub(r"[^a-zA-Z]", " ", clean_text)
    words = (clean_text.lower()).split()
    words = [w for w in words if w not in stopwords.words("english")]
    return words


reviews = []
for index,row in data_train.iterrows():
    text = (row['Text'].lower())
    reviews.append(textclean(text))
print(reviews[0])

linked_reviews = list(itertools.chain.from_iterable(reviews))
vocab_freq = dict()
#print(linked_reviews[1])

for word in linked_reviews:
    if word not in vocab_freq:
        vocab_freq[word] = 1
    else:
        vocab_freq[word] += 1
sorted_vocab_freq = list(reversed(sorted(vocab_freq.items(), key=operator.itemgetter(1))))
print(sorted_vocab_freq)
print(len(sorted_vocab_freq))


TOTAL_VOCAB = 5000

word_to_id = dict()
id_to_word = dict()
for i in range(TOTAL_VOCAB):
    word_to_id[sorted_vocab_freq[i][0]] = i
    id_to_word[i] = sorted_vocab_freq[i][0]
print(id_to_word[0])

#review_lengths
review_lengths = pd.DataFrame([len(review) for review in reviews])
review_lengths.columns = ['Len']
print(review_lengths)
#stats
print(review_lengths.describe())


def convert(l):
    new_l = []
    for word in l:
        if word in word_to_id:
            new_l.append(word_to_id[word])
    return new_l
#print(len(data_train['Sentiment']))


X_train = []
y_train = []

#Tukey's method
first_q = review_lengths.Len.quantile([0.25])[0.25]
third_q = review_lengths.Len.quantile([0.75])[0.75]

upper_threshold = third_q + 1.5*(third_q-first_q)
lower_threshold = first_q - 1.5*(third_q-first_q)

print(upper_threshold,lower_threshold)



for i in range(len(data_train)):
    converted_review = convert(reviews[i])
    if len(converted_review) <= upper_threshold:
        X_train.append(converted_review)
        y_train.append(data_train['Sentiment'][i])


X_train = np.array(X_train)
y_train = np.array(y_train)
print(X_train)
print(y_train)

X_train = sequence.pad_sequences(X_train, maxlen=int(upper_threshold),value = 0)
print(X_train.shape,y_train.shape)




data_test = pd.concat([pos_test_data,pos_test_data, neg_test_data], ignore_index=True)
data_test = data_test.sample(frac=0.3).reset_index(drop=True)
print(data_test)
print(pos_test_data)
validation_reviews = []
for index, row in data_test.iterrows():
    text = (row['Text'].lower())
    validation_reviews.append(textclean(text))

X_val = []
y_val = []
for i in range(len(data_test)):
    converted_review = convert(validation_reviews[i])
    if len(converted_review) <= upper_threshold:
        X_val.append(converted_review)
        y_val.append(data_test['Sentiment'][i])
X_val = np.array(X_val)
X_val = sequence.pad_sequences(X_val, maxlen=int(upper_threshold), value=0)
print(X_val)
y_val = np.array(y_val)
#print(X_train)
#print(y_train)




EMBEDDING_LEN = 32

model = Sequential()
model.add(Embedding(TOTAL_VOCAB,EMBEDDING_LEN,input_length = int(upper_threshold)))
model.add(Conv1D(128,3,padding = 'same'))
model.add(Conv1D(64,3,padding = 'same'))
model.add(Conv1D(32,2,padding = 'same'))
model.add(Conv1D(16,2,padding = 'same'))
model.add(Flatten())
model.add(Dropout(0.25))
model.add(Dense(100,activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(1,activation='sigmoid'))
model.summary()
opt = optimizers.Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss = 'binary_crossentropy',optimizer = opt ,metrics = ['accuracy'])
model.fit(X_train,y_train,validation_data = (X_val,y_val),epochs = 1 ,batch_size = 1000)


y_pred_vect = model.predict(X_val)
# bolean mask
mask = (y_pred_vect != y_val).any(axis=1)
print(mask)
print(len(mask))
num_words=1000 # only use top 1000 words
INDEX_FROM=3   # word index offset
# этот шаг нужен чтобы получить `test_x` в изначальном виде (до токенизации):    
(train_x, _), (test_x, _) = imdb.load_data(num_words=num_words, index_from=index_from)
x_wrong = test_x[mask]

word_to_id = 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()}
all_wrong_sents = [' '.join(id_to_word[id] for id in sent) for sent in x_wrong]
Cобственно это часть кода, отвечающая за вывод текстов.
y_pred_vect = model.predict(X_val)
# bolean mask
mask = (y_pred_vect != y_val).any(axis=1)
print(mask)
print(len(mask))
num_words=1000 # only use top 1000 words
INDEX_FROM=3   # word index offset
# этот шаг нужен чтобы получить `test_x` в изначальном виде (до токенизации):    
(train_x, _), (test_x, _) = imdb.load_data(num_words=num_words, index_from=index_from)
x_wrong = test_x[mask]

word_to_id = 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()}
all_wrong_sents = [' '.join(id_to_word[id] for id in sent) for sent in x_wrong]

 ,

Pepel
()

RSS подписка на новые темы