Java 實現等頻分箱

来源:https://www.cnblogs.com/holicx/archive/2022/05/31/16331269.html
-Advertisement-
Play Games

等頻離散法 根據數據的頻率分佈進行排序,然後按照頻率進行離散,好處是數據變為均勻分佈,但是會更改原有的數據結構。區間的邊界值要經過選擇,使得每個區間包含大致相等的實例數量。比如說 N=10 , 每個區間應該包含大約 10% 的實例。 Python 實現方式 等頻法是將相同數量的記錄放在每個區間,保證 ...


目錄

等頻離散法


根據數據的頻率分佈進行排序,然後按照頻率進行離散,好處是數據變為均勻分佈,但是會更改原有的數據結構。區間的邊界值要經過選擇,使得每個區間包含大致相等的實例數量。比如說 N=10 , 每個區間應該包含大約 10% 的實例。

Python 實現方式


等頻法是將相同數量的記錄放在每個區間,保證每個區間的數量基本一致。即將屬性值分為具有相同寬度的區間,區間的個數 boxSize 根據實際情況來決定。比如有 60 個樣本,我們要將其分為 boxSize=10 部分,則每部分的長度為 6 個樣本。其缺點是邊界易出現重覆值,如果為了刪除重覆值可以設置 duplicates=‘drop’,但易出現於分片個數少於指定個數的問題

import pandas as pd  
import numpy as np  

data = np.random.randint(1,100,200)  
dd = pd.qcut(data, 10)  
print(str(dd.value_counts()))

運行結果:

Java 實現方式


使用 Java 實現 Python 中的 qcut() 等頻分箱後的 value_counts() 功能。

/**  
 * 等頻分箱  
 *  
 * @param dataList 數據列表  
 * @param boxSize  分箱大小  
 */  
public static String quantileBasedDiscretion(List<BigDecimal> dataList, int boxSize) {  
    if (CollectionUtils.isEmpty(dataList) || 1 == dataList.size()) {  
        throw new RuntimeException("data set can not be null or size 1");  
    }    // 數據集排序  
    dataList = dataList.stream().sorted().map(value -> value.setScale(3, RoundingMode.HALF_UP))  
            .collect(Collectors.toList());  
  
    BigDecimal[] boxValue = new BigDecimal[boxSize + 1];  
    // 獲取分位數對應的值  
    for (int i = 0; i <= boxSize; i++) {  
        double quantile = 1.0 * i / boxSize;  
        boxValue[i] = sortedListPercentile(dataList, quantile).setScale(3, RoundingMode.HALF_DOWN);  
    }    // 重新計算首部分箱值  
    boxValue[0] = boxValue[0].multiply(BigDecimal.valueOf(1 - 1e-10)).setScale(3, RoundingMode.FLOOR);  
    if (boxValue[0].compareTo(BigDecimal.ZERO) <= 0) {  
        boxValue[0] = boxValue[0].add(new BigDecimal("-0.001")).setScale(3, RoundingMode.FLOOR);  
    }    // 分箱操作  
    Map<String, Long> countMap = new LinkedHashMap<>();  
    for (int right = 1; right < boxValue.length; right++) {  
        int left = right - 1;  
        for (BigDecimal data : dataList) {  
            String key = "(" + boxValue[left] + ", " + boxValue[right] + "]";  
            if (data.compareTo(boxValue[left]) > 0 && data.compareTo(boxValue[right]) <= 0) {  
                countMap.compute(key, (k, value) -> value == null ? 1L : value + 1L);  
            }  
            countMap.putIfAbsent(key, 0L);  
        }  
    }  
    StringBuilder result = new StringBuilder();  
    countMap.forEach((key, value) -> result.append(key).append("\t").append(value).append("\n"));  
    // countMap.forEach((key, value) -> result.append(key).append(" ").append(value).append("|"));  
    return result.length() > 0 ? result.substring(0, result.length() - 1) : null;  
}  
  
/**  
 * 獲取指定分位數的值  
 *  
 * @param numList 數據列表(排序後)  
 * @param p       分位點  
 */  
