Keras Извлечение информативных признаков в тексте с использованием весов - PullRequest
0 голосов
/ 24 мая 2019

Я работаю над проектом классификации текста, и я хотел бы использовать keras для ранжирования важности каждого слова (токена).Моя интуиция заключается в том, что я должен иметь возможность сортировать веса из модели Keras для ранжирования слов.

Возможно, у меня возникла простая проблема с использованием argsort или tf.math.top_k.

Полнаякод от Packt

Я начинаю с использования sklearn для вычисления TF-IDF с использованием 10 000 наиболее часто встречающихся слов.

vectorizer = TfidfVectorizer(min_df=2, ngram_range=(1, 2), stop_words='english',
                             max_features=10000, strip_accents='unicode', norm='l2')

x_train_2 = vectorizer.fit_transform(x_train_preprocessed).todense()
x_test_2 = vectorizer.transform(x_test_preprocessed).todense()

Я могу просмотреть списокслова вроде этого:

print(vectorizer.get_feature_names()[:10])

Затем я строю и подгоняю модель, используя Keras.Керас использует бэкэнд тензорного потока.

# Deep Learning modules
import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import Adadelta, Adam, RMSprop
from keras.utils import np_utils

# Definiting hyper parameters
np.random.seed(1337)
nb_classes = 20
batch_size = 64
nb_epochs = 20

Y_train = np_utils.to_categorical(y_train, nb_classes)
model = Sequential()

model.add(Dense(1000, input_shape=(10000,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))

model.add(Dense(500))
model.add(Activation('relu'))
model.add(Dropout(0.5))

model.add(Dense(50))
model.add(Activation('relu'))
model.add(Dropout(0.5))

model.add(Dense(nb_classes))
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam')

print(model.summary())

# Model Training
model.fit(x_train_2, Y_train, batch_size=batch_size, epochs=nb_epochs, verbose=1)

После этого я могу получить веса, такие как:

weight = model.weights[0]
# Returns <tf.Variable 'dense_1/kernel:0' shape=(10000, 1000) dtype=float32_ref>

Поскольку число строк (10 000) равно количеству объектов, я думаю, что я на правильном пути,Мне нужно получить список индексов, которые я могу использовать для получения имен функций: informative_features = vectorizer.get_feature_names()[sorted_indices].

Я пытался создать список, используя два различных метода:

  1. tf.nn.top_k

    sorted_indices = tf.nn.top_k(weight)
    # Returns TopKV2(values=<tf.Tensor 'TopKV2_2:0' shape=(10000, 1) dtype=float32>, indices=<tf.Tensor 'TopKV2_2:1' shape=(10000, 1) dtype=int32>)
    

    Я не определил, как получить список из этого результата.

  2. argsort

    sorted_indices = model.get_weights()[0].argsort(axis=0)
    print(sorted_indices.shape)
    # Returns (10000, 1000)
    

    Функцияargsort возвращает матрицу, но мне нужен одномерный список.

Как использовать весовые коэффициенты для ранжирования текстовых объектов?

1 Ответ

1 голос
/ 24 мая 2019

я думаю, что это не возможно, что первый слой выводит значение 1000, каждое значение, связанное с каждым признаком с некоторым значением веса, и то же самое продолжается до конца сети

, если вводить непосредственно связанный слой классификации и если он обучен, то

tfidf =  Input(shape=(10000,))
output = Dense(nb_classes, activation='softmax')(tfidf)
model = Model(tfidf,output)
model.summary()

# train model ...

last_layer = model.layers[-1]
weights = last_layer.get_weights()[0]
for i in range(nb_classes):
    print('class : ',i,' ->  Feature : ',np.argmax(weights[:,i]) )
...