Интересно Роботизируем SMM. Как научить нейросеть предсказывать успешность постов в соцсети

Takeshi

Перо Дьявола
Команда форума
PR-group
CPA & Трафик
Регистрация
23 Янв 2019
Сообщения
1,351
Баллы
0
Общие продажи
0$
Общие покупки
0$
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
У меня есть своя группа «Вконтакте», и мне стало интересно, можно ли спрогнозировать, будет публикация успешной или нет. Я решил написать программу, которая бы автоматически брала текст поста, проверяла его с помощью нейронной сети и публиковала только в том случае, если вероятность получить одобрение аудитории достаточно высока. Разрабатывать мы будем на Qt5 и используем Python и Keras для обучения нейросети.


Для начала в проекте на Qt в файле .pro подключим библиотеку network, добавив строку QT += network. Чтобы разместить пост на стене группы, выполняем код:

QString cit = "Hello!";
QUrl apiUrl;
QString str = "

Please Login or Register to view hidden text.

" + cit + "&from_group=1&access_token=abcdef&v=5.73";
apiUrl.setUrl(str);
QByteArray requestString = "";

QNetworkRequest request(apiUrl);
request.setRawHeader("Content-Type", "application/octet-stream");

QNetworkAccessManager manager_vk;
connect(&manager_vk, SIGNAL(finished(QNetworkReply)), this, SLOT(slotV(QNetworkReply)));
manager_vk.post(request, requestString);

Как видишь, мы отправляем запрос POST с адресом в переменной str. Используем метод VK API wall.post, чтобы разместить пост на стене группы. Параметр owner_id должен быть равен номеру группы, но записан со знаком минус; параметр message содержит текст поста; from_group — указатель, что пост будет размещен от имени сообщества, он равен единице; access_token — токен доступа.

Ты мог заметить, что для обработки запроса мы подключили слот slotV. Он может выглядеть так:

void MainWindow::slotV(QNetworkReply* r)
{
qDebug() << QString::fromUtf8(r->readAll());
}

В консоли ты увидишь результат запроса: ошибку, если что-то пойдет не так, или сообщение с номером опубликованного поста.

Собираем базу данных для обучения нейронной сети
Чтобы обучить нейронную сеть, нам нужна обширная база данных постов, оцененных реальными пользователями. Ты можешь взять данные из своей группы, а можешь воспользоваться данными из любой другой открытой группы. Нам нужно собрать файл с отметками о количестве лайков для каждого поста. Для этого напишем программу.

Чтобы извлечь каждый пост, отправляем запрос GET:

QString str = "

Please Login or Register to view hidden text.

" + QString::number(cnt) + "&v=5.84&access_token=abcdef";

Мы используем метод VK API wall.getById: извлекаем пост со стены группы по его номеру.

Параметр posts содержит уникальный идентификатор поста (здесь — -78329950_123), который состоит из идентификатора группы со знаком минус и порядкового номера поста, разделенных знаком _. Порядковый номер поста содержится в переменной cnt. Параметр access_token — это токен доступа к группе.

Отправим этот запрос столько раз, сколько постов нам нужно извлечь, изменяя переменную cnt в соответствии с порядковым номером поста. Получим код HTML, который будет содержать текст поста, количество лайков и другую информацию. Распарсим каждый ответ, чтобы извлечь из него текст и количество лайков. Сохраним в текстовый файл данные, которые мы получили.

номер поста #1
текст поста #1
количество лайков #1
номер поста #2
текст поста #2
количество лайков #2
...
номер поста #n
текст поста #n
количество лайков #n

Теперь, когда все посты записаны в файл, мы готовы синтезировать нейронную сеть и обучать ее.

Keras
Нам понадобится Keras — библиотека для работы с нейронными сетями.

INFO
Есть замечательная книга — «Глубокое обучение на Python» Франсуа Шолле. По ней ты можешь освоить теорию, ознакомиться с примерами решения задач от самых простых до весьма сложных, таких как сверточные сети и генерация изображений.

Для начала выполним ряд стандартных действий и установим Python:

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install python-pip python-dev python-setuptools

Затем установим пакеты научных вычислений для Python:

$ sudo apt-get install build-essential cmake git unzip pkg-config libopenblas-dev liblapack-dev
$ sudo apt-get install python-numpy python-scipy python-matplotlib python-yaml
$ sudo apt-get install libhdf5-serial-dev python-h5py

