База знаний НЛП: предварительная обработка текстовых данных

искусственный интеллект

"Это второй день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г.".

1. Зачем нужна предварительная обработка?

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

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

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

2. Несколько носителей для хранения текста

Как правило, непосредственно читаемые текстовые данные хранятся в следующих файлах:

  • База данных: sqlite, mysql...
  • Табличные файлы: csv, excel...
  • Обычные текстовые файлы: txt, json...

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

2.1 База данных

Базы данных хранят текстовую информацию и имеют множество преимуществ:

  • Поддержка хранения больших данных
  • Эффективный запрос
  • Поддерживайте сложные отношения

Возьмите базу данных sqlite в качестве примера, чтобы увидеть, как читать данные.

Ниже приведен файл базы данных размером 8 КБ.

db图标.png

В базе данных есть таблица с именем "ci", структура данных и содержание которой следующие:

db内容.png

В таблице хранится 25 фрагментов данных, которые представляют собой 25 стихотворений из песен, и каждый фрагмент данных включает в себя порядковый номер (значение), торговую марку слова (ритмический), автора (автор) и содержание (контент).

Предположим, мы хотим использовать содержимое каждого слова в качестве обучающего набора, так как же мы организуем данные?

# 导入sqlite的支持
import sqlite3

# 保存每首词的内容
str_array  = []

# 指定文件位置(同级目录data下的data.db文件)建立连接
conn = sqlite3.connect('./data/data.db')
# 执行查询语句,只获取author, content两个字段,获得游标(内含结果)
cursor = conn.execute("SELECT author, content from ci;")
# 循环结果
for row in cursor:
    # 获取结果(0 author, 1 content)中索引为1的数据
    ci = row[1]
    # 加入内容列表
    str_array.append(ci)

# 关闭操作
cursor.close()
conn.close()

# 打印结果
print(str_array)

Окончательный результат печати выглядит следующим образом:

[
'出砒霜,价钱可。\r\n赢得拨灰兼弄火。\r\n畅杀我。', 
'丞相有才裨造化,圣皇宽诏养疏顽。\r\n赢取十年闲。', 
'归。\r\n十万人家儿样啼。\r\n公归去,何日是来时。', 
'归。\r\n数得宣麻拜相时。\r\n秋前後,公衮更莱衣。', 
'百尺长藤垂到地,千株乔木密参天。\r\n只在郡城边。', 
'巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\n'
 ……
]

в\r\nявляется переводом строки возврата каретки. Посмотрим巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\nОтображение в текстовом поле может помочь вам лучше понять.

rn文本框展示.gif

Дополнительные знания: написание sqlite3

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

В следующем примере показано, что 2 фрагмента данных вставляются непрерывно.

# 导入sqlite的支持
import sqlite3

# %% 数据表数据的写入
conn = sqlite3.connect('./data/data.db')
for t in[(9998,"名称1","作者1","正文1"),(9999,"名称2","作者2","正文2")]:
    conn.execute("insert into ci values (?,?,?,?)", t)
    
conn.commit()
conn.close()

2.2 Форма документов

По сравнению с базами данных табличные документы (csv, excel) также являются хорошим способом хранения текста.

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

Ниже есть файл csv, в нем много строк, каждая строка — это песня, а первые три столбца — это: название слова бренда, автор и содержание.

csv内容.png

Предположим, мы хотим использовать содержимое каждого слова в качестве обучающего набора, так как же мы организуем данные?

import csv

# 建立存储内容的数组
str_array  = []

# 构建阅读器,指定文件位置(同级目录data下的data.csv文件),指定编码格式
csv_reader = csv.reader(open("./data/data.csv",encoding="gbk"))
# 循环每一行
for row in csv_reader:
    # 取出索引为2的列(第3列),存入数组
    str_array.append(row[2])
	
# 打印数据    
print(str_array)

Окончательный результат печати выглядит следующим образом:

[
'出砒霜,价钱可。\r\n赢得拨灰兼弄火。\r\n畅杀我。', 
'丞相有才裨造化,圣皇宽诏养疏顽。\r\n赢取十年闲。', 
'归。\r\n十万人家儿样啼。\r\n公归去,何日是来时。', 
'归。\r\n数得宣麻拜相时。\r\n秋前後,公衮更莱衣。', 
'百尺长藤垂到地,千株乔木密参天。\r\n只在郡城边。', 
'巍峨万丈与天高。\r\n物轻人意重,千里送鹅毛。\r\n\r\n'
 ……
]

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

Расширенные знания: написание csv

Запись данных аналогична чтению данных. Сначала создайте модуль записи, запишите данные и, наконец, закройте открытый файл.

В следующем примере показано, что создается новый CSV-файл, а затем вставляется 1 часть данных.

import csv

# 以写入的方式打开(新建)一个文件,指定编码
f_csv = open('./data/data2.csv','w',encoding='gbk', newline='')
# 获取这个文件的写入器
csv_writer = csv.writer(f_csv)
# 写入一行数据
csv_writer.writerow(['第一列','第二列','第三列'])

# 关闭文件
f_csv.close()

После выполнения кода в каталоге данных того же уровня будет создан новый файл data2.csv, а затем будут записаны данные одной строки и трех столбцов.

