Первый lemmatizer создаёт, очевидно, экземпляр класса WordNetLemmatizer
Но строкаlemmatizer = WordNetLemmatizerво-первых тут же удаляет этот экзмепляр и во-вторых помещает в переменную lemmatizer ссылку на сам класс WordNetLemmatizer.
Уверен, планировалось что-то другое. Возможно, надо убрать первую строку, а в строке lemmatizer = WordNetLemmatizer()добавить в конце круглые скобки, это, по-идее, поместит в переменную lemmatizer ссылку на экземпляр класса WordNetLemmatizer. Вероятно, именно это было целью всего этого безобразия.
Затем,words.append(word_list)делает не совсем очевидную вещь:
words = []
for i in range(3):
words_list = ['qwa', 'wow', 'meow']
words.append(words_list)
print(words)
>>> [['qwa', 'wow', 'meow'], ['qwa', 'wow', 'meow'], ['qwa', 'wow', 'meow']]
т.е. оно добавляет в список words несколько списков, которые были в words_list, но не добавляет в список слов слова из этих списков.
Возможно, тут надо было использовать метод .extend вместо .append?
words = []
for i in range(3):
words_list = ['qwa', 'wow', 'meow']
words.extend(words_list)
print(words)
>>>['qwa', 'wow', 'meow', 'qwa', 'wow', 'meow', 'qwa', 'wow', 'meow']
Во всяком случае, мне кажется, что сейчас на вход words циклаfor word in wordsпопадают не список слов, а, вероятно, список списков слов.
Поэтому при итерации по этому списку списков в word попадают не слова, как ожидается по названию и логике строки, а списки слов. Полагаю, .extend, о котором речь выше, исправит ситуацию.
import json
import pickle
import random
from codecs import StreamReaderWriter
from typing import Any, Union, List
import numpy as np
import nltk
import self as self
lemmatizer = nltk.WordNetLemmatizer()
nltk.download('punkt')
nltk.download('wordnet')
from nltk.stem import WordNetLemmatizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout
from tensorflow.keras.optimizers import SGD
import codecs
intents: Union[StreamReaderWriter, Any]
with codecs.open('intents.json', encoding='utf-8') as intents:
intents = json.load(intents)
# intents = json.loads(open('intents.json').read())
# for line in f:
# print(line)
words = []
classes = []
documents = []
ignore_letters = ['?', '!', '.', ',']
for intent in intents['intents']:
for pattern in intent['patterns']:
word_list = nltk.word_tokenize(pattern)
words.append(word_list)
documents.append((word_list, intent['tag']))
if intent['tag'] not in classes:
classes.append(intent['tag'])
lemmatizer = WordNetLemmatizer
words = [lemmatizer.lemmatize(self, word) for word in words if word not in ignore_letters]
words = sorted(set(words))
classes = sorted(set(classes))
pickle.dump(words, open('words.pkl', 'wb'))
pickle.dump(words, open('classes.pkl', 'wb'))
training = []
output_empty = [0] * len(classes)
for document in documents:
bag = []
word_patterns = document[0]
word_patterns = [lemmatizer.lemmatize(word.lower()) for word in word_patterns]
for word in words:
bag.append(1) if word in word_patterns else bag.append(0)
output_row = list(output_empty)
output_row[classes.index(document[1])] = 1
training.append([bag, output_row])
random.shuffle(training)
training = np.array(training)
train_x = list(training[:, 0])
train_y = list(training[:, 1])
model = Sequential()
model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(train_y[0]), activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0/9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
model.fit(np.aray(train_x), np.array(train_y), epochs=200, batch_size=5,verbose=1)
model.save('chatbot_model.model')
print("Done")
Elisey05, После исправления ряда очевидных ошибок и разных странных решений (типа отсутствия параметра download_dir у ntlk.download()) программа ломается на отсутствии файла intents.json... Да даже если бы он и был, все равно, надо разбираться с ntlk, но это совсем не моя область интересов.
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
words = [lemmatizer.lemmatize(word) for word in words if word not in ignore_letters]
words = sorted(set(words))