Learning Objectives
- 說出資料分析的五個步驟:問題、資料、整理、分析、溝通
- 看一份資料表時,先說出「一列代表什麼」(觀察單位)
- 把欄位分成類別、順序、數值(離散、連續)資料
- 依資料型態判斷能算什麼:學號不能算平均,順序資料用中位數比較穩當
從一個問題開始
「住宿的同學每週讀書時數比較多嗎?」「哪一門課最難?」「天氣熱的時候宿舍用電多多少?」 這些都是可以用資料回答的問題。資料分析不是先打開一份檔案、把所有能算的都算一遍,而是從問題出發,走過五個步驟:
| 步驟 | 要做的事 | 以「住宿生讀書時數」為例 |
|---|---|---|
| 問題 | 把想知道的事寫成可以用資料回答的問題 | 住宿與不住宿的同學,每週讀書時數的中位數差多少? |
| 資料 | 找到或蒐集資料,弄清楚每一欄是什麼意思、怎麼來的 | 學生資料:是否住宿、每週讀書時數 |
| 整理 | 讀進來、檢查缺值與錯誤、統一寫法、合併 | 讀書時數有沒有負數或空白? |
| 分析 | 分組計算、畫圖、做統計檢定 | 依是否住宿分組,算中位數並畫箱形圖 |
| 溝通 | 用圖、表與文字說明發現與限制 | 「在這份資料裡……;這是觀察資料,不能說住宿造成讀書時數改變」 |
實際做的時候常常會來回:整理時發現資料不夠回答原本的問題,就回頭修改問題或找更多資料。
這門課的 24 課大致照這個順序:第 2~4 課認識 NumPy 與 pandas 的基本物件,第 5~12 課整理資料(選取、缺值、清理、分組、合併、時間), 第 13~14 課畫圖,第 15~22 課統計,第 23 課寫報告,最後一課用宿舍用電資料從頭做一次。
這門課用的資料
這門課的資料都是程式產生的模擬資料,內容是虛構的校園情境,不是任何學校的真實資料。 用模擬資料的好處是:每個人拿到的資料都一樣、沒有個人隱私的問題,而且資料裡刻意放進了一些要學會處理的現象(缺值、髒資料、對不到的鍵)。 也因為是模擬的,從這些資料算出來的結果不能拿來推論真實世界。
| 檔案 | 列數 | 一列代表 | 主要欄位 |
|---|---|---|---|
students.csv |
200 | 一位學生 | 系所、年級、是否住宿、每週讀書與睡眠時數、是否打工、通勤分鐘 |
grades.csv |
600 | 一位學生修的一門課 | 學號、課程、期中、期末、缺席次數 |
grades_raw.csv |
63 | 一位學生修的一門課(人工輸入、還沒清理) | 同上,外加系所與繳交日期 |
weather.csv |
122 | 一天 | 日期、最高與最低氣溫、雨量、濕度 |
dorm_power.csv |
610 | 一棟宿舍的一天 | 日期、棟別、用電度數、住宿人數 |
clubs.csv |
10 | 一個社團 | 社團代號、名稱、類別、成立年 |
memberships.csv |
258 | 一位學生參加的一個社團 | 學號、社團代號、職務、加入日期 |
teaching_trial.csv |
180 | 一位參加教學法試驗的學生 | 教學法、前測、後測、滿意度、AI 使用頻率 |
檔案是 CSV(逗號分隔的純文字),第一列是欄名。下面先用 pandas 把其中兩份讀進來看看;read_csv、head 這些用法第 4 課會仔細介紹,這裡只要看懂結果。
逐步看:讀進兩份資料,一列各代表什麼
注意右邊記憶體區的資料表,以及兩份資料的列數:同樣是學生,grades 的列數是 students 的三倍。
先問:一列代表什麼?
拿到一份資料表,第一個要回答的問題是「一列代表什麼」,也就是這份資料的觀察單位(unit of observation)。
students.csv:一列=一位學生,數列數就是人數。grades.csv:一列=一位學生修的一門課。數列數得到的是「修課人次」,不是人數;直接對整欄期末成績算平均,是「每一筆修課」的平均,修比較多課的人份量比較重。dorm_power.csv:一列=一棟宿舍的一天,所以同一天會有 5 列。
觀察單位弄錯,後面的計算全部都會錯,而且程式不會報錯。寫報告時也要寫清楚,例如「600 筆修課紀錄,來自 200 位學生」。
類別、順序、數值:決定能算什麼
每一欄的值是哪一種資料型態,決定了哪些計算有意義:
| 資料型態 | 特徵 | 例子 | 有意義的計算 |
|---|---|---|---|
| 類別(nominal) | 分成幾類,沒有先後 | 系所、是否住宿、學號 | 各類的次數、比例、眾數 |
| 順序(ordinal) | 有先後,但等級之間不一定等距 | 滿意度 1~5、AI 使用頻率(不用、偶爾、常用) | 再加上排序、中位數、四分位數 |
| 數值:離散(discrete) | 用數的,只有整數 | 缺席次數、修課數 | 再加上平均、標準差、加減 |
| 數值:連續(continuous) | 用量的,可以有小數 | 身高、讀書時數、通勤時間 | 同上 |
兩個容易出錯的地方:
- 寫成數字的不一定是數值資料。學號、郵遞區號、把系所編成 1~6 的代碼,都只是名稱。電腦會很樂意幫你算出「平均學號」,但這個數字沒有任何意義。
- 順序資料算平均要小心。滿意度從 1 到 2 和從 4 到 5,不一定是一樣的差距。實務上常常還是會算平均,但描述時最好同時列出中位數與各等級的人數。
有些欄位可以有兩種看法,例如年級可以當順序,也可以當離散的數值。重點是想清楚這一欄的值代表什麼。
逐步看:不同型態的欄位,用不同的方法描述
同一份 students.csv,對類別欄數次數、對順序欄排序後數次數並找中位數、對數值欄算平均。
實作:教學法試驗的資料
teaching_trial.csv 是一份模擬的教學法試驗資料,一列是一位學生。請印出三樣東西:
- 列數,格式是
列數:後面接數字(用print("列數:", ...)) ai_use(AI 使用頻率,順序資料)各類別的人數,用value_counts()- 滿意度
satisfaction(1~5,順序資料)的中位數,格式是print("滿意度的中位數:", ...)
小測驗:流程、觀察單位與資料型態
下面哪一個是資料分析比較合理的順序?
grades.csv 的一列代表什麼?
下面哪一欄是順序資料?
某份資料把系所編成 1~6 的代碼,有人算出「系所平均 3.4」。這個數字代表什麼?
下面程式會印出什麼?
import pandas as pd
df = pd.DataFrame({"id": ["S1", "S1", "S2", "S3", "S3"],
"course": ["微積分", "英文", "英文", "微積分", "統計學"]})
print(len(df), df["id"].nunique())
重點整理
- 資料分析從問題開始,經過資料、整理、分析,最後溝通發現與限制;過程中常常要回頭修改。
- 這門課的資料都是程式產生的模擬資料,不是真實資料,結果不能推論真實世界。
- 看一份資料表,先說出「一列代表什麼」:
grades.csv的一列是一位學生修的一門課,數人數要數不同的學號。 - 資料型態分成類別、順序、數值(離散、連續)。寫成數字的不一定能算平均(學號、代碼);順序資料用中位數與各等級人數描述比較穩當。
- 下一課介紹 NumPy 陣列:pandas 底下的計算都靠它,一行就能對一整串數字做同樣的運算。