One Fine Day

So, you know how it goes. You have the best of intentions. You have the motivation to work on your new blog (a lot more than you used to, anyway), and you’re going to capitalize on it.

Well, another year has passed, and I’ve not touched this website, nor this blog.

In my defense, I’ve been working (somewhat) diligently on my dissertation, and I’m getting to the point where I can see the potential first rays of light shining from that oncoming train that is my graduation deadline. When things clarify a bit, when I can say for certain that it’s a train or the end of the tunnel…that’s when I’ll put some more effort into this enterprise.

Until then, I ask only for patience from the unending void of the universe that is my readership. I’ll get there one day.

Encode This!

What is simultaneously a terrifically frustrating programming language to learn and a nigh-unredeemable horror flick starring Robert Englund (but without the really cool razorglove)? Give up?

It’s Python…er…Python!

The truth is, it’s not usually so bad. I’ve had much worse times learning things like VisualBasic and C++, so I guess I shouldn’t complain.  I’m just frustrated because I don’t have time to deal with something piddly like this: I have to figure out how to change the encoding on my files so I can use extended characters.

Why, you ask? Well, as I’m working with Old English in my webscraping/topic modeling project, I need to process texts that use characters that have disappeared from the language, specifically Æ (ash), Þ (thorn), and Ð (eth).  I also need to support both upper and lower case versions of these letter forms.  In the good news department, ᚹ (wynn, apparently not supported here, either) has already been converted to W in the source files I’ll be using.

So what now?  Well, I get to run a bunch of functions in Python that look like this:

def add_ash(input):
output = re.sub('&aelig', 'æ', input)
return output

The problem, of course, is that Python itself only supports ASCII in its base form, meaning it only understands about 128 characters natively (a move that I understand since the language is designed to be useful and low-overhead); I have to figure out how to change the encoding to UTF-8 or somesuch.

I honestly have no idea WHAT I need to change the encoding in (the entire script? the Python environment itself? Time and Space, perhaps?), nor how to go about doing so.  All I know is that the word “þæt” should not come out looking like “þæt” when I dump my data into Mallet.

Scraping Web Pages (But Not Off of the Kitchen Floor)*

Baby Steps by marisag on Flickr

Baby Steps by marisag on Flickr. Creative Commons license

Okay, so this is going to be a middle-of-the-process post as I attempt to make something useful using Python.  Specifically, I’m working on learning how to scrape web pages for content without going crazy or devoting more time to such a project than I would already use simply by going to each of these web pages and manually copying and pasting the text.  I say that it’s the middle of the process because I’ve already done some of the work (success!), although there’s still a lot to do and several technological problems to overcome first (not-yet-failures).

First, though, it’s probably a good idea for me to clarify the project so that I can talk lucidly about what I have not yet done.

Ultimately, this scraping project is about getting some texts together so that I can create some useful topic models for my own research on the Exeter Book. I’ve mentioned before that the corpus of surviving Anglo-Saxon poetry is fairly limited; we have a mere 30,000 lines or so, and those lines exist, for the most part, in four collections: the Junius Manuscript, the Vercelli Book, the Nowell Codex, and the Exeter Book.  Each of these books has been published several times, both as complete collections and as editions of individual poems.  This presents a problem insofar as the creation of topic models are dependent on great numbers of texts which, in this case at least, are not extant.

Well, the best thing I can do is work with what I have.  Jessica came across a pretty good source for the texts online, too: seems to be pretty okay, and the fact is that I’m not at a point in the semester where I can go through and check their editing job, anyway.  This site certainly meets one criterion, though: the text isn’t bogged down with a lot of other material.  With relatively straightforward HTML, then, I should be able to scrape away with no issues!

With that in mind, I needed to develop a plan with definable goals so I could start getting done what needs to get done.  I came up with the following list of steps:

  1. Scrape the URLs of the child pages from the landing/parent page
  2. Remove the small number of unwanted URLs from the results
  3. Scrape the child pages
  4. Write the “scrapings” to a text file
  5. Profit!

So far, this is what I’ve done:

  1. Toss my current Python environment and start running Linux
  2. Install BeautifulSoup and a few other modules into Python
  3. Scrape the URLs of the child paes from the landing/parent page
  4. Write the scraped URLs to a text file

The first step was a little more work than I really wanted it to be; I’ve been running Python inside a Linux-like environment on Windows called Cygwin, but that has started to be more trouble than it’s worth.  For example, every tutorial I read on BeautifulSoup told me to start the script with the line

from bs4 import BeautifulSoup

The problem there is that Cygwin’s version of Python needed something different, specifically:

from BeautifulSoup import BeautifulSoup

