威廉·鮑姆( 威傑鮑姆 ),新罕布什爾大學統計學研究生
我的專案是使用 JMP 腳本語言從多個網站提取資料來預測職業足球的勝利。該腳本自動執行了原本費力的收集、匯總和重新組織數據以供分析的過程。腳本的幾個部分包含不同的功能,例如單元格處理以消除下標,以及多個資料集的連接和聯接。使用關聯數組來比較不同行中列公式的輸出。最後,比較了多種預測模型的結果。該專案的目的主要是為了說明如何使用 JSL 以可重複的方式自動化資料收集、組織和預測過程。
介紹
大約兩年前,我了解到 JMP 可以使用 JMP 腳本語言 [JSL] 從網路上抓取資料。作為一名統計學研究生,我經常尋找實踐數據來磨練我的分析技能並提高我的編碼能力。碰巧我是一名狂熱的美式足球迷,而且體育統計數據很容易從網路上的許多不同來源獲得。作為一項練習,我嘗試使用從網路上抓取的數據來預測每個職業足球隊在一個賽季的總勝場數。
資料擷取和清理技術可應用於網路上以 HTML 表形式提供的任何資料。我發現 JSL 可用於自動清理資料並在單一腳本或複合腳本群組中執行建模,這真是太神奇了。此外,JMP 還可以幫助那些程式設計經驗有限的人,讓使用者透過其圖形使用者介面 [GUI] 進行分析,然後將流程儲存為可重複使用的腳本。這使得用戶在使用更新或新數據重複分析時節省了大量時間。
設定
第一步是建立資料夾,用於儲存在資料聚合過程中建立的檔案。我發現為每個資料來源建立一個資料夾可以很好地組織生成的許多檔案。

接下來,我要求腳本使用者指定檔案儲存的本機路徑,以使程式碼更清晰:dir = Pick Directory(“選擇檔案儲存目錄”,顯示檔案(0));
該本地路徑也可以硬編碼。
一旦選擇了路徑,就會從多個網站抓取資料並儲存到單獨的檔案中(每個 HTML 表一個)。這些文件稍後在資料聚合階段被引用。
抓取數據
使用 JMP,只需將 URL 名稱從瀏覽器的網址列複製並貼上到 JSL 程式碼中即可。還可以直接在腳本中放置網站鏈接,這有助於在編輯 JSL 程式碼時打開網站:Web("http://url_name.com");
導入數據
JMP 有各種有用的工具來幫助資料導入。首先,可以嘗試直接將 html 表格儲存為 JMP 檔案。當資料幾乎不需要重組時,此方法最有效。第二種方法是先將 html 表儲存為逗號分隔值 [CSV] 文件,然後可以使用透過 JSL 提供的使用者定義設定將其匯入 JMP。查看匯入的表格後,我注意到有幾列空白列。使用“刪除列”命令,我能夠用一個簡短的腳本從表中刪除空列。