csv写入.png

2.3 Текстовые документы

Текстовые документы (txt) — это самая легкая форма хранения текста.

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

Однако у него есть и преимущества. То есть - простой в использовании.

Откройте файл и введите в него символы.

Поскольку понятия количества строк и столбцов не существует, обычные текстовые документы для хранения наборов данных отличаются специальными символами, такими как возврат каретки и перевод строки, а строка — это часть данных.

Ниже фрагмент текста, давайте посмотрим, как его читать.

txt内容.png

import os

# 保存每行文本内容的数组
str_array  = []

# 指定文件位置(同级目录data下的data.txt文件)
f_read = open('./data/data.txt','rb')
# 读取一行文件
line = f_read.readline()
# 如果此行存在
while line: 
    # 读出内容
    wstr = str(line, encoding = "utf-8-sig")
    # 添加到数组
    str_array.append(wstr)
    # 接着再读下一行
    line = f_read.readline()

# 关闭文件
f_read.close()

# 打印数组
print(str_array)

Окончательный результат печати выглядит следующим образом:

[
'巍峨万丈与天高。物轻人意重,千里送鹅毛。\r\n', 
'远来犹自忆梁陈。江南无好物,聊赠一枝春。\r\n', 
'用心勤苦是新诗。吟安一个字,拈断数茎髭。\r\n', 
'扪窗摸户入房来。笙歌归院落,灯火下楼台。\r\n', 
'酥某露出白皑皑。遥知不是雪,为有暗香来。\r\n', 
'称觞喜对二阳临。况当弦月上,一醉祝千春。\r\n'
]

Расширенные знания: написание txt

Запись данных аналогична чтению данных. Сначала откройте файл, запишите данные и, наконец, закройте открытый файл.

В следующем примере показано, что создается новый файл txt, а затем записывается текст.

import os

# 以写入的方式打开(新建)data2.txt的文本
f_write = open('./data/data2.txt','w')
f_write.write('写入文本第一行\n第二行')

f_write.close()

3. Комбинированный перфоратор: очистите данные и сохраните их в виде файла json.

Предположим, мы хотим обучить набор данных о Song Ci, а источником данных являются данные этой таблицы в следующей базе данных.

组合拳 词.png

Кажется, что данные хорошо организованы, но не все так идеально.

组合拳 词的问题.png

На данный момент у вас есть несколько требований:

  1. Устранение избыточности: удалите избыточные данные в начале и в конце и удалите повторяющиеся данные.
  2. Выполните фильтрацию: мне нужны данные только в шаблоне предложения «Линь Сяньцзян».
  3. Изменить хранилище: поскольку объем данных невелик, я хочу хранить очищенные данные в текстовом формате json.

анализировать:

  1. Чтобы удалить начальные и конечные пробелы и разрывы строк текста, вы можете использоватьstrip()метод. Удаление повторяющихся данных может быть достигнуто с помощью логики кода, сохранения найденных предложений и поиска следующего предложения в сохраненном списке.Если описание повторяется, описание не найдено.Просмотрите его в первый раз.

  2. Формат «Линь Сяньцзян»: {[7 китайских иероглифов]. [5 китайских символов], [5 китайских символов]. }, можно отфильтровать с помощью регулярного сопоставления, регулярное выражение:^[\u4e00-\u9fa5]{7}。\r\n[\u4e00-\u9fa5]{5},[\u4e00-\u9fa5]{5}。$.

  3. Считайте данные из базы данных, отфильтруйте соответствующий текст и сформируйте строку json для записи текста.

код показывает, как показано ниже:

import sqlite3
import json
import re

# 存储内容的数组
str_array = []
# 已经遇到过的内容
keys = {""}

# 筛选 {7。5,5。}格式内容的正则表达式
pattern = re.compile(r'^[\u4e00-\u9fa5]{7}。\r\n[\u4e00-\u9fa5]{5},[\u4e00-\u9fa5]{5}。$') 

# 连接数据库
conn = sqlite3.connect('./data/data.db')
# 执行查询,只获取内容字段,获得游标结果
cursor = conn.execute("SELECT content from ci;")
# 循环结果
for row in cursor:
    # 获取索引为0的列
    ci = row[0]
    # 裁剪头尾
    ci = ci.strip()
    # 匹配格式
    m = pattern.match(ci)
    # 没有匹配到
    if m == None:
        print('\n没有匹配到:',ci)
    else: # 匹配到
        print('\n匹配成功:',ci)
        # 是否出现过
        if ci in keys:
            # 出现过,是重复的,不处理
            print('\n已存在->',ci)
        else:
            # 没有出现过,加入出现列表,加入内容列表
            keys.add(ci)
            str_array.append(ci)

# 关闭游标和链接
cursor.close()
conn.close()

# 将内容列表转为json
j_str = json.dumps(str_array, indent=2, ensure_ascii=False)
# 打开(新建)文本
f_write = open('./data/data2.json','w')
# 写入文本
f_write.write(j_str)
# 关闭文件
f_write.close()

Содержимое сгенерированного data2.json выглядит следующим образом:

生成的json.png