本文介紹一個將911襲擊及后續影響相關新聞文章的主題可視化的項目。我將介紹我的出發點,實現的技術細節和我對一些結果的思考。
簡介
近代美國歷史上再沒有比911襲擊影響更深遠的事件了,它的影響在未來還會持續。從事件發生到現在,成千上萬主題各異的文章付梓。我們怎樣能利用數據科學的工具來探索這些主題,并且追蹤它們隨著時間的變化呢?
靈感
首先提出這個問題的是一家叫做Local Projects的公司,有人委任它們為紐約的國家911博物館設置一個展覽。他們的展覽,Timescape,將事件的主題和文章可視化之后投影到博物館的一面墻上。不幸的是,由于考慮到官僚主義的干預和現代人的三分鐘熱度,這個展覽只能展現很多主題,快速循環播放。Timescape的設計給了我啟發,但是我想試著更深入、更有交互性,讓每個能接入互聯網的人都能在空閑時觀看。
這個問題的關鍵是怎么講故事。每篇文章都有不同的講故事角度,但是有線索通過詞句將它們聯系到一起?!監sama bin Laden”、 “Guantanamo Bay”、”Freedom”,還有更多詞匯組成了我模型的磚瓦。
獲取數據
所有來源當中,沒有一個比紐約時報更適合講述911的故事了。他們還有一個神奇的API,允許在數據庫中查詢關于某一主題的全部文章。我用這個API和其他一些Python網絡爬蟲以及NLP工具構建了我的數據集。
爬取過程是如下這樣的:
調用API查詢新聞的元數據,包括每篇文章的URL。 給每個URL發送GET請求,找到HTML中的正文文本,提取出來。 清理文章文本,去除停用詞和標點我寫了一個Python腳本自動做這些事,并能夠構建一個有成千上萬文章的數據集。也許這個過程中最有挑戰性的部分是寫一個從HTML文檔里提取正文的函數。近幾十年來,紐約時報不時也更改了他們HTML文檔的結構,所以這個抽取函數取決于笨重的嵌套條件語句:
# s is a BeautifulSoup object containing the HTML of the pageif s.find('p', {'itemprop': 'articleBody'}) is not None: paragraphs = s.findAll('p', {'itemprop': 'articleBody'}) story = ' '.join([p.text for p in paragraphs])elif s.find('nyt_text'): story = s.find('nyt_text').textelif s.find('div', {'id': 'mod-a-body-first-para'}): story = s.find('div', {'id': 'mod-a-body-first-para'}).text story += s.find('div', {'id': 'mod-a-body-after-first-para'}).textelse: if s.find('p', {'class': 'story-body-text'}) is not None: paragraphs = s.findAll('p', {'class': 'story-body-text'}) story = ' '.join([p.text for p in paragraphs]) else: story = ''
新聞熱點
疑難解答