AI 診斷與推薦系統資料探勘的辛酸血淚

專案計劃

為什麼現在機器學習和深度學習這麼熱門呢?答案很簡單:線上資料蒐集的又快又多,且電腦的運算能力也跟得上需求,加上一堆開源套件,AI 變成每個公司都在追求的項目。

均一也不例外,這個專案隨著資料探勘的進展,我們不斷地調整目標,當中有些挫折,卻也有些驚喜。讓我為你點一首歌,請放鬆地看下去吧!

在 2020 年初,均一想發展 AI 診斷與推薦系統,要完成這個系統有兩個方向要做:

  1. 用少量的題目對學生的能力進行診斷,以達到智慧化出題的效果。
  2. 當診斷結果出來後,要做個人化的推薦(題目)。

這個專案就是想要完成第一個方向。均一擁有大量的做題資料可提供 AI 模型做訓練,要完成這個專案應該不困難吧?專案之初,我負責的項目為資料探勘,而在訓練模型之前,我們勢必要對自家的資料做一些探勘。

資料探勘:旺季與淡季

每月做題數的分布

在蒐集訓練資料時,我們就有個疑問:「是不是蒐集哪個月的資料都沒差?」

為了解答這個問題,我們決定找出資料量大的月份。依據教科書編排,在不同周次有相對應的單元,這些單元的順序在近年內不會改動。所以均一的各單元在一年中有不同的高峰期與低峰期,下面兩張圖讓你一目了然:

圖一:單元「正方體與長方體體積」於 2019 年各月份的做題數
圖二:單元「因數與公因數」於 2019 年各月份的做題數

圖一的縱軸為練習題(知識點內的題目)被做的數量,單元「正方體與長方體體積」位於康軒版五下第一章、南一版五下第四章以及翰林版五下第二章,皆為下學期的單元。

很明顯的,在該單元被教授的二月到四月是最多人練習的時間點,剩餘月份的做題數就相形見拙,經由計算後發現,二到四月的做題量總和占整年的 66% 呢!

圖二的單元「因數與公因數」歸在康軒版五上第二章、南一版五上第二章以及翰林版五上第二章。所以在學期初應該會有大量的使用者,圖中七月到十月的長條特別突出,加總佔據了整年的 42%。

修但幾勒!七、八月不是暑假嗎?為什麼做題數反而衝上來了呢?

其實是因為均一在 2019 年暑假特別推出「時間冒險家」挑戰賽以及上線「週計劃」的新功能,所以使用量才大幅提升。

小結

在訓練機器學習模型時,我們要確保有足夠的資料量才能讓模型夠穩固(robust)。以因數與公因數這單元來看,我們挑七到十月份來當作訓練資料會是比較好的選擇。

資料探勘:你還會回來嗎?

筆者曾經當過高中數學實習老師,在準備教材和規劃課程進度時,會預設教完一個單元大多會花上 4 至 6 節課,而一個禮拜的數學課節數大約就是 6 節(視每間學校的升學導向程度而定),所以一周教完一個單元是沒問題的。

在訓練模型時,我們想確定這些學生通常會在一個單元內待多久,這樣子才能決定出我們的訓練資料包含蒐集多長的時間。

試想,若我們的診斷系統需要使用的資料量大於學生真實會待在單元內的資料量,那就算訓練出來的指標很漂亮,也不會是一個實用的系統。

學生在單元內的學習天數

看完第一章,我們知道學生會在特定月份大量湧入特定單元,但我們也好奇那些月份實際的學習狀況,像是「這些學生在單元內會做幾題?」、「這些學生在單元內會停留幾天?」接下來將深入分析因數與公因數這個單元。

圖三:單元「因數與公因數」各學習天數的人數分布圖

由圖二可見,該單元的旺季在七月到十月,而圖三則幫助我們深入查看旺季中學生的學習狀況,我們發現大多數的學生只在本單元待了 1 到 2 天,而有少數的學生待了 50 天。

其中有個有趣的現象:大約每過 7 天就有一個做題的高峰。這些高峰代表有部分學生在過了 7 天後又回頭進到這個單元,可能跟教師或家長指派給學生的週計劃有關。

另外,由於我們對於學習天數的定義:「使用者在這單元有紀錄的最後一天與第一天的差值」很粗淺,使用者在第一天和最後一天之間不一定有持續地學習,所以這樣還不能定論為有使用者真的在本單元「學」了 50 天。

學生跨週的存留率

