Uma das coisas incríveis sobre trabalhar com engenharia de software é o maior número de APIs de código aberto disponíveis na web para utilização. Qualquer um pode utilizar alguma ferramenta complexa que abstraia qualquer complexidade, sem um conhecimento profundo na área, e então a partir desta primeira utilização, adquirir algum conhecimento sobre esse complexo processo. Essa foi minha intenção quando passei um fim de semana explorando Keras. Keras é uma API Tensorflow de alto nível, já que não sou um cientista de dados Keras é uma ferramenta de iniciação perfeita para entender como AI / PNL, Redes Neurais e CNNs funcionam na prática.
O código completo pode ser encontrado no seguinte github repo: TicketActivityClassifier.
Esse é outro modelo de classificação de texto, usando uma classificação de rede neural fazendo coisas básicas de aprendizado de máquina como no fluxo de trabalho abaixo.
Keras
Keras é uma API de redes neurais de alto nível, de código aberto e escrita em Python. Foi desenvolvida com foco em permitir experimentações rápidas e se tornou uma das bibliotecas de IA mais populares para a construção e treinamento de modelos de aprendizado profundo.
Keras é construída em cima de outras bibliotecas de aprendizado profundo como TensorFlow, Theano e CNTK e fornece uma interface simplificada para definir e treinar redes neurais profundas. Ela suporta uma ampla gama de arquiteturas de rede, incluindo redes neurais convolucionais (CNNs), redes neurais recorrentes (RNNs) e mais.
Uma das principais características do Keras é a sua facilidade de uso e flexibilidade. Ele permite que os usuários prototipem e experimentem rapidamente com diferentes arquiteturas de rede e hiperparâmetros, e fornece uma interface simples e intuitiva para definir e treinar modelos. Ele também inclui uma variedade de modelos pré-treinados e ferramentas para preparação e aumento de dados.
Keras possui uma comunidade grande e ativa de usuários e desenvolvedores, que contribuem para seu desenvolvimento e fornecem suporte por meio de fóruns e outros recursos. Ele também suporta a integração com outras bibliotecas e ferramentas populares de IA, tornando-se uma ferramenta poderosa e versátil para pesquisa e desenvolvimento de aplicações de aprendizado profundo.
Keras Ticket Classification Model
O objetivo deste projeto é criar um modelo que seja capaz de indicar o que é a Classificação do Ingresso com base na Descrição Curta e na Categoria do Ingresso.
Obter / preparar conjunto de dados -> Word vectors e embedding layers -> Criação de modelo -> Avaliação e persistência de modelo -> Previsão do conjunto de dados
Get/Prepare dataset
Primeiro, usando Pandas lemos o arquivo de entrada CSV e o convertemos em um DataFrame Pandas .Também usando o Pandas, removemos os valores nulos que são entradas obrigatórias para o treinamento do modelo usando o método ‘dropna’.
99
100
101
102
103
104
105
|
def load_prepare_dataset(self, dataset, *args, **kwargs):
"""
loading dataset from csv and removal of null keys which are mandatory for training:
TicketShortDesc and Activity
"""
logging.info("Preparing to read csv dataset: " + str(dataset))
data = pd.read_csv(os.path.join(myapp_config.DATASETS_PATH, dataset), dtype=str)
|
Also using Pandas we remove null values which are mandatory inputs for model training using ‘dropna’ method.
106
107
108
109
110
111
|
drop_if_na = ["ShortDescription", "Activity"]
for i in range(0, len(drop_if_na)):
logging.info("Removing nulls from column " + str(drop_if_na[i]))
data.dropna(subset=[drop_if_na[i]], inplace=True)
return data
|
Word vectors and embedding layers
Precisamos representar o texto com valores numéricos porque é o que o formato de que input esperado pelos modelos de Machine Learning. Keras Tokenizer é usado para converter texto em valores inteiros. O tokenizer atribuirá um número inteiro às 10.000 (input_words) palavras usadas com mais frequência.
99
100
101
102
103
104
105
106
107
|
X_train, X_test, Y_train, Y_test, Z_train, Z_test = train_test_split(
data["ShortDescription"], data["Category"], data["Activity"], test_size=0.15 )
# define Tokenizer with Vocab Sizes
vocab_size = 10000
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer2 = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(X_train)
tokenizer2.fit_on_texts(Y_train)
|
116
117
118
119
120
|
x_train = tokenizer.texts_to_matrix(X_train, mode="tfidf")
x_test = tokenizer.texts_to_matrix(X_test, mode="tfidf")
y_train = tokenizer2.texts_to_matrix(Y_train, mode="tfidf")
y_test = tokenizer2.texts_to_matrix(Y_test, mode="tfidf")
|
I use Keras Tokenizer to convert text into integer values. Tokenizer will assign a integer to the 10000 (input_words) most frequently used words.
116
117
118
119
120
121
122
|
# Create classes file
encoder = LabelBinarizer()
encoder.fit(Z_train)
text_labels = encoder.classes_
with open(os.path.join(myapp_config.OUTPUT_PATH, "classes.txt"), "w") as f:
for item in text_labels:
f.write("%s\n" % item)
|
116
117
118
119
|
z_train = encoder.transform(Z_train)
z_test = encoder.transform(Z_test)
num_classes = len(text_labels)
logging.info("Numbers of classes found: " + str(num_classes))
|
Model creation
O modelo está usando ReLU como função de ativação no Input Layer do modelo, no Output Layer a função softmax é usada como função de ativação, Softmax estende os recursos de regressão logística para problemas de multiclasses, atribuindo probabilidades decimais para cada categoria.
O modelo tem duas entradas: Descrição e Categoria. Categorial crossentropy é a função de Loss usada para nosso problema de classificação multiclasse, que mede o desempenho do modelo de classificação. A otimização Adam é usada como Otimizador.
99
100
101
102
103
|
# Model creation and summarization
batch_size = 100
input1 = Input(shape=(vocab_size1,), name="main_input")
x1 = Dense(512, activation="relu")(input1)
x1 = Dropout(0.5)(x1)
|
99
100
101
102
103
104
105
|
input2 = Input(shape=(vocab_size2,), name="cat_input")
main_output = Dense(num_classes, activation="softmax", name="main_output")(x1)
model = Model(inputs=[input1, input2], outputs=[main_output])
model.compile(
loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]
)
model.summary()
|
Model evaluation and persistence
177
178
179
180
181
182
183
184
185
|
# Model Evaluation
history = model.fit(
[x_train, y_train],
z_train,
batch_size=batch_size,
epochs=10,
verbose=1,
validation_split=0.10,
)
|
177
178
179
180
181
182
|
score = model.evaluate(
[x_test, y_test], z_test, batch_size=batch_size, verbose=1
)
logging.info("Test accuracy:", str(score[1]))
self.accuracy = score[1]
|
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# serialize model to JSON
model_json = model.to_json()
with open(
os.path.join(
myapp_config.OUTPUT_PATH, "model_" + myapp_config.MODEL_NAME + ".json"
),
"w",
) as json_file:
json_file.write(model_json)
# creates a HDF5 file 'my_model.h5'
model.save(
os.path.join(
myapp_config.OUTPUT_PATH, "model_" + myapp_config.MODEL_NAME + ".h5"
)
)
|
177
178
179
180
181
182
183
184
185
|
# Save Tokenizer i.e. Vocabulary
with open(
os.path.join(
myapp_config.OUTPUT_PATH,
"tokenizer" + myapp_config.MODEL_NAME + ".pickle",
),
"wb",
) as handle:
pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)
|
Dataset Prediction
200
201
202
203
204
205
206
207
|
# ShortDescriptions
x_pred = self._tokenizer.texts_to_matrix(short_description, mode="tfidf")
# Categorias
y_pred = self._tokenizer.texts_to_matrix(category, mode="tfidf")
model_predictions = self._model.predict(
{"main_input": x_pred, "cat_input": y_pred}
)
|
200
201
202
|
logging.info("Running Individual Ticket Prediction")
sorting = (-model_predictions).argsort()
sorted_ = sorting[0][:5]
|
200
201
202
203
204
205
206
207
208
209
210
|
for value in sorted_:
predicted_label = self.labels[value]
# just some rounding steps
prob = (model_predictions[0][value]) * 100
prob = "%.2f" % round(prob, 2)
top5_pred_probs.append([prob, predicted_label])
output = {
"short_description": short_description[0],
"category": category[0],
"top5_pred_probs": top5_pred_probs,
}
|
200
201
202
|
with open(
os.path.join(myapp_config.OUTPUT_PATH, "activity_predict_output.json"), "w"
) as fp:
|
SYNOPSIS
Creating the Model
1
2
3
4
5
6
|
from TicketClassifierModel import TicketClassifierModel
ticket_model = TicketClassifierModel(training_dataset='TicketTrainingData.csv',
testing_dataset='TicketTestingData.csv',
recreate_model=True)
ticket_model.evaluate_model(testing_dataset=testing_dataset)
|
Making Predictions
1
2
3
4
5
6
7
|
from ActivityClassify import TicketActivityPredict
classifier = TicketActivityPredict()
# Return top 5 prediction scores
prediction = classifier.predict_text(ShortDescription='Unlock of an Active Directory Admin or Server Account account or account',
Category='Account Update Account Administration')
print(prediction)
#{'short_description': 'Unlock of an Active Directory Admin or Server Account account or account', 'category': 'Account Update Account Administration', 'top5_pred_probs': [['87.09', 'AD User Isse'], ['12.90', 'Password reset'], ['0.00', 'Application Access'], ['0.00', 'Script Execution'], ['0.00', 'DB Connection']]})
|
LINKS
For more information about Keras Text classification I recommend the following links.
- https://realpython.com/python-keras-text-classification/
- https://keras.io/examples/structured_data/structured_data_classification_from_scratch/
- Feature 1 image source: https://semiengineering.com/deep-learning-spreads/