Поставим TensorFlow:

$ sudo pip install tensorflow

И саму библиотеку Keras:

$ sudo pip install keras

Можно установить Keras и из репозитория на GitHub. В этом случае ты получишь доступ к папке keras/examples с примерами сценариев.

$ git clone

Please Login or Register to view hidden text.


$ cd keras
$ sudo python setup.py install

Чтобы проверить, что все установилось, попробуй запустить сценарий Keras.

python examples/mnist_cnn.py

Для выполнения этого примера может потребоваться несколько минут.

Синтезируем и обучаем нейронную сеть
Основу своей нейронной сети я выбрал из библиотек Keras — нейронная сеть предсказывает, какой отзыв получит рецензия на фильм: положительный или отрицательный. В нашем случае сеть будет определять, получит пост лайки или нет. Начнем с подключения всех необходимых библиотек и модулей.

#! /usr/bin/env python
# -- coding: utf-8 --

from keras.preprocessing.text import Tokenizer

from keras.preprocessing import sequence
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalMaxPooling1D

import numpy as np
import pickle

Объявим два массива: string_list и mark_list. В первом будут храниться тексты постов, а во втором ноль, если у соответствующего поста не было лайков, и единица, если были. Прочитаем все посты из созданного ранее файла базы данных.

string_list = []
mark_list = []
handle = open("vkbase.txt", "r")
for i in range(20000):
s = handle.readline()
s = handle.readline()
string_list.append(s)
s = handle.readline()
l = int(s)
if l > 0:
mark_list.append(1)
else:
mark_list.append(0)

Создадим и подготовим токенайзер:

tokenizer = Tokenizer(num_words=15000)
tokenizer.fit_on_texts(string_list)

Токенайзер создает таблицу, в которой каждому слову из нашего массива постов присваивается уникальное число. Максимальное число в моем случае — 15000.

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

with open('tokenizer.pickle', 'wb') as hand:
pickle.dump(tokenizer, hand, protocol=pickle.HIGHEST_PROTOCOL)

А теперь преобразуем наш массив постов в массив чисел в соответствии с таблицей токенайзера:

sequences = tokenizer.texts_to_sequences(string_list)

Тут я бы хотел отметить, что мы прочитали не все посты из файла, а только те, которые нам понадобятся для обучения нейронной сети. Давай прочитаем оставшиеся 3000 постов, которые будут использоваться для проверки работоспособности нашей нейросети, и также преобразуем их в массивы чисел.

string_list_test = []
mark_list_test = []

for i in range(3000):
s = handle.readline()
s = handle.readline()
string_list_test.append(s)
s = handle.readline()
l = int(s)
if l > 0:
mark_list_test.append(1)
else:
mark_list_test.append(0)

sequences_test = tokenizer.texts_to_sequences(string_list_test)

Далее наши массивы надо привести к формату, удобному для понимания нейронной сетью. Это значит, что число слов в каждом посте должно быть одинаковым. Зададим его равным 400. Если в каком-нибудь посте будет меньше слов, то оставшиеся числа заполнятся нулями:

x_train = sequence.pad_sequences(sequences, maxlen=400)
x_test = sequence.pad_sequences(sequences_test, maxlen=400)

На данный момент все подготовительные мероприятия завершены, и мы можем синтезировать нейронную сеть.

print('Build model...')
model = Sequential()

# We start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(20000,
50,
input_length=400))
model.add(Dropout(0.2))

# We add a Convolution1D, which will learn filters
# word group filters of size filter_length:
model.add(Conv1D(250,
3,
padding='valid',
activation='relu',
strides=1))
# We use max pooling:
model.add(GlobalMaxPooling1D())

# We add a vanilla hidden layer:
model.add(Dense(250))
model.add(Dropout(0.2))
model.add(Activation('relu'))

# We project onto a single unit output layer, and squash it with a sigmoid:
model.add(Dense(1))
model.add(Activation('sigmoid'))

Этот код я полностью взял из примера и заменил лишь размерности данных.

Давай скомпилируем нашу нейронную сеть.

model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])

А теперь напишем код, который запустит тренировку сети и сохранит результат в файл, чтобы он не потерялся.

