Чат-бот на Python (Deep Learning + TensorFlow). Часть III: буферизация данных

Предыдущая статья — Чат-бот на Python (Deep Learning + TensorFlow). Часть II.

Добро пожаловать в третью часть серии статей про создание чат-бота при помощи алгоритмов глубокого обучения и библиотеки TensorFlow. В прошлой статье мы говорили о структуре наших данных и создали базу данных для их хранения. Теперь мы готовы приступить к работе с ними!

На настоящий момент наш код выглядит следующим образом:

import sqlite3
import json
from datetime import datetime

timeframe = '2015-05'
sql_transaction = []

connection = sqlite3.connect('{}.db'.format(timeframe))
c = connection.cursor()

def create_table():
    c.execute("CREATE TABLE IF NOT EXISTS parent_reply(parent_id TEXT PRIMARY KEY, comment_id TEXT UNIQUE, parent TEXT, comment TEXT, subreddit TEXT, unix INT, score INT)")

if __name__ == '__main__':
    create_table()

Теперь приступим к буферизации наших данных. Мы также запустим пару счетчиков для отслеживания прогресса с течением времени:

if __name__ == '__main__':
    create_table()
    row_counter = 0
    paired_rows = 0

    with open('J:/chatdata/reddit_data/{}/RC_{}'.format(timeframe.split('-')[0],timeframe), buffering=1000) as f:
        for row in f:

Row_counter (счетчик строк) будет сообщать нам, как далеко мы продвинулись в файле, который просматриваем, а paired_rows скажет нам, сколько строк связанных данных у нас есть (то есть c комментарием и ответом, которые собственно и являются обучающими данными). Обратите внимание, что, конечно, ваш путь к фактическому файлу данных будет отличаться от нашего.

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

[machinelearning_ad_block]

Теперь нам нужно прочитать эту строку, имеющую формат json:

if __name__ == '__main__':
    create_table()
    row_counter = 0
    paired_rows = 0

    with open('J:/chatdata/reddit_data/{}/RC_{}'.format(timeframe.split('-')[0],timeframe), buffering=1000) as f:
        for row in f:
            row_counter += 1
            row = json.loads(row)
            parent_id = row['parent_id']
            body = format_data(row['body'])
            created_utc = row['created_utc']
            score = row['score']
            comment_id = row['name']
            subreddit = row['subreddit']

Обратите внимание на вызов функции format_data. Давайте создадим ее:

def format_data(data):
    data = data.replace('\n',' newlinechar ').replace('\r',' newlinechar ').replace('"',"'")
    return data

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

Мы можем считывать данные в Python-объект с помощью json.loads(), который просто принимает строку, отформатированную как объект json.

Как упоминалось ранее, изначально все комментарии не будут иметь родителя либо потому, что это комментарий верхнего уровня (а родителем является сам пост на Reddit), либо потому, что родителя нет в нашем документе.

Однако, просматривая документ, мы найдем комментарии, у которых есть родители, имеющиеся в нашей базе данных. Когда это будет происходить, мы намереваемся добавлять этот комментарий к существующему родительскому объекту.

После просмотра файла или списка файлов мы возьмем базу данных и выведем наши пары в качестве обучающих данных, обучим нашу модель и, наконец, найдем «друга», с которым мы сможем поговорить!

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

parent_data = find_parent(parent_id)

Теперь нам нужно создать функцию find_parent():

def find_parent(pid):
    try:
        sql = "SELECT comment FROM parent_reply WHERE comment_id = '{}' LIMIT 1".format(pid)
        c.execute(sql)
        result = c.fetchone()
        if result != None:
            return result[0]
        else: return False
    except Exception as e:
        #print(str(e))
        return False

Вероятно, есть более эффективный способ произвести эту операцию, но и так сработает. Итак, если у нас есть comment_id в нашей базе данных, которому соответствует parent_id другого комментария, то мы должны сопоставить этот новый комментарий с уже имеющимся у нас родителем.

В следующей статье мы начнем строить логику, необходимую для отбора подходящих данных.

Чат-бот на Python (Deep Learning + TensorFlow). Часть IV: строим логику.