如何使用单个字母字符串列表作为输入来生成概率最高的双字母组合的结果

时间:2018-08-24 16:26:22

标签: python python-3.x nlp nltk probability

我正在学习有关bigram主题的自然语言处理。在这个阶段,我在Python计算上遇到了困难,但是我尝试了。

我将使用尚未经过标记化处理的语料库作为我的主要原始数据集。我可以使用nltk模块生成bigram结果。但是,我的问题是如何在Python中进行计算以生成包含两个以上特定单词的双字母组。更具体地说,我希望找到所有在corpus_A中可用的二元组,其中包含来自word_of_interest的单词。

  
    
      

corpus = [“他并不是那么容易放弃,但他始终坚强地感到孤独,他总是结识新朋友以获取成功的动力和灵感,他年轻时就坚守学术诚信,他希望圣诞老人在成年后会给他更多的朋友,他不再希望圣诞老人到来,他和他的朋友总是外出就餐,但他们在进食前先洗手除沙”]

             

word_of_interest = ['santa','and','hand','stands','handy','sand']

    
  

我想从word_of_interest列表中获取每个单词的双字母组。接下来,我想根据每个双字母组在corpus_A中的出现来获得频率。利用可用的频率,我想根据二元组从高到低的概率进行分类和打印。

我已经尝试了在线搜索中的代码,但是没有输出。代码如下:

for i in corpus:
    bigrams_i = BigramCollocationFinder.from_words(corpus, window_size=5)
    bigram_j = lambda i[x] not in i
    x += 1
print(bigram_j)

不幸的是,输出没有返回我计划实现的目标。

请给我建议。我想要的输出将包含来自word_of_interest中特定单词的双字母组,其概率按如下所示排序。

[((santa, clauss), 0.89), ((he, and), 0.67), ((stands, firm), 0.34))] 

1 个答案:

答案 0 :(得分:0)

您可以尝试以下代码:

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
vec = TfidfVectorizer(ngram_range=(2,2),use_idf=False)

corpus = ["he is not giving up so easily but he feels lonely all the time his mental is strong and he always meet new friends to get motivation and inspiration to success he stands firm for academic integrity when he was young he hope that santa would give him more friends after he is a grown up man he stops wishing for santa clauss to arrival he and his friend always eat out but they clean their hand to remove sand first before eating"]
word_of_interest = ['santa', 'and', 'hand', 'stands', 'handy', 'sand']
matrix = vec.fit_transform(corpus).toarray()
vocabulary = vec.get_feature_names()

all_bigrams = []
all_frequencies = []
for word in word_of_interest:
    for bigram in vocabulary:
        if word in bigram:
            index = vocabulary.index(bigram)
            tuple_bigram = tuple(bigram.split(' '))
            frequency = matrix[:,index].sum()
            all_bigrams.append(tuple_bigram)
            all_frequencies.append(frequency)

df = pd.DataFrame({'bigram':all_bigrams,'frequency':all_frequencies})
df.sort_values('frequency',inplace=True)
df.head()

输出是一个熊猫数据帧,其中显示了按频率排序的二元数。

    bigram  frequency
0     (for, santa)   0.109764
19  (stands, firm)   0.109764
18    (he, stands)   0.109764
17   (their, hand)   0.109764
16      (hand, to)   0.109764

这里的理由是,TfidfVectorizer会计算一个语料在每个语料库文档中存在多少次,然后计算特定于术语的频率,然后将该信息存储在与该语标关联的列中。该列的索引与词汇表中的关联单词的索引相同,该词汇表已使用已经适合的矢量化器方法.get_feature_names()检索。 然后,您只需从包含令牌的相对频率的矩阵中选择所有行,然后沿着感兴趣的列求和即可。

双重嵌套的for循环虽然不是理想的,但是可能有一个更有效的实现。问题是get_feature_names不返回元组,而是以['first_token second_token',]形式的字符串列表。 我希望看到上述代码后半部分的更好实现。