model.fit(x_train, mark_list, batch_size=32, epochs=15, validation_data=(x_test, mark_list_test))
model.save("vkbase.h5")

Чтобы начать обучение, нужно запустить наш скрипт на исполнение из консоли. В терминале должна появиться бегущая строка.

14784/20000 [=====================>........] - ETA: 8s - loss: 0.5232 - acc: 0.7835

Процесс может занять до десяти минут, придется подождать. У меня точность обучения составила 62%. Это говорит о том, что в данных была найдена закономерность и сеть можно использовать по назначению. Если бы результат составил 50% или меньше, это значило бы, что закономерностей не найдено и нейронная сеть просто угадывает исход с той же вероятностью.

Давай проверим, как работает наша сеть.

network = load_model("vkbase.h5")
strin = ["А ты знаешь, мне сегодня грустно. Люди разучились быть людьми, В этом мире стало слишком пусто... Слов не надо... Просто обними... Наталия Коденцова"]

#loading tokenizer
with open('tokenizer.pickle', 'rb') as handle:
tokenizer = pickle.load(handle)

seq = tokenizer.texts_to_sequences(strin)
x_seq = sequence.pad_sequences(seq, maxlen=400)

prediction = network.predict(np.array(x_seq), verbose=1)
print(prediction)

Этот скрипт показывает, с какой вероятностью данная цитата получит лайк. Им мы и будем пользоваться в дальнейшем.

Внедряем нейронную сеть на Python в проект на С++
Наша нейронная сеть обучена и готова к использованию. Теперь нам надо внедрить ее в проект на С++ на платформе Qt5, который будет постить отобранные посты в ВК.

#include "/usr/include/python2.7/Python.h"

Py_Initialize();

PyObject *moduleMainString = PyString_FromString("main");
PyObject *moduleMain = PyImport_Import(moduleMainString);

PyRun_SimpleString(
"import pickle\n"
"import numpy as np\n"
"from keras.preprocessing.text import Tokenizer\n"
"from keras.preprocessing import sequence\n"
"from keras.models import Sequential, load_model \n"
"def neuron(text): \n"
" network = load_model(\"/home/alex/Projects/vkbase/vkbase.h5\") \n"
" strin = [text]\n"
" #loading tokenizer \n"
" with open(\"/home/alex/Projects/vkbase/tokenizer.pickle\", \"rb\") as handle: \n"
" tokenizer = pickle.load(handle) \n"
" seq = tokenizer.texts_to_sequences(strin) \n"
" x_seq = sequence.pad_sequences(seq, maxlen=400) \n"
" prediction = network.predict(np.array(x_seq), verbose=1) \n"
" return prediction \n"
);

Тебе нужно только прописать свои пути к файлам vkbase.h5 и tokenizer.pickle.

Скрипт, который мы внедрили в проект, — функция под названием neuron, которая принимает параметр text и возвращает вероятность в виде числа prediction. Опишем доступ к нашей функции и аргумент, который мы будем в нее отдавать.

PyObject *func = PyObject_GetAttrString(moduleMain, "neuron");
char [] cit = "Hello!";
PyObject *args = PyTuple_Pack(1, PyString_FromString(cit));

Здесь переменная cit — это пост, который надо проверить. Теперь вызовем нашу функцию с постом в качестве аргумента и получим результат.

PyObject *result = PyObject_CallObject(func, args);
double koef = PyFloat_AsDouble(result);

Переменная koef и есть наш результат, вероятность того, что пост получит лайки. Теперь мы можем проверить его: если он больше 0.5, мы можем размещать пост в сети, если меньше — лучше взять другой.

Таким образом мы можем реализовать автопостинг: завести таймер (например, на один час), по его срабатыванию брать пост из банка постов, проверять на пригодность с помощью нейронной сети и публиковать в случае успеха.

Выводы
После внедрения описанного проекта в реальной группе ВК я увидел результат довольно скоро. Количество лайков не сильно изменилось, но количество подписчиков продолжает расти, так что этот проект оказался не только интересным, но и полезным. Надеюсь, не для меня одного.
 

SkyLooter9

Новый пользователь
Пользователь
Регистрация
23 Мар 2019
Сообщения
12
Баллы
0
Общие продажи
0$
Общие покупки
0$
Это все шняга братан. Не работает такая "нейронка"