108 年 國立臺灣大學新聞學研究所《資訊科學與新聞》
第 1 題
假設現在你收到數萬則PTT 的貼文資料與該貼文的回文資料如下。請:
(1) 設計一內含多個表格的關聯式資料庫(以 E-R Diagram 來描繪)紀錄下述資料。其次,說明你如何利用正規化的技術來降低資料的重複性 (Redundancy)? 又如何利用 primary key 與 foreign key 來確保資料的完整性?
(2) 此時,你打算建立網民的 Profile 來偵測其實否為網軍,當你要查詢所有資料中的個體分別有貼文過多少次、回文過多少次、曾經出現在多少個 ID 時,就你前述的資料表設計,你要如何設計 SQL? 而你認為這樣的網軍定義是否適切?為什麼?
(15%+15%)
(題幹附有 PTT 貼文與回文的範例文字,內容如下)
作者 x09xxx13 (x09xxx13) 看板 Gossiping
標題[問卦] 請問這是什麼機器
時間 Fri Jan 11 15:54:41 2018
各位週末下午不想上班的宅宅好宅宅我啊 昨天路上看到一台很詭異的機器請問有人看過嗎
-- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.111.147.208 ※ 文章網址:
https://www.ptt.cc/bbs/Gossiping/M.1547111112.A.FB6.html
→ hsnxxxxxxn:這世界上只有10種人懂二進位的和不懂二進位的 10/27 00:13
-- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.124.73.41 ※ 文章網址:
https://www.ptt.cc/bbs/Gossiping/M.1547283914.A.39A.html
噓 hate0504:五樓知道 01/11 15:55
推 okbong1: hate0504 的數學老師XDDDDDDDDDDDDDDDDDDDDDDDD 01/11 15:55
登入後即可作答並保存紀錄。
本題主要考察資料庫設計、正規化、SQL 查詢以及對「網軍」定義的批判性思考能力。
(1) 關聯式資料庫設計、正規化與鍵的應用
核心觀念: 關聯式資料庫的設計需要將實體(如使用者、文章、回文)及其關係(如使用者發布文章、文章包含回文)抽象化成表格,並透過正規化減少資料冗餘、提升資料一致性,同時利用主鍵(primary key)與外鍵(foreign key)確保資料的關聯與完整性。
資料庫設計(E-R Diagram):
我們可以設計以下三個主要的表格:
-
Users (使用者)
user_id(Primary Key, e.g., INT, AUTO_INCREMENT) - 使用者唯一識別碼username(VARCHAR) - 使用者名稱 (若有)first_seen_ip(VARCHAR) - 第一次出現的 IP 位址 (用於初步偵測)registration_date(DATETIME) - 註冊日期 (若有)- ... 其他使用者相關資訊
-
Posts (文章)
post_id(Primary Key, e.g., INT, AUTO_INCREMENT) - 文章唯一識別碼author_id(Foreign Key references Users.user_id) - 作者 IDboard(VARCHAR) - 看板名稱 (e.g., "Gossiping")title(VARCHAR) - 文章標題content(TEXT) - 文章內容post_timestamp(DATETIME) - 發文時間ip_address(VARCHAR) - 發文 IP 位址url(VARCHAR) - 文章 URL
-
Comments (回文)
comment_id(Primary Key, e.g., INT, AUTO_INCREMENT) - 回文唯一識別碼post_id(Foreign Key references Posts.post_id) - 所屬文章 IDauthor_id(Foreign Key references Users.user_id) - 回文作者 IDcontent(TEXT) - 回文內容comment_timestamp(DATETIME) - 回文時間ip_address(VARCHAR) - 發文 IP 位址
E-R Diagram 示意(文字描述):
Users 1 -- * Posts (一個使用者可以有多篇文章)
Posts 1 -- * Comments (一篇文章可以有多則回文)
Users 1 -- * Comments (一個使用者可以有多則回文)
正規化(Normalization)以降低資料重複性:
正規化是將資料庫結構化,以減少資料冗餘和提高資料完整性的過程。常見的正規化形式有第一正規化 (1NF)、第二正規化 (2NF)、第三正規化 (3NF) 等。
- 1NF: 確保每個欄位都是原子性的(不可再分割),且沒有重複的欄位組。在上述設計中,每個欄位都符合原子性,且表格結構也符合 1NF。
- 2NF: 在 1NF 的基礎上,消除部分函數依賴。例如,如果我們有一個表格包含文章標題和作者姓名,而作者姓名只依賴於作者 ID,則應將作者姓名移到 Users 表格。在我們的設計中,
Posts表格的title、content、post_timestamp等都完全依賴於post_id(主鍵),而author_id則依賴於post_id。Comments表格同理。Users表格的資訊也只依賴於user_id。因此,我們的設計已基本符合 2NF。 - 3NF: 在 2NF 的基礎上,消除傳遞函數依賴。例如,如果
Post A的屬性(如作者姓名)依賴於Post B的屬性(如作者 ID),而Post B的屬性又依賴於Post A的主鍵,則需要調整。在我們的設計中,Posts表格中的board、title、content、post_timestamp、ip_address、url都直接依賴於post_id。author_id依賴於post_id,但它指向另一個實體Users。Comments表格同理。Users表格的資訊(如username,first_seen_ip)都直接依賴於user_id。這樣的分離有助於減少重複。例如,如果同一個使用者發布多篇文章,其使用者名稱 (username) 只需在Users表格中儲存一次。
利用 Primary Key 與 Foreign Key 確保資料完整性:
- Primary Key (主鍵): 每個表格都應有一個主鍵(如
user_id,post_id,comment_id),它能唯一識別表格中的每一筆記錄。主鍵的值不能為 NULL,且必須是唯一的。這確保了我們能夠準確地存取和管理每一筆資料。 - Foreign Key (外鍵): 外鍵用於建立表格之間的關聯。例如,
Posts表格中的author_id是Users表格的user_id的外鍵。當我們設定外鍵約束時,資料庫系統會強制執行以下規則:- Referential Integrity (參照完整性): 外鍵的值必須存在於其參照的主鍵欄位中,或為 NULL(如果允許)。這意味著,我們不能創建一個文章,其作者 ID 在
Users表格中不存在。反之,在刪除Users表格中的使用者時,資料庫可以設定為級聯刪除其發布的文章和回文,或者阻止刪除,以防止出現「孤兒」記錄。 - 關聯性: 外鍵使得我們可以輕鬆地連接不同表格的資料。例如,要查找某個使用者發布的所有文章,我們可以透過
Users.user_id連接Posts.author_id來實現。
- Referential Integrity (參照完整性): 外鍵的值必須存在於其參照的主鍵欄位中,或為 NULL(如果允許)。這意味著,我們不能創建一個文章,其作者 ID 在
總結:
透過將 PTT 的貼文與回文資訊分解到 Users、Posts、Comments 三個表格,並進行正規化(至少到 3NF),我們能有效減少重複儲存,如同一位使用者發布多篇貼文,其帳號資訊(如 username)只需儲存一次。主鍵確保了每筆記錄的唯一性,而外鍵則確保了使用者、文章、回文之間的關聯是有效的,例如,不能有文章指向一個不存在的使用者。
(2) 網民 Profile 設計與 SQL 查詢,以及網軍定義的評估
核心觀念: 建立使用者行為分析模型,並利用 SQL 進行資料提取。同時,需批判性地分析所提出的網軍定義的有效性與局限性。
網民 Profile 設計:
基於上述資料庫設計,我們可以為每個使用者(Users 表格中的每一行)建立一個 Profile,其中包含其行為的統計數據。這些數據可以從 Posts 和 Comments 表格中聚合計算得出。
SQL 查詢以獲取 Profile 數據:
假設我們想查詢某個使用者(例如 user_id = 123)的貼文次數、回文次數,以及其曾經出現過的 ID 數量。
-
貼文次數 (Post Count):
SELECT COUNT(p.post_id) FROM Posts p WHERE p.author_id = 123; -
回文次數 (Comment Count):
SELECT COUNT(c.comment_id) FROM Comments c WHERE c.author_id = 123;
第 2 題
網路上的新聞經常在刊出後會被新聞編輯從後台再次修改,比如傷亡人數更新,或者因為被網友抗議而修改其一些標題或內容。無論新聞編輯的動機為何,顯然在不同時間所看到的網路新聞標題或內文可能是不一樣的。你現在被要求設計一個爬蟲程式,想大量抓取新聞資料來偵測標題或內容在上線後被更動的情形,請問:
(1) 你計畫如何儲存該資料,以便於你在日後能夠比較有哪些新聞標題曾經被修改過?這些資料筆數可能相當龐大,爬蟲也要爬很久,請考慮時間、空間與計算複雜度等因素,試問,你打算用哪種檔案或資料庫儲存之?為什麼?
(2) 就你所選的格式,你會設計哪些資料欄位來便於你後續比較新聞的差異?
(3) 在你這樣的設計架構下,你今天要寫一個函式比較某一則新聞的不同版本有哪些差異字時,你所設計的演算法為何?計算複雜度為何?
(15%+15%)
登入後即可作答並保存紀錄。
本題主要考察網路爬蟲資料儲存、欄位設計、以及版本差異比對演算法的設計與複雜度分析。
(1) 資料儲存格式的選擇與考量
核心觀念: 針對大量、結構化(或半結構化)且需要版本比對的新聞資料,需要選擇一個能夠有效儲存、快速檢索、支援版本管理,並能處理高數據量的儲存方案。
考量因素:
- 資料量龐大: 數萬則新聞,加上多次版本更新,資料量會非常可觀。
- 資料結構: 新聞資料包含標題、內容、發布時間、來源等,具有一定的結構性。
- 版本比對需求: 需要儲存同一新聞的不同版本,並能高效比對差異。
- 讀寫頻率: 爬蟲需要頻繁寫入新資料,而分析時需要頻繁讀取和比對。
- 時間、空間、計算複雜度: 選擇的方案需兼顧效率。
儲存方案選擇:
-
選項一:關聯式資料庫 (Relational Database, RDB)
- 優點: 結構化儲存,支援 SQL 查詢,資料一致性高,適合處理結構化資料,具備 ACID 特性。可以設計表格來儲存新聞的不同版本。
- 缺點: 對於極大規模的資料量,擴展性可能面臨挑戰(垂直擴展成本高,水平擴展較複雜)。版本比對的複雜查詢可能影響效能。
-
選項二:NoSQL 資料庫 (例如 Document Database 如 MongoDB, Key-Value Store 如 Redis, Columnar Database 如 Cassandra)
- Document Database (如 MongoDB): 每個新聞版本可以儲存為一個文件。
- 優點: 靈活的 schema,易於儲存半結構化資料,水平擴展性好,適合處理不斷變化的資料結構。可以將同一新聞的所有版本關聯起來。
- 缺點: 相較於 RDB,資料一致性可能較弱(視具體設計)。複雜的跨文件(或跨集合)查詢可能不如 RDB 方便。
- Columnar Database (如 Cassandra): 適合寫入密集型應用,擅長處理大量數據,水平擴展性極佳。
- 優點: 高寫入吞吐量,良好的擴展性,適用於海量數據。
- 缺點: 查詢靈活性相對較差,不適合頻繁進行複雜的 JOIN 或聚合操作。
- Document Database (如 MongoDB): 每個新聞版本可以儲存為一個文件。
-
選項三:檔案系統 + 索引 (File System + Indexing)
- 優點: 儲存成本低,靈活性高。可以將每個新聞版本儲存在一個文件中(如 JSON, XML),並使用搜尋引擎(如 Elasticsearch, Solr)建立索引,以實現快速搜尋和版本比對。
- 缺點: 需要自行管理資料的一致性、備份、容錯等。
推薦方案:
綜合考量,我會推薦使用關聯式資料庫 (RDB),並進行優化,或者結合文件資料庫 (Document Database) 如 MongoDB。
-
理由 (選擇 RDB):
- 結構化查詢: 雖然新聞內容不完全結構化,但標題、發布時間、來源、URL 等核心資訊是結構化的。RDB 的 SQL 語句非常適合進行精確的查詢和篩選(例如,查找特定 URL 在不同時間的版本)。
- 版本管理: 可以設計一個
Articles表格存放新聞的基礎資訊(如 URL, 初始標題),再設計一個ArticleVersions表格來儲存每一個版本(包含時間戳、標題、內容、作者等)。 - 資料一致性: RDB 的 ACID 特性有助於確保資料儲存的可靠性。
- 現有技術成熟: 大部分團隊對 RDB 較為熟悉。
-
理由 (選擇 MongoDB):
- 彈性 Schema: 網路上新聞的欄位可能隨時間變化,MongoDB 的 Schema-less 設計更易於適應。
- 水平擴展: 對於海量數據和爬蟲的持續寫入,MongoDB 的水平擴展能力更強。
- 文件儲存: 可以將同一新聞的所有版本儲存在一個文件中,或使用 collections 進行管理,方便關聯。
在此,我選擇以關聯式資料庫 (RDB) 的思路來闡述,因為其結構化查詢和關聯性處理更符合「比較差異」的需求。
(2) 資料欄位設計
基於關聯式資料庫的設計思路,我會設計至少兩個核心表格:Articles(新聞主表)和 ArticleVersions(新聞版本記錄表)。
-
Articles 表格: 存放新聞的唯一識別資訊,確保每個新聞實體只出現一次。
article_id(Primary Key, INT, AUTO_INCREMENT): 新聞的唯一識別碼。url(VARCHAR, UNIQUE): 新聞的原始 URL,作為新聞的唯一標識(雖然 URL 可能變化,但通常初始 URL 是固定的,或者可以設計一個「canonical URL」)。source(VARCHAR): 新聞來源(例如:中央社, 聯合報)。first_seen_timestamp(DATETIME): 爬蟲第一次爬到該新聞的時間。last_seen_timestamp(DATETIME): 爬蟲最近一次爬到該新聞的時間。title_hash(VARCHAR, optional): 記錄初始標題的雜湊值,用於快速判斷標題是否變動。
-
ArticleVersions 表格: 記錄同一新聞的每一個版本。
version_id(Primary Key, INT, AUTO_INCREMENT): 版本記錄的唯一識別碼。article_id(Foreign Key references Articles.article_id): 指向新聞主表,表示這是哪個新聞的版本。version_timestamp(DATETIME): 該版本內容被爬蟲抓取到的時間戳,這是區分不同版本的重要依據。title(VARCHAR): 新聞標題。content(TEXT): 新聞內容。title_snapshot_hash(VARCHAR, optional): 記錄此版本標題的雜湊值,方便與其他版本標題快速比對。content_snapshot_hash(VARCHAR, optional): 記錄此版本內容的雜湊值,方便與其他版本內容快速比對。ip_address(VARCHAR, optional): 爬蟲抓取時的 IP 位址(如果爬蟲部署在多個節點)。
欄位說明與考量:
article_id和url:article_id作為主鍵,url作為唯一識別符,確保我們能準確定位到同一則新聞。version_timestamp: 這是區分不同版本的核心欄位。爬蟲每次抓取到同一 URL 的內容時,都會記錄下抓取時間,並將其視為一個新版本。title和content: 儲存實際的標題和內容。*_snapshot_hash(雜湊值): 為了快速判斷兩個版本之間是否有差異,可以計算標題和內容的雜湊值(如 MD5, SHA-256)。若雜湊值不同,則表示內容必定有變動。這比直接比較字串要快得多,尤其是在處理大量數據時。ip_address: 如果爬蟲部署在多個節點,記錄 IP 有助於追蹤爬蟲的來源。
(3) 版本差異比對函式與計算複雜度
核心觀念: 比較兩個文本版本之間的差異,本質上是尋找兩個字串(或字元序列)之間的編輯距離(Edit Distance)或差異點。
第 3 題
請問你過去印象最深刻的一則資料新聞報導為何?他可能運用到哪些資料或技術?你認為資料可能包含哪些欄位?
(10%)
登入後即可作答並保存紀錄。
本題為開放性問題,旨在考察考生對「資料新聞」(Data Journalism)的理解、實際案例的記憶與分析能力,以及對新聞中數據元素的敏感度。沒有標準答案,但好的回答應展現對資料新聞的掌握。
解題思路:
- 選擇案例: 回憶一個你印象深刻的、使用了數據分析或視覺化的新聞報導。這可以是國內外任何媒體發布的。選擇一個你相對熟悉其內容和技術的案例會更容易深入分析。
- 描述案例: 簡述該新聞報導的主題、核心發現或想傳達的訊息。
- 分析所用資料: 說明該報導使用了哪些數據。這些數據的來源是什麼?是政府公開數據、商業數據、使用者生成數據,還是自行收集的數據?數據的類型是什麼(例如:人口統計數據、經濟指標、氣象數據、地理空間數據、社群媒體數據等)?
- 分析所用技術: 該報導運用了哪些技術來處理、分析或呈現這些數據?
- 資料處理/分析技術: 如資料清洗、統計分析、數據挖掘、機器學習模型(如預測模型、分類模型)、地理資訊系統 (GIS) 分析等。
- 數據視覺化技術: 如製作互動式圖表(長條圖、折線圖、圓餅圖、散佈圖)、地圖視覺化(熱力圖、點圖層)、資訊圖表 (Infographics)、動畫視覺化等。
- 程式語言/工具: 如 Python (Pandas, NumPy, Matplotlib, Seaborn, Scikit-learn), R, JavaScript (D3.js, Chart.js), Tableau, Excel 等。
- 推測資料欄位: 根據報導的內容和所用的數據,推測原始數據可能包含哪些欄位。例如,如果是關於房價的報導,欄位可能包括:地區、房屋類型、坪數、屋齡、成交價格、成交日期、樓層、社區名稱等。
- 點評與總結: 簡述該報導的優點,以及為何它讓你印象深刻。
範例回答(僅供參考,需自行替換為具體案例):
案例: 《紐約時報》關於 COVID-19 疫情發展的追蹤報導(例如:2020 年初至 2022 年的每日確診、死亡、疫苗接種等數據的持續更新與視覺化)。
描述:
這系列報導透過持續更新的數據,清晰地呈現了全球及美國各州 COVID-19 疫情的演變趨勢、對醫療系統的影響、疫苗接種的進展與成效。它不僅提供了事實,更透過數據讓讀者理解疫情的嚴重性、傳播模式以及防疫措施的有效性。
所用資料:
- 政府公開數據: 主要來自各國衛生部、疾病管制中心 (CDC) 等官方機構發布的疫情統計數據(確診數、死亡數、檢測數、住院數、加護病房佔用率、疫苗接種劑量、接種人口比例等)。
- 研究機構報告: 引用學術機構和流行病學家的研究成果。
第 4 題
你現在設計好了一則資料新聞,你希望能夠知道使用者的閱覽行為,我們可以把它稱為使用者評估或者使用者經驗評估。請問,如果是你,你知道有哪些方式可以紀錄、調查各種類型的使用者經驗。除描述方法之外,請對其優點與限制進行簡略說明。
(15%)
登入後即可作答並保存紀錄。
本題考察考生對於「使用者經驗評估」(User Experience Evaluation, UX Evaluation)方法的理解與應用能力,特別是在資料新聞(Data Journalism)情境下。
核心觀念:
使用者經驗評估是為了了解使用者如何與產品(在此為資料新聞報導)互動,並從中獲取回饋,以改進產品。資料新聞的評估尤其關注使用者能否理解複雜數據、是否被視覺化吸引、是否能從中獲取資訊、以及整體閱讀體驗。
使用者經驗評估方法:
以下列出幾種常見的方法,並說明其優點與限制:
-
使用者測試 (User Testing / Usability Testing)
- 描述: 邀請目標使用者在受控的環境下(實驗室或遠端),完成一系列預設的任務(例如:找到某個數據、理解圖表的趨勢、分享報導)。觀察他們的行為、聆聽他們的口頭回饋(Think-aloud protocol),並記錄他們遇到的困難。
- 優點:
- 直接觀察: 能直接看到使用者如何互動,發現他們未說出口的問題。
- 深入了解: 「Think-aloud」方法能深入了解使用者的思考過程、困惑點和動機。
- 發現潛在問題: 能找出設計上的可用性問題。
- 限制:
- 成本較高: 需要招募參與者、安排時間、設置場地,且通常時間較長。
- 實驗室效應: 在實驗室環境中,參與者可能因為知道被觀察而表現不同(Hawthorne effect)。
- 參與者代表性: 難以確保招募到的參與者能完全代表所有目標使用者。
- 任務設計: 任務設計的合理性直接影響測試結果。
-
問卷調查 (Surveys / Questionnaires)
- 描述: 設計一系列結構化或半結構化的問題,讓大量使用者填寫。問題可以涵蓋滿意度、易用性、內容理解度、資訊獲取效率、視覺化吸引力等方面。常用的有李克特量表 (Likert Scale) 問題。
- 優點:
- 量化數據: 能夠快速收集大量量化數據,便於進行統計分析,了解整體使用者群體的意見。
- 成本較低: 相較於使用者測試,成本較低,可擴展性強。
- 廣泛觸及: 可以透過線上連結、電子郵件等方式大規模發放。
- 限制:
- 淺層資訊: 難以深入了解使用者行為背後的原因。
- 設計偏差: 問題的措辭、順序可能影響回答。
- 參與者偏差: 回答者可能不是隨機樣本,而是特別熱情或特別不滿的使用者。
- 回覆率: 線上問卷的回覆率通常不高。
-
使用者訪談 (User Interviews)
- 描述: 與個別使用者進行一對一的深入對話,了解他們對資料新聞的看法、使用習慣、需求,以及對特定報導的感受。訪談可以是結構化、半結構化或非結構化的。
- 優點:
- 深度洞察: 能獲取非常深入、細膩的使用者回饋和故事。
- 靈活性: 可以根據訪談對象的回答,隨時調整問題,深入挖掘關鍵點。
- 建立連結: 能夠與使用者建立更深入的理解。
- 限制:
- 耗時耗力: 進行大量訪談需要投入大量時間和人力。
- 數據難以量化: 訪談結果多為質性數據,分析和總結較為主觀。
- 訪談者技巧: 訪談結果很大程度上依賴於訪談者的技巧。
- 參與者代表性: 少量訪談者可能無法代表整體。
-
日誌研究 (Diary Studies)
- 描述: 要求使用者在一段時間內(數天、數週),定期記錄他們在使用資料新聞時的經驗、感受、遇到的問題或突發的洞察。
- 優點:
第 5 題
排序:現有一資料如下,請你用一種你熟悉的程式語言,直接把該筆資料用你認為適合的變數型態/資料結構打在程式碼內,並指向一個變數。請簡單設計一個排序函式,可以根據某一欄進行排序所有的資料,例如根據從小到大的 M96 數值調換資料列的先後順序。
(15%)
| country | M95 | M96 | M97 |
|---|---|---|---|
| Albania | 5 | 5 | 5 |
| Algeria | 3 | 3 | 3 |
| Argentina | 2 | 2 | 2 |
登入後即可作答並保存紀錄。
核心觀念
本題考查:
- 表格資料如何表示為程式中的資料結構。
- 如何以欄位名稱取得每筆資料的欄位值。
- 排序函式的設計。
- 排序演算法的時間與空間複雜度。
適合的資料結構是「由字典組成的串列」:
- 每一筆資料使用一個字典表示。
- 欄位名稱作為字典的鍵,例如
country、M95、M96、M97。 - 所有資料列放入串列中。
- 以某個欄位的數值作為排序依據。
解題方法
使用 Python 將資料表示如下:
data = [
{"country": "Albania", "M95": 5, "M96": 5, "M97": 5},
{"country": "Algeria", "M95": 3, "M96": 3, "M97": 3},
{"country": "Argentina", "M95": 2, "M96": 2, "M97": 2}
]
設計排序函式,接收三個參數:
rows:原始資料。column:要排序的欄位名稱。reverse:是否採用遞減排序,預設為遞增排序。
def sort_by_column(rows, column, reverse=False):
return sorted(rows, key=lambda row: row[column], reverse=reverse)
其中:
row[column]
代表取得目前資料列中指定欄位的值。例如:
row["M96"]
會取得該筆資料的 M96 數值。
依照 M96 從小到大排序:
sorted_data = sort_by_column(data, "M96")
for row in sorted_data:
print(row)
排序結果為:
[
{"country": "Argentina", "M95": 2, "M96": 2, "M97": 2},
{"country": "Algeria", "M95": 3, "M96": 3, "M97": 3},
{"country": "Albania", "M95": 5, "M96": 5, "M97": 5}
]
因為原始的 M96 值依序為:
排序後變成:
因此資料列順序為:
若要依照 M96 從大到小排序,只需設定:
sorted_data = sort_by_column(data, "M96", reverse=True)