Сегментация китайских слов, математическое представление текста и расчет сходства

искусственный интеллект
Сегментация китайских слов, математическое представление текста и расчет сходства

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

В повседневной жизни мы часто видим применение чат-ботов, таких как онлайн-обслуживание клиентов Taobao, автоматический ответ WeChat, прием роботов-офлайн-магазинов и т. д. Чат-боты могут помочь нам освободиться от монотонной и утомительной работы. Для разработки чат-бота вам необходимо освоить три основных понятия, а именно:Сегментация китайских слов,Математическое представление текстаиРасчет схожести текста.

Сегментация китайских слов

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

использоватьJiebaПример получения сегментации предложения:

import jieba
s = 'Python是一种面向对象的动态类型语言。'
[ print(c) for c in jieba.cut(s)]

результат:

Python
是
一种
面向对象
的
动态
类型
语言
。

Математическое представление текста

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

В математике слово может быть представлено вектором, который называетсяслово вектор.

Например, есть такой словарь:

Python, один, объектно-ориентированный, динамический, тип, язык

Затем дайте следующие три слова:

Python, объектно-ориентированный, искусственный интеллект

Векторы слов этих трех слов:

  • Python. (1, 0, 0, 0, 0, 0, 0, 0)
  • объектно-ориентированный. (0, 0, 0, 1, 0, 0, 0, 0)
  • искусственный интеллект. (0, 0, 0, 0, 0, 0, 0, 0)

Видно, что если слово в определенной позиции в словаре соответствует данному слову, оно устанавливается в 1, в противном случае оно устанавливается в 0.

Используйте Python для завершения преобразования вектора слов:

# 词库
word_vector_list = ["Python", "是", "一种", "面向对象", "的", "动态", "类型", "语言"]
# 要转成词向量的词
word1 = "Python"
word2 = "面向对象"
word3 = "人工智能"

# 定义词向量转换方法
def get_word_vector_result(word):
    return [ 1 if(w == word) else 0 for w in word_vector_list]

print(get_word_vector_result(word1))
print(get_word_vector_result(word2))
print(get_word_vector_result(word3))

результат:

[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]

Как представить вектор слова теперь известно, как представить предложение в виде вектора?

Или воспользуйтесь словарем прямо сейчас:

Python, один, объектно-ориентированный, динамический, тип, язык

Затем дайте следующие два предложения:

Python — язык высокого уровня

Мы изучаем Python

Векторы этих двух предложений:

  • Python — язык высокого уровня. (1, 1, 1, 0, 0, 0, 0, 1)
  • Мы изучаем Python. (1, 0, 0, 0, 0, 0, 0, 0)

Прежде чем получить вектор предложения, необходимо разбить причастие каждого предложения, а затем проверить, существует ли причастие в словаре в причастии данного предложения по одному, если оно существует, то ему присваивается значение 1, в противном случае он устанавливается в 0.

На самом деле суть преобразования векторов предложений — это преобразование векторов слов, за исключением того, что предложения состоят из множества сегментаций слов.

Используйте Python для завершения преобразования вектора предложения:

import jieba
# 词库
word_vector_list = ["Python", "是", "一种", "面向对象", "的", "动态", "类型", "语言"]
# 用户输入的语句
s1 = "Python是一种高级语言"
s2 = "我们在学习Python"

# 转化成向量的方法
def get_vector(data):
    data_iter = list(jieba.cut(data))
    return [ 1 if(w in data_iter) else 0 for w in word_vector_list]

# 打印向量
print(get_vector(s1))
print(get_vector(s2))

Python предоставляетgensimИнструменты, которые помогут нам завершить векторное преобразование:

from gensim.models import word2vec

# 从 xxx.txt 读取句子,文件中存的是一个个分词
sentences = word2vec.Text8Corpus('xxx.txt')

# 将句子转换为向量,句子的分词数量较小时,需要加上 min_count=1 参数
model = word2vec.Word2Vec(sentences, min_count=1)

# 将向量结果保存到 word2vec.model 中
model.save('word2vec.model')

# 得到分词的向量
model.wv['分词1', '分词2']

Расчет схожести текста

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