雖然大多數的人都待不到 7 天,但圖三中學習天數大於 7 的人數仍然維持在一定的程度,這些使用者可能是真的很需要學習的人,或是愛好學習的人。

無論如何,我們可以將他們簡稱為「忠實客戶」,而我們最關心的就是客戶的存留率。

存留率是什麼?舉例來說:我們以週次切分,第一週使用者有 100 位,這 100 位中還有出現在第二週的使用者有 30 位;在第三週的使用者有 10 位,那麼就說使用者過一週的存留率為 30%,過兩週的存留率為 10%。現在我們就來看看使用者的存留率有多少吧!

圖四:第 0 週使用者在往後幾周的存留率

圖四顯示了第 0 週使用者在後面幾週的存留率。第 0 週的使用者在第 0 週有100%;在一週後存留率為 27%;兩週後還有 11.5%;三週後就只剩下 8.4%⋯⋯六週後,第 0 週的使用者大概只剩下 3% 還留在本單元。

問題來了:為什麼七週後的存留率上升了?這個現象暗示著有些人特別在那週回流,而這些人可能不是學生,而是老師或家長,但真正的原因有待進一步的探索。

圖五:各周使用者在下一周的存留率

有時候我們不在乎第一週使用者是否擅長馬拉松長跑,而是在乎那些短期衝刺的使用者。

圖五呈現出第 0 週到第 8 週使用者在一週後的存留率,最高為 27.04%、最低為 18.32%,平均值和標準差分別為 22.8% 和 0.02,我們可以確定大約有 22% 的使用者會留到下一週。

小結

這篇內容說了兩個重點:

  1. 學習天數每 7 天有一個高峰
  2. 一週後存留率穩定在 23% 左右

這兩個重點支持我們把目標從「用做過的題目(的資訊)去預測沒做過的題目(的答對率)」變成「用上一週做題(的資訊)去預測下週做其他題(的答對率)」。

這個轉變讓資料的切割變得十分簡單:只要用時間切就好了。當然,一個最理想的情況是:「所有使用者都完整的在本單元學習了 14 天,並且在第 1 週時,每個習題都至少被一個使用者做過」,我們才能確保資料的充足性和模型的穩定性。

資料探勘:我可能不會做題

在統計學中的離群值(outlier)代表它們的數值明顯地遠離其他資料點。這些點會顯著地影響迴歸係數,讓迴歸模型的 SSE 大幅提升。

在訓練機器學習模型時,我們希望資料中沒有離群值,所以想要排除那些做題太少的學生,因為可能他只寫了一題就在螢幕前掛機了。

但到底怎樣才算太少或太多呢?顯然,我們需要訂一個門檻。

如何定義「有做」知識點

由於我們想預測的是個人能力(練習題的答對率),而非整個族群的能力,因此勢必把資料探索的顆粒度縮小到個人層級。

回到一開始的問題:我們不要答題數太少或太多的人。

如果答題數太少,答對率的波動就會很大,對於判斷該學生的程度較為困難。所以我們就來看看在一個單元內,每個人在各個知識點平均會練習多少題,用以規定何謂「太少」。

同樣以 2019 年中五年級的單元「因數與公因數」為例,該單元含有 12 個知識點(習題),觀察圖六可發現,練習 1 題和 5 題的人為大宗。

並且在 17 多萬名使用者中,有將近 3 萬人剛好做了 5 題,這群人占的比例極大!這時天秤的兩端開始比重:資料量 v.s. 答題數。

我是要為了高答題數而捨棄掉 17% 的資料量呢?還是反其道而行呢?經過一番討論,最後我們決定將「有做」知識點的定義設為「練習 5 題(含)以上」。

圖六:使用者數量對上做題數

單元覆蓋率的分布

單元覆蓋率是指一位使用者在單元內「有做」知識點的比例。例如:狐狸貓在單元內的 12 個知識點中「有做」6 個知識點,狐狸貓的單元覆蓋率就是 50%。

如圖七所示,有一半的人單元覆蓋率不到 0.3,也就是只在單元內做了 3 到 4 個知識點就走人了。這些負心漢太可惡了!這樣我要怎麼蒐集完整的資料啊~~~

圖七:單元覆蓋率對上人數(紅色虛線為人數均值)

小結

我們定義:做 5 題以上才算「有做」這個知識點(習題)。最後,我們藉由單元覆蓋率去看大家的完成單元的程度如何,發現狀況並不樂觀,我們應該要想辦法努力地把人留在單元內。