JMP 自動從網路提取資訊並儲存檔案。人們不一定需要保存這些文件,但從網路上抓取的資料有時可能會有點混亂。將資料儲存到檔案可以更容易地進行偵錯,因為可以查看匯入的表並根據需要調整程式碼。
方法 1
資料被匯入並儲存為 CSV 文件,最初:
ObjectName = Open(“http//:url_name1.com”,HTML 表(#))<< 設定名稱(“TableName1”)<< Save(dir||“FileName1.csv”);
方法 2
資料直接導入JMP並儲存:
物件名稱 = 打開(“http://url_name2.com”, HTML 表 (#) << 設定名稱 (“TableName2”) << 儲存 (dir||“FileName2.jmp”);

細胞處理
在腳本中對字元資料進行排序時,即使導入的字串有細微的變化也會破壞您的程式碼。在這種情況下,季後賽已經臨近,為了表明新英格蘭已經奪得分區冠軍,他們的名字中插入了一個“z”。值得慶幸的是,JMP 提供了各種命令來操作單元格內的字串。

在下面的腳本中,JMP 循環遍歷「團隊」名稱列的每一行,並刪除指定字母(如果它們出現在字串的開頭)。 「For Each Row」指令可以輕鬆實現循環,將一個過程應用到每一行。條件「如果,那麼」短語告訴 JMP 在特定條件適用時該做什麼。 「包含」指令傳回字串中指定項目的位置。 「Substr」(子字串)指令傳回字串的一部分:從指定位置開始,傳回指定數量的字元。

合併表
透過「表格」選單可以輕鬆地在 JMP 中合併表格。表格選單提供多個選項。一般來說,我使用“連接”來組合具有不同列但相同行標籤的表。當我將具有不同行標籤但相同列的表格組合在一起時,我使用「連接」。在這種情況下,我連接了來自多個表的資訊。為每個團隊部門建立了一張表格。接下來,我按照團隊名稱的字母順序對結果檔案的行進行排序,以確保稍後在加入過程中符合相同的行。

建立新表
我發現在連接表之前建立新表很有用。 JMP 允許使用者透過幾種方式建立新表。首先,它可以透過 GUI 完成。也可以透過腳本來完成。在這種情況下,我使用「新表」指令建立一個具有適當行數的新表:每個足球隊一個表。然後,我使用“新列”命令添加了團隊名稱列,並使用列表設定值。

連接表
我發現如果沒有 JMP,連接表格是一項煩人的任務。值得慶幸的是,JMP 有一個不錯的 GUI,可以在「表格」選單中合併表格。儘管命名約定始終很重要,但 JMP 會自動重新命名來自不同資料表但具有相同名稱的資料列。在這種情況下,我透過 GUI 連接表格,然後簡單地將結果表的表格腳本複製並貼上到我的更大的自訂腳本中。否則,在連接表格之前,我得進行大量的輸入工作(重命名列)。我重複了多次加入過程。

重新命名和重新格式化列
一旦連接完成,我就會得到很多聽起來很奇怪的列名。為了消除混淆,我重命名了這些列。為此,我首先建立了一個首選名稱清單。然後,我使用循環和“設定名稱”函數的組合重命名了列。

有時 JMP 會將資料作為字串匯入,但使用者需要不同的列格式,例如時間。這在 JMP GUI 中很容易更改,但也可以在 JSL 腳本中完成。在這種情況下,我讓 JMP 知道該列包含連續時間訊息,而不是字元。
重新組織列
一旦資料被聚合並且新列被創建,人們可能想要改變資料表中列的順序。在 JSL 中,使用「移動選定的列」指令可以輕鬆實現。

資料表視圖
這是已完成的資料表的部分視圖。

開發關聯數組
當我完成資料匯總後,就該進行一些分析了。我首先想要比較的是根據賽季到那時為止的賽程強度,比較不同球隊的相對實力。我的目標是預測一支球隊未來的表現有多強,不僅基於他們自己的過去表現,也相對於他們未來對手的過去表現。為了做到這一點,我必須比較表格中不同行和列的儲存格中包含的資訊。建立關聯數組(又稱字典或雜湊圖)對於這項任務非常有用。
在 JMP 中,可以使用列表、矩陣或關聯數組中的列。在這種情況下,我使用了兩列,具有預設值(null)。關鍵列“TEAM”包含每個球隊的城市名稱縮寫。價值欄稱為“實力”,是一個公式欄,用於計算指數,結合勝利和淨得分。我使用 17 週比賽日程表的每一周(一列)作為鍵來引用該週的關聯數組值。
17 週課程表:鑰匙

在腳本中,我定義了關聯數組,然後建立了一個公式列來引用它。再次,公式透過關聯數組的下標引用正確的值,使用每週對手作為關鍵。如果鍵列中的值不在關聯數組中,則函數會傳回空值(適用於時間表中的休息週)。

然後,我每週創建一個新專欄來比較團隊實力。這兩個公式可以合併在一起,但我更願意將它們分開,這樣我就可以直觀地看到數據表中的不同指標。

接下來,我計算了本季預測的勝利場次。計算列結果的一個簡單方法是建立一個新的公式列,其中包含 17 列中每一列的一系列「If-Then」條件的總和。在這種情況下,如果實力差異為正,則預測被視為獲勝並有效。

建立預測模型
JMP 具有多種用於預測的建模技術。許多技術可以透過“分析”選單訪問,包括“擬合模型”和“神經”平台。在建立自訂腳本時,我建議先在 JMP 平台中開發最佳模型。然後可以將模型腳本儲存到資料表(透過 GUI),並將程式碼複製並貼上到自訂腳本中。也可以使用 JSL 將模型腳本儲存到資料表中。這使用戶可以靈活地設定模型自動運行,或使模型在自訂腳本建立的表的資料表腳本清單中可用。
以下是一個例子。

JMP Pro 中的高階建模技術
JMP Pro 中提供了幾種高階建模技術,而這些技術在 JMP 標準版本中是沒有的。兩個例子是神經網路的增強版本和彈性網路廣義迴歸技術。 JMP 的另一個優點是它能夠按照使用者指定的比例執行保留驗證,並自動從資料集中選擇隨機樣本。這簡化了驗證和模型比較。
增強神經網絡

彈性網絡

有時,多個模型預測的平均值可能會優於單一模型的表現。
這裡我在 JSL 中建立了一個公式列,對兩個預測公式進行平均。

JMP Pro 有一個模型比較平台,使用者可以並排比較多個模型的相對有效性。模型比較平台還允許用戶只需單擊幾下即可對多個模型進行平均。
模型比較

在這種情況下,神經網路和彈性網路模型(帶有保留驗證 [HB])的平均值比單獨的兩個模型中的任何一個表現都要好一些。模型比較平台的另一個很好的功能是「實際與預測」和「殘差與行」圖。
模型比較圖

結論
借助 JMP 腳本語言 [JSL],JMP 可以從多個 Web 來源抓取資料、處理資料、執行多個預測、比較它們並顯示它們——所有這些都在單一腳本中完成。有效使用 JSL 可以節省大量時間,尤其是當必須定期重複分析時。