gpt4 book ai didi

python - 如何识别与主题相关的句子?

转载 作者:行者123 更新时间:2023-11-30 22:08:48 26 4
gpt4 key购买 nike

我正在做一个项目,需要我对文档进行排序以与主题匹配。

例如,我有 4 个主题,即讲座、导师、实验考试。我有一些句子是:

  1. 讲座很吸引人
  2. 导师非常友善且活跃
  3. 2个小时的讲座内容太多了。
  4. 与每周的实验室相比,考试似乎太难了。

现在我想将这些句子排序到上面的主题中,结果应该是:

  • 讲座:2
  • 导师:1
  • 考试:1

我做了研究,发现最多的指导是使用 LDA 主题建模。但似乎无法解决我的问题,因为据我所知LDA支持识别文档中的主题,并且不知道如何手动预先选择主题。

有人可以帮我吗?我坚持这一点。

最佳答案

这是使用比字符串匹配更智能的东西的绝佳示例 =)

让我们考虑一下:

  • 有没有办法将每个单词转换为向量形式(即 float 数组)?

  • 有没有办法将每个句子转换为相同的向量形式(即与单词向量形式具有相同维度的 float 数组?

<小时/>

首先让我们获得句子列表中所有可能出现的单词的词汇表(我们称之为语料库):

>>> from itertools import chain
>>> s1 = "Lecture was engaging"
>>> s2 = "Tutor is very nice and active"
>>> s3 = "The content of lecture was too much for 2 hours."
>>> s4 = "Exam seem to be too difficult compare with weekly lab."
>>> list(map(word_tokenize, [s1, s2, s3, s4]))
[['Lecture', 'was', 'engaging'], ['Tutor', 'is', 'very', 'nice', 'and', 'active'], ['The', 'content', 'of', 'lecture', 'was', 'too', 'much', 'for', '2', 'hours', '.'], ['Exam', 'seem', 'to', 'be', 'too', 'difficult', 'compare', 'with', 'weekly', 'lab', '.']]
>>> vocab = sorted(set(token.lower() for token in chain(*list(map(word_tokenize, [s1, s2, s3, s4])))))
>>> vocab
['.', '2', 'active', 'and', 'be', 'compare', 'content', 'difficult', 'engaging', 'exam', 'for', 'hours', 'is', 'lab', 'lecture', 'much', 'nice', 'of', 'seem', 'the', 'to', 'too', 'tutor', 'very', 'was', 'weekly', 'with']

现在让我们使用词汇表中单词的索引将 4 个关键词表示为向量:

>>> lecture = [1 if token == 'lecture' else 0 for token in vocab]
>>> lab = [1 if token == 'lab' else 0 for token in vocab]
>>> tutor = [1 if token == 'tutor' else 0 for token in vocab]
>>> exam = [1 if token == 'exam' else 0 for token in vocab]
>>> lecture
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> lab
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> tutor
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
>>> exam
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

同样,我们循环遍历每个句子并将它们转换为向量形式:

>>> [token.lower() for token in word_tokenize(s1)]
['lecture', 'was', 'engaging']
>>> s1_tokens = [token.lower() for token in word_tokenize(s1)]
>>> s1_vec = [1 if token in s1_tokens else 0 for token in vocab]
>>> s1_vec
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]

对所有句子重复相同的操作:

>>> s2_tokens = [token.lower() for token in word_tokenize(s2)]
>>> s3_tokens = [token.lower() for token in word_tokenize(s3)]
>>> s4_tokens = [token.lower() for token in word_tokenize(s4)]
>>> s2_vec = [1 if token in s2_tokens else 0 for token in vocab]
>>> s3_vec = [1 if token in s3_tokens else 0 for token in vocab]
>>> s4_vec = [1 if token in s4_tokens else 0 for token in vocab]
>>> s2_vec
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
>>> s3_vec
[1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0]
>>> s4_vec
[1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1]

现在,给定句子和单词的向量形式,您可以使用相似度函数,例如cosine similarity :

>>> from numpy import dot
>>> from numpy.linalg import norm
>>>
>>> cos_sim = lambda x, y: dot(x,y)/(norm(x)*norm(y))
>>> cos_sim(s1_vec, lecture)
0.5773502691896258
>>> cos_sim(s1_vec, lab)
0.0
>>> cos_sim(s1_vec, exam)
0.0
>>> cos_sim(s1_vec, tutor)
0.0

现在,更系统地进行:

>>> topics = {'lecture': lecture, 'lab': lab, 'exam': exam, 'tutor':tutor}
>>> topics
{'lecture': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'lab': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'exam': [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'tutor': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]}


>>> sentences = {'s1':s1_vec, 's2':s2_vec, 's3':s3_vec, 's4':s4_vec}

>>> for s_num, s_vec in sentences.items():
... print(s_num)
... for name, topic_vec in topics.items():
... print('\t', name, cos_sim(s_vec, topic_vec))
...
s1
lecture 0.5773502691896258
lab 0.0
exam 0.0
tutor 0.0
s2
lecture 0.0
lab 0.0
exam 0.0
tutor 0.4082482904638631
s3
lecture 0.30151134457776363
lab 0.0
exam 0.0
tutor 0.0
s4
lecture 0.0
lab 0.30151134457776363
exam 0.30151134457776363
tutor 0.0
<小时/>

我想你明白了。但我们看到 s4-lab 和 s4-exam 的分数仍然是平的。所以问题就变成了,“有没有办法让它们发散?”你会跳进兔子洞:

  • 如何最好地将句子/单词表示为固定大小的向量?

  • 使用什么相似度函数来比较“主题”/单词与句子?

  • 什么是“主题”?这个向量实际上代表什么?

上面的答案就是通常所说的one-hot向量来表示单词/句子。这比简单地比较字符串来“识别与主题相关的句子?”要复杂得多。 (又名文档聚类/分类)。例如。一份文档/句子可以有多个主题吗?

请查找这些关键字以进一步理解“自然语言处理”、“文档分类”、“机器学习”问题。同时,如果您不介意的话,我想这个问题已经很接近了“太宽泛”

关于python - 如何识别与主题相关的句子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52087044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com