public static BigDecimal sortedListPercentile(List<BigDecimal> numList, double p) {  
    int n = numList.size();  
    BigDecimal px = BigDecimal.valueOf(p).multiply(BigDecimal.valueOf(n - 1));  
    BigDecimal i = px.setScale(0, RoundingMode.FLOOR);  
    BigDecimal g = px.subtract(i);  
    
    if (g.compareTo(BigDecimal.ZERO) == 0) {  
        return numList.get(i.intValue());  
    } else {  
        BigDecimal d1 = BigDecimal.ONE.subtract(g).multiply(numList.get(i.intValue())).setScale(2, RoundingMode.HALF_UP);  
        BigDecimal d2 = g.multiply(numList.get(i.intValue() + 1)).setScale(2, RoundingMode.HALF_UP);  
        return d1.add(d2);  
    }  
}

運行結果:

測試結果對比


100 次運行結果差異對比

10000 次運行結果差異對比

ps: 這裡的分箱成功率使用的是每個區間分的的值作為判斷依據。

由上圖可以得出在 1 萬條數據時,存在 22% 的數據與 Python 分箱後的值存在差異。但通過區間數據可以觀測出統計範圍誤差在可容忍範圍 (0.000 ~ 0.099) 內,且最終統計數據值之和均為相同的,不存在數據未分區的情況。

總結


這是一個簡易的 Java 等頻分箱功能實現。對比 Python 的 Pandas 庫中 qcut() 方法還有很大的提升空間。包括如果邊界出現重覆值的問題處理等問題還未實現。功能實現僅供參考,希望能給大家帶來幫助,也歡迎相互學習討論~

參考文獻:

Java 分位點 (分位值) 計算_0xYGC 的博客 - CSDN 博客_分位點怎麼計算

python 數據分析之數據離散化 —— 等寬 & 等頻 & 聚類離散_Mr 番茄蛋的博客 - CSDN 博客_python 數據離散化


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前端周刊:2022-9 期 前端開發 網路視頻的防盜與破解 網路視頻(Web 視頻)是指利用 HTML5 技術在瀏覽器中播放的視頻,這類視頻資源通常可以被隨意下載,某些行業(比如教培行業)如果希望保護自己的視頻資源不被下載,就需要對視頻做防盜鏈處理。 Vue 組件復用問題的一個解決方法 關於 vue ...
  • 1. id選擇器 <style> #container { width: 100px; } </style> <body> <div id="container"></div> </body> 2. class選擇器 | 類選擇器 <style> .container { width: 100px; ...
  • Tooltip常用於展示滑鼠 hover 時的提示信息。 而在實際過程中,有這麼一個需求:只有文字內容排不下,出現省略號,才需要顯示tooltip的提示內容。 本文章的思路是通過一個自定義指令實現如下效果:姓名欄位過長時才顯示tooltip ...
  • 緊急通知!更新中.... (一)FastJson反序列化漏洞。據國家網路與信息安全信息通報中心監測發現,阿裡巴巴公司開源Java開發組件FastJson存在反序列化漏洞。FastJson被眾多java軟體作為組件集成,廣泛存在於java應用的服務端代碼中。攻擊者可利用上述漏洞實施任意文件寫入、服務端 ...
  • 摘要:NumPy中包含大量的函數,這些函數的設計初衷是能更方便地使用,掌握解這些函數,可以提升自己的工作效率。這些函數包括數組元素的選取和多項式運算等。下麵通過實例進行詳細瞭解。 前述通過對某公司股票的收盤價的分析,瞭解了某些Numpy的一些函數。通常實際中,某公司的股價被另外一家公司的股價緊緊跟隨 ...
  • 背景 框架之前完成了多數據源的動態切換及事務的處理,想更近一步提供一個簡單的跨庫事務處理功能,經過網上的搜索調研,大致有XA事務/SEGA事務/TCC事務等方案,因為業務主要涉及政府及企業且併發量不大,所以採用XA事務,雖然性能有所損失,但是可以保證數據的強一致性 方案設計 針對註冊的數據源拷貝一份 ...
  • 首先請記住一點,在電腦中所有的二進位都是以補碼的形式存儲的,所以你最後取反之後只是這個數的補碼,你還需要轉換成源碼,才是我們最終的十進位數字 下麵是計算過程: 正數取反(123,結果是-124): (1)先將此數變為二進位數,全部位取反(0變1,1變0); (2)由於這個數是補碼,所以要進行再一次 ...
  • Spring Ioc源碼分析系列--Bean實例化過程(二) 前言 上篇文章Spring Ioc源碼分析系列--Bean實例化過程(一)簡單分析了getBean()方法,還記得分析了什麼嗎?不記得了才是正常的,記住了才是怪人,忘記了可以回去翻翻,翻不翻都沒事, 反正最後都會忘了。 這篇文章是給上篇填 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...