特徵選擇:冒牌臥底

我們在資料探勘時,一直注重在習題的資料。在某天開完日常會議後,mentor 跑來跟我說:「測驗題的資料或許比較接近真實的能力」。

此事細思極恐,到現在我也做了三個禮拜了,原來我一直在研究冒牌貨?沒錯,練習題正確率比較不能反映學生真實的能力,因為學生是在練習的情境下答題,沒有時間壓力,也沒有想表現好的慾望,更糟糕的是他能夠倚賴提示來答題。

相反地,測驗題正確率應當比較能夠反映出真實能力(雖然還是離課堂中的考試有一段距離),因此我們相信,與測驗題正確率比較相似的那些練習題,才是我們應該拿來訓練模型的資料。

無奈的是測驗題資料量太小,我們想看一下哪些練習題能夠幫我們增加資料量。

檢驗練習題與測驗題答對率的相關性

圖八:各習題與單元測驗的正確率相關性(高低橫線分別為 0.7 與 0.3)

如圖八,以五年級的單元「因數與公因數」為例,單元測驗與自己的相關係數為1.0(廢話!)。有 8 個習題與單元測驗的正確率相關係數達中度正相關(0.3 以上,不到 0.7),有 3 個習題則只有達到低度正相關(低於 0.3)。

太可惡了!這三個習題竟然和測驗差這麼多,於是我把他們挑出來狠狠的罵一下,分別是:【一般】因數與公因數綜合習題(8 / 11)、【進階】因數與公因數綜合題(10 / 11)、【基礎】最大公因數的應用題(11 / 11)。

有趣的是這三個低相關的習題的排序都是在網頁的底端,分別排第 8、第 10 和第 11,而且這些習題本來就比較少人做,所以相關係數的計算容易受到離群值的影響。

小結

評量的情境與練習的情境不同,我們的確發現有些與測驗題正確率相關性不高的練習題,這些冒牌貨臥底在茫茫題海之中,等待我們一個一個揪出來。為了避免GIGO(garbage in garbage out)的情況,我們應避免使用相關太低的練習題當訓練資料,這或許就是教育領域的「特徵選擇」吧!

特徵選擇:我們不一樣

AI 模型產出的答題正確率,對於老師而言並不能直接被應用,也無法給老師實質上的建議,老師想知道的應該是學生是否「熟練」、「一般」或「待加強」。

但我們要如何把答對率對應到這三個類別呢?每個習題的平均答對率都不同,或許在 A 習題上答對率 70% 的學生為「一般」,但是在 B 習題上答對率 70% 的學生卻是「待加強」,因此我們想細分練習題是否有不一樣的型態。

檢驗練習題的鑑別能力

如下圖所示,縱軸是正確率,橫軸是人數百分比,每一條曲線都是某個習題的正確率(已由小到大排序),我們將 12 個習題的正確率曲線(分布)疊起來就能看出題目的相對難易度。

首先,有一條黃芥末色的曲線在圖中的左上方,代表該習題的難度特別低,有 80% 的使用者在該習題上的答題正確率達到 0.83(粗藍線)。其他習題大多只有不到 60% 的使用者達到 0.83 的正確率。

圖九:單元「一億以上的數」的各習題答對率疊圖
圖十:四年級所有習題答對率疊圖

疊圖的好處除了可以看到各個習題的正確率分布外,也能幫助我們將習題分群。分群當然不能只靠人腦,當我們遇到幾百個習題(圖十)的時候,就必須倚賴電腦幫我們做分群。

做分群時,我們不只利用使用者在習題上的答對率,也加入了答題數、答題時間、提示數和跳過數等 5 個維度的特徵來將習題分群,使用 k-means 將習題分成 4 群。

分群之後,為了將分群結果視覺化,我們要使用主成分分析(PCA)將資料從 5 維降低到 2 維再繪製平面散佈圖。

圖十一:四年級所有習題分群後的散布圖

根據圖十一,每一群習體都被畫上不同的顏色,顯而易見的,group 1 和 group 2 之間並不是被分的很好,因為兩群之間有些重疊。

分群之後,我們要利用分群後各群的特色將其命名。以下附上各群在答對率、答題數、答題時間、提示數和跳過數這五個數值上的折線圖(圖十二、圖十三),以及藉由觀察這些折線圖所得出來的結論(表一)。