Евклидово расстояние

В декартовой системе координат заданы две точки: a(x1, y1), б(х2, y2), а их расстояния вычисляются следующим образом:

d=(x1x2)2+(y1y2)2d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}

Полученное таким образом расстояние равноЕвклидово расстояние. Распространяя его на n-мерное пространство, формула расчета расстояния выглядит следующим образом:

d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2 + ... + (n_1 - n_2)^2}

как пройтиЕвклидово расстояниеКак насчет вычисления сходства между двумя предложениями?

Учитывая векторы предложений следующих двух предложений:

  • Python — язык высокого уровня. (1, 1, 1, 0, 0, 0, 0, 1)
  • Мы изучаем Python. (1, 0, 0, 0, 0, 0, 0, 0)

Применяя формулу расчета евклидова расстояния, получаем:

d = \sqrt{(1 - 1)^2 + (1 - 0)^2 + ... + (1 - 0)^2}

когдаdЧем он ближе к 0, тем выше сходство предложений.

Манхэттенское расстояние

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

d = |x_1 - x_2| + |y_1 - y_2|

То есть сумма сторон прямоугольного треугольника, где лежит линия, соединяющая две точки.

Формула расчета расстояния, распространенная на n-мерное пространство, выглядит следующим образом:

d = |x_1 - x_2| + |y_1 - y_2| + ... + |n_1 - n_2|

Так же,dЧем он ближе к 0, тем выше сходство предложений.

косинусное сходство

косинусное сходствоСуть заключается в вычислении значения косинуса угла, образованного двумя векторами.Формула вычисления косинусного подобия n-мерного вектора:

cosθ=x1y1+x2y2+...+xnynx12+x22+...+xn2y12+y22+...+yn2cos\theta = \frac{x_1y_1 + x_2y_2 + ... + x_ny_n}{\sqrt{x_1^2 + x_2^2 + ... + x_n^2} \cdot \sqrt{y_1^2 + y_2^2 + ... + y_n^2}}

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

Интервал значения косинуса равен [-1, 1]. Когда значение ближе к 1, это означает, что два предложения более похожи, а когда значение ближе к -1, это означает, что два предложения меньше похожий.

Полный пример кода для вычисления сходства сегментации слов

import jieba
from gensim.models import word2vec

# 打开 fenci.txt,内容是一段原始文本
file1 = open('fenci.txt', encoding='utf-8')

# 将分词后的结果保存到 fen_ci.txt,
# open() 第二个参数是 mode,可传入 r/w/x/a
# 'r' -> readonly, 'w' -> truncating the file if it already exists , 'x' -> creating and writing to a new file, 'a' -> append
file2 = open('fenci_result.txt', mode='w', encoding='utf-8')

# 读取 fenci.txt 中的所有行
lines = file1.readlines()

# 将文本的空格、tab缩进、回车换行符都去掉,以便后续对整个文本内容进行分词
for line in lines:
    replaced_line = line.replace(' ', '').replace('\t', '').replace('\r', '').replace('\n', '')
    seg_list = jieba.cut(replaced_line)
    file2.write(' '.join(seg_list))

# 关闭资源
file1.close()
file2.close()

# 加载刚刚生成的语料库,就是已经生成的分词文件
sentences = word2vec.Text8Corpus('fenci_result.txt')

# 使用 word2vec 模型来训练机器(这里就是计算词向量),由于语料库中的分词数较少,需要加上 min_count=1 (最小分词数量=1)参数,否则会报错
model = word2vec.Word2Vec(sentences, min_count=1)

# 将模型命名为 word2vec.model,并保存为本地文件
model.save('word2vec.model')

# 得到词向量,要计算向量的分词必须存在于语料库中,否则会由于找不到分词而报错
word_vec_arr = model.wv['Python', '面向对象']

# 打印词向量
print(word_vec_arr)

# 计算两个分词的相似度
s1 = model.wv.similarity('Python', '面向对象')
s2 = model.wv.similarity('会', '不会')
s3 = model.wv.similarity('会', '会')

# 打印的结果:0.06410548、 -0.069218084、 1.0(完全一致)
print(s1, s2, s3)