首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >符号化文本中符号(字符串)的频率

符号化文本中符号(字符串)的频率
EN

Stack Overflow用户
提问于 2018-04-03 01:02:28
回答 1查看 163关注 0票数 2

我有一组独特的ngram (列表称为ngram列表)和ngram标记文本(list称为ngram)。我想要构造一个新的向量,freqlist,其中的每个元素都是ngram的分数,等于ngram列表的元素。我编写了下面的代码,给出了正确的输出,但我想知道是否有一种优化它的方法:

代码语言:javascript
复制
freqlist = [
    sum(int(ngram == ngram_condidate)
        for ngram_condidate in ngrams) / len(ngrams)
    for ngram in ngramlist
]

我想在nltk或其他地方有一个函数可以更快地做到这一点,但我不确定是哪个函数。

谢谢!

编辑:由于nltk.util.ngramsngramlist的联合输出都是由所有找到的ngram组成的列表,所以它们都是有价值的。

Edit2:

这里有可重复的代码来测试freqlist行(剩下的代码不是我真正关心的)

代码语言:javascript
复制
from nltk.util import ngrams
import wikipedia
import nltk
import pandas as pd

articles = ['New York City','Moscow','Beijing']
tokenizer  = nltk.tokenize.TreebankWordTokenizer()

data={'article':[],'treebank_tokenizer':[]}
for article in articles:
    data['article' ].append(wikipedia.page(article).content)
    data['treebank_tokenizer'].append(tokenizer.tokenize(data['article'][-1]))

df=pd.DataFrame(data)

df['ngrams-3']=df['treebank_tokenizer'].map(
    lambda x: [' '.join(t) for t in ngrams(x,3)])

ngramlist = list(set([trigram for sublist in df['ngrams-3'].tolist() for trigram in sublist]))

df['freqlist']=df['ngrams-3'].map(lambda ngrams_: [sum(int(ngram==ngram_condidate) for ngram_condidate in ngrams_)/len(ngrams_) for ngram in ngramlist])
EN

回答 1

Stack Overflow用户

发布于 2018-04-03 17:28:24

首先,不要通过重写导入函数并使用它们作为变量来污染导入的函数,保留ngrams名称作为函数,并使用其他变量。

代码语言:javascript
复制
import time
from functools import partial
from itertools import chain
from collections import Counter

import wikipedia

import pandas as pd

from nltk import word_tokenize
from nltk.util import ngrams

接下来,您在原始问题中所问的行之前的步骤可能会有点效率低下,您可以清理它们,使它们更容易阅读,并以如下方式度量它们:

代码语言:javascript
复制
# Downloading the articles.
titles = ['New York City','Moscow','Beijing']
start = time.time()
df = pd.DataFrame({'article':[wikipedia.page(title).content for title in titles]})
end = time.time()
print('Downloading wikipedia articles took', end-start, 'seconds')

然后:

代码语言:javascript
复制
# Tokenizing the articles
start = time.time()
df['tokens'] = df['article'].apply(word_tokenize)
end = time.time()
print('Tokenizing articles took', end-start, 'seconds')

然后:

代码语言:javascript
复制
# Extracting trigrams.
trigrams = partial(ngrams, n=3)
start = time.time()
# There's no need to flatten them to strings, you could just use list()
df['trigrams'] = df['tokens'].apply(lambda x: list(trigrams(x)))
end = time.time()
print('Extracting trigrams took', end-start, 'seconds')

最后,到最后一行

代码语言:javascript
复制
# Instead of a set, we use a Counter here because 
# we can use an intersection between Counter objects later.
# see https://stackoverflow.com/questions/44012479/intersection-of-two-counters
all_trigrams = Counter(chain(*df['trigrams']))

# More often than not, you don't need to keep all the 
# zeros in the vectors (aka dense vector), 
# you could actually get the non-zero sparse vectors 
# as a dict as such
df['trigrams_count'] = df['trigrams'].apply(lambda x: Counter(x) & all_trigrams)

# Now to normalize the count, simply do:
def featurize(list_of_ngrams):
    nonzero_features = Counter(list_of_ngrams) & all_trigrams
    total = len(list_of_ngrams)
    return {ng:count/total for ng, count in nonzero_features.items()}

df['trigrams_count_normalize'] = df['trigrams'].apply(featurize)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49620764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档