圖十二:各群習題的正確率分布圖
圖十三:各群習題答題數(左上)、提示數(右上)、跳過數(左下)、答題時間(右下)分布圖
表一:各群習題的特色以及命名解釋

小結

如果說身高、體重、學歷、收入、性別可以將社會上的人分成好幾種,這些人都具有某種特性。

那麼我們也能用正確率、(被)答題數、(被按)提示數、(被)跳過數、(被)答題時間來將習題分類,最後我們用非監督式機器學習技術將題目分成 4 類,並把各類習題的特性附在表一。

在做這個資料探勘的時候已經差不多知道原本的目標無法達成了,因為沒有一種習題可以幫我們把中分族群和低分族群分開來,而我們的模型也真的只對高分族群有很好的預測準確率

圖十四:混淆矩陣,正確率依照 0.4、0.7 將學生分為低分組、中分組和高分組。

模型結果:不是每段戀情都有美好回憶

初始模型(DeepFM 1

DeepFM 是一種利用深度神經網路實現分解矩陣機的演算法。

起初我們對於單元中的 12 個習題做預測,想要用少題數(做過的習題數量)來預測學生在一個單元內各習題的能力(答對率),來減少診斷系統診斷所需的題數。

我們的變項有:學生 ID、習題 ID、該學生對該習題的答對率、性別、年級、是否註冊、有無教練、身分、居住地和習題難度,模型的輸出為:該學生對其他習題的答對率。

結果如圖十五,RMSE 高達 0.16,可說是慘不忍睹。

圖十五、DeepFM 1 之真實答對率(藍)與預測答對率(紅)

最終模型(XGB

在第五篇的前言有提到「老師想知道的是學生的熟練程度」,於是我們根據答對率來分將學生分組。在請教了均一數學組的大大後,我們以 0.4、0.7 為界線將學生由低至高分成 low、 mid、high 三組。換成分類問題後就能用 confusion matrix、precision 和 recall 來當作指標。

XGB(極限梯度提升樹)是 Kaggle 競賽上的大殺器,用它做準沒錯!並且將真實正確率依照 0.4、0.7 切分成 3 種類別:低分組(low)、中分組(mid)、高分組(high),當作是要預測的標籤。

在資料部分,我們蒐集擁有最多共同使用者的連續兩週當作資料集,並以第一週作為訓練集、第二週作為測試集。

在特徵部分,我們將 12 種習題的 ID 做 one-hot encoding(圖十六),並且增加習題相關的特徵,如:該習題過去被回答時平均耗時的均值、四分位距以及被按了幾次提示。

期望能提供更多的資訊在每個習題中,而非只有單純的習題 ID。而對於所有的連續變量,我們使用過最大一最小歸一化做資料轉換。

然而混淆矩陣與指標如圖十七,硬生生地告訴我們這模型仍然只能準確地預測高分組的學生,對於低、中分組學生毫無辨別能力,這和「特徵選擇:我們不一樣」的推論一致。

圖十六:習題 ID 的獨熱編碼
圖十七:XGB 的混淆矩陣

總結與未來方向

謝謝大家看到這邊,故事到了尾聲,來說說我的感想吧!

這個 AI 專案當初是想要預測學生的能力,但是在多次的模型優化和資料探勘後發現這個這個任務在指標上(RMSE、precision、recall 等等)都達不到我們心中的標準。失敗原因有很多:

  1. 資料量太少
  2. 樣本不均衡
  3. 習題正確率並不代表真實能力

換言之,是一個被汙染的 y 值。雖說這個專案暫時停擺了,倘若未來要改良此模型,我們可以針對上述失敗原因做改善。

我自己認為,均一應該舉辦一場全國性的線上挑戰賽,如同 PaGamO的反毒英雄爭霸賽,在比賽當中做題就可以模擬考試的情境。

這就能解決第一點和第三點。至於第二點,我們可以用 SMOTE 演算法來增強少數類別的樣本,以解決資料不平衡的問題。

當然,還有許多機器學習的相關技術是我們尚未嘗試的,例如:ensemble learning 與 grid search 等。

最後我想說,這個 AI 專案可以說是失敗了,但同時也成功了,因為資料探勘給予我們團隊更多收穫,也更清楚這些資料可以或不行支持哪些 AI 專案。


作者:皇甫承佑(均一平台教育基金會資料分析與機器學習實習生)
編輯:陳又慈(均一平台教育基金會社群內容實習生)

分享這篇文章:

相關文章