15 KiB
import nltk
nltk.download("book", download_dir="/usr/local/share/nltk_data")
from nltk.book import *
text1
type(text1)
from nltk.text import Text
nltk.text.Text
for line in text1.concordance_list("whale"): print (line.left_print, line.query, line.right_print)
text5.tokens
Reading Words for the Future texts¶
Chapter 3 of the NLTK book discusses using your own texts using urlopen and the nltk.text.Text class.
We can use urllib.request.urlopen + pull the "raw" URLs of materials from the SI13 materials on git.xpub.nl.
url = "https://git.xpub.nl/XPUB/S13-Words-for-the-Future-materials/raw/branch/master/txt-essays/RESURGENCE%20Isabelle%20Stengers.txt"
url
from urllib.request import urlopen
r = urlopen(url)
rawtext = r.read()
text = rawtext.decode()
text = urlopen(url).read().decode()
len(text)
words = text.split?
words = text.split
words = text.split
words = text.split
words = text.split
words = text.split()
len(words)
from nltk import word_tokenize
tokens = word_tokenize(text)
len(tokens)
len(tokens)
tokens[-10:]
stengers = Text(tokens)
stengers.concordance("the", width=82, lines=74)
for line in stengers.concordance_list("the", width=82, lines=74): print (line.left_print, line.query, line.right_print)
with open ("patches/stengers_the.txt", "w") as output: for line in stengers.concordance_list("the", width=82, lines=74): print (line.left_print, line.query, line.right_print, file=output)
for line in stengers.concordance_list("the", width=82, lines=74): print (line.query)
stengers.concordance("the", width=3)
stengers.common_contexts(["power", "victims"])
stengers.dispersion_plot(["power", "the", "victims"])
from nltk.probability import FreqDist
freq = FreqDist(stengers)
freq["WHALE"]
freq['power']
freq.plot(50)
freq.plot(50, cumulative=True)
len(stengers)
len(set(stengers))
def lexical_diversity(text): return len(text) / len(set(text))
lexical_diversity(stengers)
def percentage (count, total): return 100 * count / total
percentage(4, 5)
NB: BE CAREFUL RUNNING THE FOLLOWING LINE ... IT'S REALLY SLOW... Not all code is equal, and just because two different methods produce the same result doesn't mean they're equally usable in practice
Why? because text1 (Moby Dick) is a list and checking if (x not in text1) has to scan the whole list of words AND THEN this scan is done FOR EVERY WORD in the stengers text The result is called "order n squared" execution, as the number of words in each text increases the time to perform the code get EXPONENTIALLY slower it's basically the phenomenon of nested loops on large lists.... SSSSSSSSSLLLLLLLLLOOOOOOOOOOOWWWWWWWWWWW
# stengers_unique = [] # for word in stengers.tokens: # if word not in text1: # stengers_unique.append(word)
# stengers_unique = [x for x in stengers.tokens if x not in text1]
FIX: make a set based on the Moby Dick text, checking if something is in a set is VERY FAST compared to scanning a list (Order log(n) instead of n)...
moby = set(text1)
"the" in moby
Rather than n*n (n squared), the following is just n log(n) which is not* exponential as n gets big
stengers_unique = [] for word in stengers.tokens: if word not in moby: stengers_unique.append(word)
The above can also be expressed using the more compact form of a list comprehension
stengers_unique = [word for word in stengers.tokens if word not in moby]
len(stengers_unique)
stengers_unique
stengers_unique_text = Text(stengers_unique)
freq = FreqDist(stengers_unique)
freq.plot(50)
stengers_unique_text.concordance("witches")
Increasing the default figure size¶
from IPython.core.pylabtools import figsize
figsize(20.0,20.0)
stengers
stengers
Nami asks: How to I get concordances of just words ending "ity"¶
t = stengers
ity = [] for w in stengers: if w.endswith("ity"): # print (w) ity.append(w.lower()) ity = set(ity)
for word in ity: stengers.concordance(word)
"Objectivity".lower
set(ity)
Clara asks, what about lines that are shorter than the width you give?¶
https://www.peterbe.com/plog/how-to-pad-fill-string-by-variable-python
cwidth is how much "padding" is needed for each side it's our page width - the length of the word divided by 2 in python means "integer" (whole number) division
for line in stengers.concordance_list("resurgence", width=82, lines=74): cwidth = (82 - len("resurgence")) // 2 # print (cwidth) print ( line.left_print.rjust(cwidth), line.query, line.right_print.ljust(cwidth) )