{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 挑戰:分析關於數據科學的文本\n", "\n", "在這個例子中,我們做一個涵蓋傳統數據科學流程所有步驟的簡單練習。你不需要寫任何代碼,只需點擊下面的單元格執行它們並觀察結果。作為挑戰,鼓勵你使用不同的數據嘗試這段代碼。\n", "\n", "## 目標\n", "\n", "在本課程中,我們討論了與數據科學相關的不同概念。讓我們透過做一些文本挖掘來嘗試發現更多相關概念。我們將從一段關於數據科學的文本開始,從中提取關鍵字,然後嘗試將結果視覺化。\n", "\n", "我將使用維基百科上關於數據科學的頁面作為文本:\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "url = 'https://en.wikipedia.org/wiki/Data_science'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第一步:取得數據\n", "\n", "每個數據科學流程的第一步都是取得數據。我們將使用 `requests` 函式庫來完成這個步驟:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import requests\n", "\n", "# Define a custom header.\n", "headers = {\n", " 'User-Agent': 'DataScienceChallenge/1.0 (myemail@gmail.com)'\n", "}\n", "\n", "# Pass the headers into the get request\n", "response = requests.get(url, headers=headers)\n", "\n", "if response.status_code == 200:\n", " text = response.content.decode('utf-8')\n", " print(text[:1000])\n", "else:\n", " print(f\"Error: {response.status_code}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第 2 步:轉換數據\n", "\n", "下一步是將數據轉換成適合處理的形式。在我們的例子中,我們已經從網頁下載了 HTML 原始碼,現在需要將它轉換成純文本。\n", "\n", "這可以用多種方法完成。我們將使用 [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/),一個流行的 Python 解析 HTML 的庫。BeautifulSoup 讓我們能夠定位特定的 HTML 元素,因此我們可以專注於維基百科的主要文章內容,並減少一些導航菜單、側邊欄、頁腳和其他無關的內容(雖然仍可能留有一些樣板文字)。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "首先,我們需要安裝 BeautifulSoup 庫以進行 HTML 解析:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sys\n", "!{sys.executable} -m pip install beautifulsoup4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from bs4 import BeautifulSoup\n", "\n", "# Parse the HTML content\n", "soup = BeautifulSoup(text, 'html.parser')\n", "\n", "# Extract only the main article content from Wikipedia\n", "# Wikipedia uses 'mw-parser-output' class for the main article content\n", "content = soup.find('div', class_='mw-parser-output')\n", "\n", "def clean_wikipedia_content(content_node):\n", " \"\"\"Remove common non-article elements from a Wikipedia content node.\"\"\"\n", " # Strip jump links, navboxes, reference lists/superscripts, edit sections, TOC, sidebars, etc.\n", " selectors = [\n", " '.mw-jump-link',\n", " '.navbox',\n", " '.reflist',\n", " 'sup.reference',\n", " '.mw-editsection',\n", " '.hatnote',\n", " '.metadata',\n", " '.infobox',\n", " '#toc',\n", " '.toc',\n", " '.sidebar',\n", " ]\n", " for selector in selectors:\n", " for el in content_node.select(selector):\n", " el.decompose()\n", "\n", "if content:\n", " # Clean the content node to better approximate article text only.\n", " clean_wikipedia_content(content)\n", " text = content.get_text(separator=' ', strip=True)\n", " print(text[:1000])\n", "else:\n", " print(\"Could not find main content. Using full page text.\")\n", " text = soup.get_text(separator=' ', strip=True)\n", " print(text[:1000])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第 3 步:獲取見解\n", "\n", "最重要的一步是將我們的數據轉換成某種格式,從中提取見解。在我們的案例中,我們想從文本中提取關鍵詞,並了解哪些關鍵詞更有意義。\n", "\n", "我們將使用名為 [RAKE](https://github.com/aneesha/RAKE) 的 Python 函式庫進行關鍵詞提取。首先,讓我們安裝此函式庫,以防尚未安裝: \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sys\n", "!{sys.executable} -m pip install nlp_rake" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "主要功能由 `Rake` 物件提供,我們可以使用一些參數來自訂。以我們的例子,我們會設定關鍵字的最小長度為5個字元,文件中關鍵字的最小出現頻率為3,以及關鍵字中最多的字數為2。隨意嘗試其他值並觀察結果。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import nlp_rake\n", "extractor = nlp_rake.Rake(max_words=2,min_freq=3,min_chars=5)\n", "res = extractor.apply(text)\n", "res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "我們獲得了一個詞彙列表以及相關的重要程度。如你所見,最相關的學科,如機器學習和大數據,在列表中位於頂部位置。\n", "\n", "## 步驟4:結果視覺化\n", "\n", "人們能夠以視覺形式最佳解讀數據。因此,通常將數據視覺化以獲取一些洞見是合理的。我們可以使用 Python 中的 `matplotlib` 庫繪製關鍵詞及其相關性的簡單分佈圖:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "def plot(pair_list):\n", " k,v = zip(*pair_list)\n", " plt.bar(range(len(k)),v)\n", " plt.xticks(range(len(k)),k,rotation='vertical')\n", " plt.show()\n", "\n", "plot(res)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "不過,有一個更好的方法去視覺化字詞頻率 —— 使用 詞雲。我們需要安裝另一個庫,來從我們的關鍵字列表繪製詞雲。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!{sys.executable} -m pip install wordcloud" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`WordCloud` 物件負責接收原始文字或預先計算好的字詞及其頻率列表,並回傳一張圖片,該圖片隨後可以使用 `matplotlib` 顯示:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from wordcloud import WordCloud\n", "import matplotlib.pyplot as plt\n", "\n", "wc = WordCloud(background_color='white',width=800,height=600)\n", "plt.figure(figsize=(15,7))\n", "plt.imshow(wc.generate_from_frequencies({ k:v for k,v in res }))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "我們也可以將原始文字傳給 `WordCloud` - 讓我們看看是否能獲得相似的結果:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.figure(figsize=(15,7))\n", "plt.imshow(wc.generate(text))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "wc.generate(text).to_file('images/ds_wordcloud.png')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "你可以看到那個詞雲現在看起來更有氣勢,但它也包含了很多噪音(例如無關的詞如 `Retrieved on`)。此外,我們獲得的由兩個字組成的關鍵字較少,比如 *data scientist* 或 *computer science*。這是因為 RAKE 演算法在從文本中選擇好的關鍵字方面效果更佳。這個例子說明了數據預處理和清理的重要性,因為最後清晰的圖像將允許我們做出更好的決策。\n", "\n", "在這個練習中,我們通過一個簡單的流程從維基百科文本中提取一些意義,以關鍵字和詞雲的形式呈現。這個例子相當簡單,但它很好地展示了數據科學家在處理數據時通常會採取的所有步驟,從數據獲取一直到視覺化。\n", "\n", "在我們的課程中,我們會詳細討論所有這些步驟。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n\n\n**免責聲明**:\n本文件由 AI 翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 翻譯而成。雖然我們致力於確保準確性,但請注意,機器自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於重要資訊,建議進行專業人工翻譯。我們不對因使用本翻譯而產生的任何誤解或誤釋承擔責任。\n\n" ] } ], "metadata": { "interpreter": { "hash": "c28e7b6bf4e5b397b8288a85bf0a94ea8d3585ce2b01919feb195678ec71581b" }, "kernelspec": { "display_name": "Python 3.8.11 64-bit ('base': conda)", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.11" } }, "nbformat": 4, "nbformat_minor": 2 }