I arrived at this information through extensive trial and error, not through any documentation, which is a real problem in Cygwin, it seems, because there are other differences in Python, as well, such as the use of module names written in camel-caps (capitalizing the first letter of the second word instead of using a space or underscore) instead of the otherwise-universally used underscore method of calling modules.  There needed to be a better way.

Indeed there was; rather than give up on Linux and its advantages for doing things in Python, and rather than continuing to suffer through the Cygwin problem, I decided to install Ubuntu on a flash drive and run from that.  This solution is great because it doesn’t wipe my hard drive at all, it doesn’t cause any problems as far as compatibility is concerned (as Windows or Cygwin do), and this way I get to play with Linux while scraping away.

Once in my new environment, I was happy to see that I could install and run the various necessary modules with the same common commands listed in much of the documentation we’ve seen linked in class.  The next problem would be to use the modules to scrape the code from the parent page.  Cobbling together code from two or three tutorials, I ended up with a script that looks like this:

from bs4 import BeautifulSoup
import requests

url = ""
r  = requests.get(url)
data = r.text
soup = BeautifulSoup(data)

for link in soup.find_all('a'):
	address_text = link.get('href')
	target = open("target\targetURLs.txt", 'a')

This worked straight off the bat.  It also provided me with a text file of the results, which means that I can go through and manually clean up the two or three additional links that I don’t need to follow when building my catalog of Old English poetry.

There you have it.  My next goal is to learn how to read through the text file and load each line into a loop so that it can function as a full URL.  Then it’s off to scraping to another file and ultimately to cleaning up the text, although I may have a lead on the latter that will make things a lot easier, even it it is a little bit like cheating.  More later!

*In case you’re wondering, the title is a reference to one of the recent cartoons that marks the triumphant return of Homestar Runner, or in this case, the triumphant return of Strong Bad and the Cheat making music videos.

Mixing Methodology and Interdisciplinarity: Text Mining and the Study of Literature

???As I’ve mentioned earlier, I enrolled in Digital Methods this semester for many reasons, but one of the big ones was to learn the technology necessary to do some serious text analysis.  Text Mining, and specifically Topic Modeling, are exactly what I want to deal with and I’m quite excited to be able to start working with the tools that, at least hopefully, will allow me to perform a remarkable form of analysis that will inform my dissertation in new and compelling ways.  The trouble is, as a student of literature, my method is usually set to focus on a very small number of texts (indeed, usually a single text); topic modeling, however, requires thousands of texts in order to be effective.  As a result, I need to deal with some pretty hairy problems.

They come in two basic groups: problems with acquiring texts and problems with rendering the texts.  Neither of these is a problem inherent and isolated to Anglo-Saxon studies, but there are some particular difficulties in both arenas that I think I’m going to have to ask for help on if I’m going to bring all this to a successful conclusion.

As far as acquiring texts is concerned, the fact is that one would expect such a thing to be easy.  After all, most of what we study as Anglo-Saxonists has been published over and over again for centuries.  Zupitza’s first edition of Beowulf was published in 1815, almost 200 years ago, so one would expect that sort of thing to be readily available as a part of the public domain, right?

Well, for the most part, yes.  There are a lot of documents out there where people have edited one poem or another, and there are even websites that feature all of Anglo-Saxon poetry (approximately 30,000 lines, a rather meager sample size).  The problem here comes in the fact that it’s also all poetry.  If topic modeling works on the principle of words being found in association with one another, then the fact that Anglo-Saxon verse is built on variation might cause some problems, as it would for any analysis that attempted to build a series of categories around poetry alone.  Thus, in order to understand poetry, a large number of prose texts must also be found.

This leads into the second difficulty.  While I have no doubt that various software tools can learn to handle the special characters used in Anglo-Saxon manuscripts (ash “æ”, eth “ð”, thorn “þ”, wynn “ƿ”, and others), one must also allow for the fact that different editors have different editorial practices, including the use of diacritic marks (many editors differentiate between the short “a” and the long “ā”, for example, as it helps modern readers, who would not know the differences in pronunciation).  Since marks like the macron do not appear in manuscripts, there is no widespread standard as to their use, nor is there a way to ensure that decisions made by editors are perfectly reliable.  There is likewise no way to ensure that the texts even represent their native language in a standard way since spelling would not be normalized for several centuries.  Thus, any decision I make with regards to cleaning and standardizing the texts I include in my sample has the very real potential to cause false associations and false results.

I have no idea how to deal with the complexities of this problem in a way that will work for my dissertation.  I can only sit back and learn about the process and its workings one step at a time, hoping that some sort of answer will occur to me.  It’s certainly possible that I’m just missing the obvious right now, too.  As I apply myself to tools like MALLET, I’ll be sure to be on the lookout.

