Формирование биграмм слов в списке предложений с Python
у меня есть список фраз:
text = ['cant railway station','citadel hotel',' police stn'].
мне нужно сформировать пары bigram и сохранить их в переменной. Проблема в том, что когда я это делаю, я получаю пару предложений вместо слов. Вот что я сделал:--5-->
text2 = [[word for word in line.split()] for line in text]
bigrams = nltk.bigrams(text2)
print(bigrams)
, который дает
[(['cant', 'railway', 'station'], ['citadel', 'hotel']), (['citadel', 'hotel'], ['police', 'stn'])
не может железнодорожный вокзал и отель цитадель сформировать один биграм. Чего я хочу, так это
[([cant],[railway]),([railway],[station]),([citadel,hotel]), and so on...
последнее слово первого предложения не должны совпадать с первым словом второго предложения. Что должно Я делаю, чтобы это сработало?
7 ответов
С помощью списочные включения и zip:
>>> text = ["this is a sentence", "so is this one"]
>>> bigrams = [b for l in text for b in zip(l.split(" ")[:-1], l.split(" ")[1:])]
>>> print(bigrams)
[('this', 'is'), ('is', 'a'), ('a', 'sentence'), ('so', 'is'), ('is', 'this'), ('this',
'one')]
вместо того, чтобы превращать текст в списки строк, начните с каждого предложения отдельно в виде строки. Я также удалил знаки препинания и стоп-слова, просто удалите эти части, если они не имеют отношения к вам:
import nltk
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from nltk.tokenize import WordPunctTokenizer
from nltk.collocations import BigramCollocationFinder
from nltk.metrics import BigramAssocMeasures
def get_bigrams(myString):
tokenizer = WordPunctTokenizer()
tokens = tokenizer.tokenize(myString)
stemmer = PorterStemmer()
bigram_finder = BigramCollocationFinder.from_words(tokens)
bigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 500)
for bigram_tuple in bigrams:
x = "%s %s" % bigram_tuple
tokens.append(x)
result = [' '.join([stemmer.stem(w).lower() for w in x.split()]) for x in tokens if x.lower() not in stopwords.words('english') and len(x) > 8]
return result
чтобы использовать его, сделайте так:
for line in sentence:
features = get_bigrams(line)
# train set here
обратите внимание, что это идет немного дальше и фактически статистически оценивает биграммы (которые пригодятся при обучении модели).
без nltk:
ans = []
text = ['cant railway station','citadel hotel',' police stn']
for line in text:
arr = line.split()
for i in range(len(arr)-1):
ans.append([[arr[i]], [arr[i+1]]])
print(ans) #prints: [[['cant'], ['railway']], [['railway'], ['station']], [['citadel'], ['hotel']], [['police'], ['stn']]]
from nltk import word_tokenize
from nltk.util import ngrams
text = ['cant railway station', 'citadel hotel', 'police stn']
for line in text:
token = nltk.word_tokenize(line)
bigram = list(ngrams(token, 2))
# the '2' represents bigram...you can change it to get ngrams with different size
просто исправление кода Дэна:
def get_bigrams(myString):
tokenizer = WordPunctTokenizer()
tokens = tokenizer.tokenize(myString)
stemmer = PorterStemmer()
bigram_finder = BigramCollocationFinder.from_words(tokens)
bigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, 500)
for bigram_tuple in bigrams:
x = "%s %s" % bigram_tuple
tokens.append(x)
result = [' '.join([stemmer.stem(w).lower() for w in x.split()]) for x in tokens if x.lower() not in stopwords.words('english') and len(x) > 8]
return result
>>> text = ['cant railway station','citadel hotel',' police stn']
>>> bigrams = [(ele, tex.split()[i+1]) for tex in text for i,ele in enumerate(tex.split()) if i < len(tex.split())-1]
>>> bigrams
[('cant', 'railway'), ('railway', 'station'), ('citadel', 'hotel'), ('police', 'stn')]
использование функции enumerate и split.
читать набор данных
df = pd.read_csv('dataset.csv', skiprows = 6, index_col = "No")
соберите все доступные месяцы
df["Month"] = df["Date(ET)"].apply(lambda x : x.split('/')[0])
создание токенов всех твитов в месяц
tokens = df.groupby("Month")["Contents"].sum().apply(lambda x : x.split(' '))
создание биграмм в месяц
bigrams = tokens.apply(lambda x : list(nk.ngrams(x, 2)))
количество биграмм в месяц
count_bigrams = bigrams.apply(lambda x : list(x.count(item) for item in x))
оберните результат в аккуратные фреймы данных
month1 = pd.DataFrame(data = count_bigrams[0], index= bigrams[0], columns= ["Count"])
month2 = pd.DataFrame(data = count_bigrams[1], index= bigrams[1], columns= ["Count"])