Я строю алгоритм анализа настроений для прогнозирования оценки IMDb. Я хотел сделать это с нуля, поэтому я собрал полмиллиона отзывов и создал свой собственный набор данных.
Я отправляю небольшие обзоры (состоящие из 50 обзоров) на review_cleaner с пулом. Это помогло мне сократить время выполнения с 40 минут до 11 минут для 1000 обзоров. Но у меня есть полмиллиона отзывов, мне нужен более быстрый способ их обработки. Я думал, возможно ли запустить его на моем графическом процессоре (GTX1060 6GB)? Я установил CUDA, но не смог найти, как запустить специфицированную c функцию (review_cleaner) на ядрах графического процессора.
По сути, мне нужно решение для ускорения предварительной обработки. Я искал и пробовал много разных вещей, но не мог этого сделать. Есть ли способ запустить его быстрее?
def filling_the_database(review_data):
try:
c.executemany("""INSERT INTO preprocessed_reviews(review, review_score) VALUES (?, ?)""", review_data)
conn.commit()
except Error as e:
print(e)
def get_wordnet_pos(word):
"""Map POS tag to first character lemmatize() accepts"""
tag = nltk.pos_tag([word])[0][1][0].upper()
tag_dict = {"J": wordnet.ADJ,
"N": wordnet.NOUN,
"V": wordnet.VERB,
"R": wordnet.ADV}
return tag_dict.get(tag, wordnet.NOUN)
def review_cleaner(review):
lemmatizer = WordNetLemmatizer()
new_review_data = ()
bulk_data = []
for each in review:
review_temp = ''.join([i for i in each[0] if not i.isdigit()])
review_temp = REPLACE_NO_SPACE.sub(" ", review_temp.lower())
review_temp = nltk.word_tokenize(review_temp)
review_temp = (lemmatizer.lemmatize(word, get_wordnet_pos(word)) for word in review_temp)
review_temp = ' '.join([word for word in review_temp if word not in stopwords.words('english')])
new_review_data = (review_temp, each[1])
bulk_data.append(new_review_data)
filling_the_database(bulk_data)
if __name__ == "__main__":
review_data = ()
bulk_data = []
amount_of_reviews = 0
previous_amount = 0
conn = create_connection('2020-04-11')
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS preprocessed_reviews(review TEXT, review_score INTEGER, ID PRIMARY KEY)""")
conn.commit()
total_number_of_reviews = c.execute("""SELECT COUNT(*) FROM movie_reviews""")
for each in total_number_of_reviews:
total_number_of_reviews = each[0]
while amount_of_reviews < total_number_of_reviews:
review_package = []
amount_of_reviews += 50
data = c.execute("""SELECT * FROM movie_reviews WHERE ID BETWEEN (?) AND (?)""", (previous_amount, amount_of_reviews-1))
conn.commit()
previous_amount = amount_of_reviews
for each in data:
review_data = (each[0], each[1])
review_package.append(review_data)
del review_data
bulk_data.append(review_package)
del review_package
print(amount_of_reviews)
p = Pool(4)
p.map(review_cleaner, bulk_data)
p.close()
print('---- %s seconds ----' % (time.time() - start_time))
Я храню около полумиллиона (400 тыс.) Обзоров в базе данных SQLite. Один столбец для обзора и один столбец для оценки обзора. В другой таблице я вставляю предварительно обработанные обзоры таким же образом, один столбец для обзора и один столбец для оценки. У меня 16 гигабайт оперативной памяти, Intel i7 6700HQ, SSD и GTX1060 6 ГБ.