Why I Hate to Wait: The Real Cost of Less-Than-Immediate Computing

"Lost" by Jose Maria Cuellar . Used under CC-BY-NC license.

“Lost” by Jose Maria Cuellar . Used under CC-BY-NC license.

If there is a single force on this Earth that unites us all, making clear that we are all the same regardless of our culture, gender, age, socioeconomic background, or language, it is that we hate to wait for technology.  Unfortunately, this is not going to be the force that eliminates war or poverty, but it does speak volumes about how we use these miraculous machines we’ve created and what we expect of them in our day-to-day interactions.  When we click, we want to see evidence that we clicked.  When we type, we expect characters to show up on the screen simultaneously.  Even in my earliest computer-related activities, I wondered why it took so long for the computer do do some things, while it seemed like it could handle anything I threw at it as fast as I could throw it in other situations (those of you who have used a BBS know exactly to which pain I am referring).

Interestingly, though, my problem isn’t one of simple, aggravated frustration.  Again, this is probably because I cut my digital teeth in a world where online speed was measured in baud and most data moved around in 720 K chunks via sneakernet.  In those days, the expectations may have been low, but there were still basic things we expected computers to do, such as reflect our input.  When something happened and we were forced to wait (which happened a lot), we sometimes got frustrated with the machine itself and banged on it like it were some sort of mechanical device (perhaps one of Grace Hopper’s bugs got in there somewhere?), but we never really walked away.  We never gave up because computers were just like that and we accepted them in all of their fickle imperfection because we didn’t know any better.

Now, that may sound like an advantage at first, and indeed it probably is when dealing with magic boxes one barely understands, but it does come with its own set of problems, especially given the current ubiquity and pervasiveness of the web.  In particular, when I have to wait for login information to be e-mailed to me by an automated system, I tend to wait for a few minutes, but invariably if it isn’t in my mailbox in under 180 seconds, I get distracted by something else and then completely forget that I ever signed up for an e-mail in the first place.  This is precisely the problem I’m having with a number of the services to which we were directed for text mining.  In the case of Bookworm, it’s been several days, and the only reason I remember that I signed up in the first place is that I wanted to be sure to write this blog post about my frustrations surrounding text mining.

So yes, in short, sometimes the biggest frustrations we face in the realm of technology is not the software itself, but simply getting access to it.  I know that’s been my struggle on a number of occasions outside of the work we’re doing for Digital Methods, and it has popped up occasionally in #digimeth, as well.  As in everything else, persistence and purpose will win out in the end, but sometimes I wonder how much I haven’t learned just because I forgot I was interested in the first place.

The Best Laid Plans of Mice and Medievalists…

There can really be no doubt about which of the #digimeth technologies I’m weakest with; I’ve messed around with all sorts of programming languages and I’ve used many different types of software over the years with varying levels of success, but I’ve never been good with geospatial stuff.  As I tweeted before, I’m bad enough when I have to read a map; I’m pretty sure it’s a bad idea to ask me to make one.  As a result, I find that I’m falling behind in my plan to finish most of the portfolio work two or three weeks before the end of the semester (necessary because I have a number of other important projects on which I’ll need to focus at that point).  Being behind on that, as well as behind on my various other responsibilities, like grading, hasn’t been good for my blood pressure, which my doctors have been pushing me to reduce, as well.  In essence, although it’s happening a bit later than I thought it would, my semester is certainly now spiraling out of control.

That isn’t my big failure, though.

If I’ve messed up on anything this semester, it’s that I’ve not capitalized on the excellent resources that are readily at hand; indeed, if I could change anything about the class so far, I would address the fact that I’ve not yet asked one of my fellow students for help.  There are, of course, a myriad of reasons for this, but none supercede the simple fact that I have yet to reach out to the others who seem to really “get” that particular technology.  My sad attempt at putting together a work group via Twitter didn’t even get off the ground (I’m not aware that I received a single response), so I let it fade into the obscurity of the feed’s past and did nothing to revive the effort later. I could have been light years ahead of where I am now if I had just followed through a bit more there and asked for help again.

This may be a general pattern with the way I run my life; I wouldn’t be the first academic who bit off more than he or she could chew in a semester, nor would I be the first to try and keep things together far beyond the point when it became clear that doing so was not just impossible, attempting to do so was destructive.

Thus, I’m changing my tactics.  Tonight, I post this first “celebrate failure” post along with a tweet that will call, once again, for a study or work group of some sort.  I will list what I’d like to accomplish for myself instead of just vaguely and weakly suggesting we all get together and poke at our computers until they do something interesting.  I’m sure I’m not the only one who has problems that could be better solved by having two or three fresh sets of eyes looking over my code, and I hope that I can be of service helping the rest of the class.