大家好。感謝各位今天蒞臨。今天我將就我參與的一個專案進行演講,演講主題是《從開發到測試:JMP插件的創建與驗證之旅》。
簡單介紹一下我自己。我目前是美國克萊姆森大學數學科學專業的博士研究生。我的研究方向主要集中在實驗設計和偏好學習領域。自2024年夏季以來,我一直在JMP公司的實驗設計與可靠性團隊實習。實習期間,我參與過離散選擇實驗和軟體測試相關的項目,這兩個領域截然不同。關於我的介紹就到這裡。
我先概述一下今天的演講內容。首先,在演講的第一部分,我將談談我們在暑假期間開發這款外掛程式的動機。原因是,我們正在為 JMP 的 Easy DOE 專案進行一些可用性研究,試圖了解不同使用者群體(包括不同人口統計群體)的使用者介面偏好。之後,在闡述了開發這款外掛的動機之後,我將詳細介紹並示範這款外掛程式。最後,我將簡要介紹如何使用 JSL 單元測試框架來測試這款插件,以驗證我們開發的應用程式或插件。
這是第一部分,也是我們開發這款外掛的動機。正如一些用戶可能知道的那樣,JMP 中有一個名為 Easy DOE 的程式。該程式旨在幫助用戶完成實驗設計和分析的整個過程。 Easy DOE 的工作流程包含幾個不同的部分。實驗人員首先需要定義他們感興趣的因素和反應變數。之後,他們選擇要用於分析所收集資料的模型。選擇模型後,他們就可以為該模型設計實驗了。
實驗設計完成後,他們可以進行實驗,然後將收集到的資料輸入到「資料輸入」標籤中。資料收集完畢後,他們可以分析模型。分析數據並擬合模型。最後,他們可以使用該模型進行預測,並根據需要選擇最佳因子設定。最後,他們可以查看模型的總結報告。
今天我們要重點關注的是「分析」選項卡。正如一些使用過 Easy DOE 的使用者所知,「分析」標籤的介面如圖 2 所示。今年夏天,我們一直在研究如何改進「分析」標籤的某些部分,使其更便於實驗人員和 Easy DOE 用戶使用。最終,我們提出了幾個不同的使用者介面版本供使用者選擇,並希望了解哪個版本最受歡迎。
我們設計的這個使用者介面採用了因子結構。我們特別關注的是懸停幫助功能。懸停幫助包含幾個不同的信息,用於告知使用者模型的一些統計屬性。這些資訊包括“已輸入資訊”,用於指示某個項目是否已添加到模型中(我們為此設置了兩個版本);“顯著性信息”,用於指示該項是否顯著;以及“遺傳信息”,用於解釋為什麼某個項即使不顯著也會被包含在模型中。
通常情況下,存在一種稱為「遺傳」的特性,即如果交互項顯著,但主效應不顯著,我們仍然會包含主效應。最後,懸停幫助設定的另一個因素是懸停幫助的位置。它是位於置信區間上方,還是位於預覽列上方?
我們想了解的是,用戶最喜歡哪種設定?正如我剛才所說,我們考慮了四個因素。其中兩個或三個因素有兩個級別,而另一個因素有三個級別,因此懸停幫助設定的使用者介面可能有多達 24 種不同的版本。
另外,Easy DOE 的使用者群體中,許多都是新手或只有一些實驗設計經驗的人。但有時也會有經驗豐富的實驗設計人員使用 Easy DOE,他們可能會將其用於個人學習或教學。 Easy DOE 的使用者群體涵蓋了不同的人口統計特徵。我們希望了解不同人口統計特徵的用戶群體偏好哪些懸停幫助設置,以便我們能夠針對每個用戶群體定制懸停幫助的設計。
我們希望透過情境離散選擇實驗框架來解決這個問題。接下來我將簡單介紹一下這個框架。首先,我將談談資料收集過程。在情境離散選擇實驗中,我們會有一組參與者,以及這些參與者的一些協變量資訊。例如,我們稱之為協變量資訊或情境資訊。通常,它可以是用戶的基本資訊。
在這個框架下,我們向不同的參與者發放問卷,每個問題都要求他們比較兩種或多種替代方案,並選擇他們更傾向的方案。資料收集過程非常直觀,也反映了人們在現實生活中可能做出的選擇。
現在我將簡要介紹情境離散選擇實驗的建模和分析。收集資料後,您可以對這些資料擬合一個效用模型。此模型不僅包含研究對象的相關因素(在本例中為懸停幫助設定),還包含參與者的情境資訊。將這兩者結合起來,可以了解不同使用者群體(來自不同人口統計群體)對不同懸停幫助設定的偏好。最終,一旦擬合出這個效用模型,您就可以利用它來了解或找出每個人口統計群體最偏好的懸停幫助設計。
情境離散選擇實驗的一個重要組成部分是實驗設計。我們如何選擇要向參與者提出的問題?如果您熟悉常規離散選擇實驗,就會知道,為了設計出好的離散選擇實驗,通常需要一些關於使用者偏好的先驗資訊。
在情境離散選擇實驗中,我們先進行所謂的篩選研究。在篩選研究中,我們首先招募一定數量的參與者,並收集他們的情境資訊或人口統計信息,然後讓他們填寫問卷並收集他們的偏好數據。基於篩選研究的結果,我們擬合一個模型來描述使用者的偏好。之後,我們可以利用這個模型來了解不同人口統計群體之間的偏好。
因此,我們可以利用這個模型來創建貝葉斯先驗,進而為問卷設計貝葉斯D-最優設計。我們可以利用這些設計,針對不同的人口統計群體創建問卷,從而更有效率地從每個群體中獲取更多統計資料。這就是我們想要採用的方法……我們想要解決這個問題的方式。我們希望創建統計效率極高的問卷,發放給參與者,以便更有效地收集信息,並了解不同人口統計群體的偏好。
接下來我將簡單介紹一下這個插件的建立過程。首先,對於那些不了解的朋友,JSL 是 JMP 腳本語言。它允許使用者擴展 JMP 的功能,例如運行常規的多步驟分析,或將指定的模型擬合到每日產生的資料。 JSL 真正實現了 JMP 功能的擴展。 JMP 外掛本質上就是一個 JSL 腳本,它可以擴展 JMP 的功能,其他 JMP 使用者可以下載並使用它。
我們為什麼要針對特定問題開發 JMP 外掛?首先,我們當時正在進行多項可用性研究。我們會在不同的時間點進行同一項可用性研究,即針對懸停幫助設定的可用性研究。隨著時間的推移,我們收集的數據越來越多,並利用這些數據來改進實驗設計或發送給使用者的問卷。此外,我們也正在進行其他可用性研究,例如,針對使用者介面不同因素的可用性研究。例如,其中一項可用性研究是關於「分析」標籤上通知訊息的配色方案和位置。
開發此插件的另一個原因是,創建這些情境離散選擇實驗可能很繁瑣,因為通常需要計算先驗均值和協方差矩陣,才能為每個組創建貝葉斯D-最優設計。我們發現,透過JSL腳本可以實現這一過程的自動化。
最後,這個情境離散選擇實驗框架可以應用在非常廣泛的選擇任務。它不僅限於可用性研究,也適用於任何需要使用者在多個選項中表達偏好的研究。我們開發這個外掛不僅是為了幫助我們自己,也是為了讓其他人也能使用它來解決他們的問題。
我將簡要介紹我們情境離散選擇插件的工作流程。首先,使用者或實驗人員需要從篩選研究中收集資料。篩選研究應包含以下資訊:您向參與者提出了哪些問題?參與者的屬性是什麼?個人資料屬性是什麼?您研究的對像有哪些因素,以及受試者的協變數。
獲得這些數據後,就可以對數據擬合篩選模型。在篩選模型中,實驗者需要指定兩種效應:一是界面效應,二是受試者效應。在我們的案例中,界面效應指的是懸停幫助設定。這使得實驗者能夠創建一個效用模型。然後,使用 JMP 的選擇分析平台來估計該效用模型。
完成上述步驟後,使用者即可選擇人口統計群體進行深入研究。他們透過選擇每個受試者效應或背景因素的水平來實現這一點。這些水平的組合確定了一個待研究的群體。選定群體後,系統會為該群體建構一個貝葉斯D-最優設計或貝葉斯D-最優問卷,以便實驗者能夠以統計高效的方式對該群體進行進一步研究。
現在我將示範情境離散選擇實驗插件。我打開 JMP,然後進入“插件”選單。我選擇“數據表”。這個數據表包含一些資訊……我快速展示一下它的樣子。這個資料表包含了先前針對懸停幫助功能的可用性研究資訊。您可以看到,其中包含諸如使用者選擇了哪個選項、呈現了哪些選項等資訊。我們還有一些關於使用者的情境訊息,例如他們在實驗設計方面的經驗水平,以及他們使用 Easy DOE 的原因。是用於個人用途還是用於教學?
在這個……我打開這裡。首先,我們要新增回應指示器,也就是使用者所做的選擇,也要設定選擇集 ID 和主題 ID。然後,我們可以在這裡輸入個人資料效果,在我們的設定中,就是滑鼠懸停幫助位置的那三個訊息。如果需要,我們也可以加入互動效果。但現在,我只保留主效果模型。此外,我們還可以添加主題效果,例如經驗水平,以及使用者是教導別人還是將 Easy DOE 用於個人用途。
您可以看到,這裡的許多資訊看起來都和選擇分析平台的設定非常相似。點選「運行」後,後台會啟動選擇分析平台,並分析篩選研究的篩選模型。當然,我們可以像操作選擇分析平台一樣與它互動。例如,我們可以調出效用分析器,然後可以看到,經驗豐富的使用者(也就是正在指導他人的使用者)更傾向於選擇某個特定的遺傳資訊選項,也就是這裡的第二個選項。
查看這些資訊後,我們可以調出這個元件,它會要求我們選擇一個人口統計群體進行進一步研究。假設我正在進行這些研究,並且我想研究Easy DOE的專家用戶,也就是那些在實驗設計方面經驗豐富的用戶,我對他們在指導他人時的表現很感興趣。我想製作一份問卷來了解這些專家使用者的偏好。我點擊“創建設計”,它會打開選擇設計平台,並將我們在選擇分析階段或篩選研究階段輸入的資訊自動導入到選擇設計平台中。
我們有自己的屬性,也有針對這個特定群體的模型,這是我們指定的主效果模型。最重要的是,利用篩選研究中的模型,我們能夠計算出我們感興趣的特定群體的貝葉斯先驗平均值和先驗變異數。
創建好先驗資訊後,我們就可以點擊「創建設計」按鈕,創建一個所謂的貝葉斯D-最優設計。這樣,我們就得到了一個專門針對我們正在研究的特定群體而設計的實驗設計。這個設計的建構充分考慮了我們之前掌握的關於該群體偏好的先驗資訊。現在,這個設計已經針對我們想要進一步研究的群體進行了客製化。以上就是我對情境離散選擇實驗插件的示範。接下來我會關閉一些演示,然後回到幻燈片部分。
接下來,我要講的最後一點是使用 JSL 單元測試框架來測試外掛程式。首先,對於那些不了解單元測試的人來說,什麼是單元測試?單元測試是指測試軟體應用程式的各個組件以識別錯誤。特別是,自動化單元測試允許頻繁地對軟體應用程式執行單元測試,以便在開發過程中識別和修正新引入的錯誤。
具體來說,JMP 提供了一個名為 JSL 單元測試框架的單元測試框架,該框架專為 JSL 應用程式量身定制。該框架中最重要的函數是 `ut assert` 函數,它允許使用者測試 JSL 應用程式的特定元件。使用者會預設一個他們認為正確的輸出,即預期值。然後,他們將預期值與應用程式的實際輸出進行比較。如果兩者匹配,則表示測試案例通過;如果不匹配,則表示測試案例失敗。當使用者編寫包含 `ut assert` 函數的腳本並執行後,系統會傳回一份報告,告知使用者哪些測試案例通過,哪些失敗,以便進行進一步的調查。
我們在情境離散選擇實驗插件中測試了不少功能。例如,我們測試了用於新增互動效果的「叉號」按鈕。它是否正常工作?我們設想,如果選擇兩個特定的選項並點擊「叉號」按鈕,我們知道應該顯示什麼內容,因此可以將其與實際輸出進行對比,以確保系統運作正常。
我們測試的另一個重要內容是,在選擇要進行進一步研究的人口統計群體時,我們希望確保如果實驗人員將某個選項留空,則會彈出一條訊息。我們進行了測試,並確保此錯誤訊息按要求彈出。
最後,這一點非常重要。我們要確保匯入到選擇設計器中的先驗資訊是正確的。我們對此進行了測試,並將其與選擇分析平台的輸出結果進行了比對。如果兩者匹配,則表示我們已正確地將先驗資訊匯入到選擇設計器中;如果兩者不匹配,則表示存在問題。值得慶幸的是,我們發現導入的先驗資訊是正確的。
現在,自動化單元測試最重要的作用之一就是在程式碼重構時發揮作用。自動化單元測試允許開發者重構程式碼並檢查是否引入了任何錯誤。所謂程式碼重構,指的是在開發過程中對程式碼進行修改。如果你修改了程式碼,如何知道是否破壞了與修改內容無關的其他部分?
我們發現的一個例子是,該外掛程式的一位測試使用者發現,當某個上下文因素具有值標籤時,該上下文因素的清單將無法正確顯示。實際上,它根本不會顯示。
我們回頭修復了那個錯誤。但我們想確保修復過程中不會引入其他問題。我們做到了。我們透過重新運行單元測試腳本進行了驗證。值得慶幸的是,在執行單元測試腳本後,我們發現沒有引入新的錯誤,這有助於確保我們沒有破壞其他功能。正如您在圖片右側看到的那樣,我們針對值標籤問題提出的修復方案確實正確地解決了該問題。
單元測試非常重要,原因有三:首先,它可以幫助您發現程式碼中的錯誤;其次,它可以幫助您重構程式碼,確保沒有引入其他錯誤;第三,隨著 JMP 的更新,JMP 內部的某些機制以及某些平台可能會發生變化。有了單元測試腳本,您就可以在 JMP 更新後隨時測試您的插件,確保 JMP 內部的某些變更是否影響了您的插件。
在今天的演講結尾,我介紹如何設計情境離散選擇實驗,以幫助我們了解不同使用者群體對 Easy DOE 的使用者介面偏好。然後,我示範如何使用 JSL 腳本建立一個非常方便的 JMP 插件來建立這些離散選擇實驗。最後,我討論了在插件開發過程中或開發完成後進行單元測試的重要性,這有助於在開發過程中及開發完成後發現錯誤。
我的演講到此結束。請問大家有什麼問題嗎?