2. Chatbot con inteligencia artifical en tensorflow
- Hola a todos.En esta ocasión continuamos con nuestro tutorial para crear y entrenar nuestro propio chatbot que se comportará con inteligencia artificial. Para crear un chatbot, o realmente hacer cualquier tipo de tarea de aprendizaje automático, el primer trabajo que tenemos que hacer es adquirir datos para el entrenamiento.Después necesitamos estructurarlos y prepararlos para que se formateen para "la entrada" y "la salida"para que un algoritmo de aprendizaje automático puede digerir.
- En esta entrada explicaremos el código necesario para volcar el contenido de los ficheros que descargamos en el capítulo anterior en una base datos. La idea es preparar la estructura de la base de datos para poder generar posteriormente los ficheros necesarios para entrenar nuestro modelo.
- En el siguiente vídeo explico el código que utilizamos para alcanzar nuestro propósito:
- Os dejo el código visto en el vídeo:
#Cargamos librerias necesarias
import sqlite3
import json
from datetime import datetime
import time
#De todos los meses disponibles en los datos del torrent de de reddit elijo marzo de 2015
timeframe = '2015-03'
sql_transaction = []
start_row = 0
cleanup = 1000000
#vamos a almacenar los datos en un una BBDD sqlLite
connection = sqlite3.connect('{}.db'.format(timeframe))
c = connection.cursor()
#Nos creamos una función para crear la tabla donde guardamos los campos que nos interesan del #JSON. En este caso son:
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)")
#Función para formatear los datos que vamos leyendo
def format_data(data):
data = data.replace('\n',' newlinechar ').replace('\r',' newlinechar ').replace('"',"'")
return data
# Esta función se utiliza para crear sentencias de inserción y confirmarlas en grupos
# en lugar de hacer que inserte uno a uno
def transaction_bldr(sql):
global sql_transaction
sql_transaction.append(sql)
if len(sql_transaction) > 1000:
c.execute('BEGIN TRANSACTION')
for s in sql_transaction:
try:
c.execute(s)
except:
pass
connection.commit()
sql_transaction = []
#función que actualiza el comentarios en nuestra BBDD sqlLite
def sql_insert_replace_comment(commentid,parentid,parent,comment,subreddit,time,score):
try:
sql = """UPDATE parent_reply SET parent_id = ?, comment_id = ?, parent = ?, comment = ?, subreddit = ?, unix = ?, score = ? WHERE parent_id =?;""".format(parentid, commentid, parent, comment, subreddit, int(time), score, parentid)
transaction_bldr(sql)
except Exception as e:
print('s0 insertion',str(e))
#Funcion que guarda en BBDD un comentario que tiene padre
def sql_insert_has_parent(commentid,parentid,parent,comment,subreddit,time,score):
try:
sql = """INSERT INTO parent_reply (parent_id, comment_id, parent, comment, subreddit, unix, score) VALUES ("{}","{}","{}","{}","{}",{},{});""".format(parentid, commentid, parent, comment, subreddit, int(time), score)
transaction_bldr(sql)
except Exception as e:
print('s0 insertion',str(e))
#Funcion que guarda en BBDD un comentario que no tiene padre
def sql_insert_no_parent(commentid,parentid,comment,subreddit,time,score):
try:
sql = """INSERT INTO parent_reply (parent_id, comment_id, comment, subreddit, unix, score) VALUES ("{}","{}","{}","{}",{},{});""".format(parentid, commentid, comment, subreddit, int(time), score)
transaction_bldr(sql)
except Exception as e:
print('s0 insertion',str(e))
#Solo guardamos los comentarios cuyo tamaño sea válido para el entrenamiento
def acceptable(data):
if len(data.split(' ')) > 1000 or len(data) < 1:
return False
elif len(data) > 32000:
return False
elif data == '[deleted]':
return False
elif data == '[removed]':
return False
else:
return True
#Función que encuentra el padre de un comentario dado
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
#Función que nos da la puntuación de un comentario dado
def find_existing_score(pid):
try:
sql = "SELECT score FROM parent_reply WHERE parent_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
if __name__ == '__main__':
create_table() #Empezamos creando la tabla sobre la que almacenar los datos
row_counter = 0 #Contador para ver en que parte del archivo estamos.Va contando las filas
paired_rows = 0 #Contador que nos dice las filas que están emparejas.Pregunta con respuesta
#Abrimos la ubicación del archivo que nos iteresa y vamos lyendo filas
with open('D:/reddit/RC_{}'.format(timeframe), buffering=1000) as f:
for row in f:
#print(row)
#time.sleep(555)
row_counter += 1
#vamos obtiendo los datos quqe nos interesan de cada fila
if row_counter > start_row:
try:
row = json.loads(row)
parent_id = row['parent_id'].split('_')[1]
body = format_data(row['body'])
created_utc = row['created_utc']
score = row['score']
comment_id = row['id']
subreddit = row['subreddit']
#Todos los comentarios inicialmente no tendrán un padre.
#Sin embargo, a medida que avanzamos en el documento, encontraremos
#comentarios que tienen padres que tenemos en nuestra base de datos.
#Cuando esto sucede, queremos agregar este comentario al padre existente.
parent_data = find_parent(parent_id)
existing_comment_score = find_existing_score(parent_id)
#Si existe un comentario asociado al padre con mejor puntuación reemplazamos
#el comentario existente.
#En el caso que el comentario no tenga padre se inserta
if existing_comment_score:
if score > existing_comment_score:
if acceptable(body):#validamos el tamaño
sql_insert_replace_comment(comment_id,parent_id,parent_data,body,subreddit,created_utc,score)
else:
if acceptable(body):
if parent_data:
if score >= 2:#solo tratamos comentarios con más de dos votos
sql_insert_has_parent(comment_id,parent_id,parent_data,body,subreddit,created_utc,score)
paired_rows += 1
else:
sql_insert_no_parent(comment_id,parent_id,body,subreddit,created_utc,score)
except Exception as e:
print(str(e))
#Muestro por pantalla cada 100000 filas
if row_counter % 100000 == 0:
print('Total Rows Read: {}, Paired Rows: {}, Time: {}'.format(row_counter, paired_rows, str(datetime.now())))
#Finalmente borrmos los comentarios que no tengan padre cada 100000 lineas #procesadas
if row_counter > start_row:
if row_counter % cleanup == 0:
print("Cleanin up!")
sql = "DELETE FROM parent_reply WHERE parent IS NULL"
c.execute(sql)
connection.commit()
c.execute("VACUUM")
connection.commit()
No hay comentarios:
Publicar un comentario