【💊 Python的解憂錦囊】亂數按比例分配資料集

更新於 發佈於 閱讀時間約 0 分鐘

假設我們今天想要訓練一個AI模型, 那麼我們會有一批大型資料集, 通常會根據比例來切分三個模型訓練所需的訓練集(train)、驗證集(dev)、測試集(test), 而我們本次會示範一下Python如何對一個List清單進行切分, 基本上大同小異, 我們只要掌握作法即可概念相通。

任務提示

raw-image


我們有10個依序的號碼球, 每個桶子按照比例大小裝載這些球, 比例如下:

  • A桶 = 10 * 0.8 = 容納8個球
  • B桶 = 10 * 0.1 = 容納1個球
  • C桶 = 10 * 0.1 = 容納1個球

並且每個球會被分到哪邊是隨機亂數的, 請依照這些條件完成隨機分配的任務。

拆解問題並釐清作法

從任務的描述之中我們可以觀察到幾個重點, 「隨機」與「按照比例分類」。

首先我們來談談「隨機」, 這方式最直白的就像是我們在玩撲克牌的洗牌一樣, 將排組盡量模糊掉順序, 避免每次的結果都一樣。

raw-image

那「按照比例分類」呢? 其實就想像成蛋糕切成幾等份一樣, 一定有些人食量較大, 有些人食量較小, 那我們便按照大小的比例來切成幾等份。

raw-image


那上述的情境我們可能會有以下幾個思路:

  1. 分成三桶後, 依序拿球隨機丟桶。
  2. 分成三桶後, 隨機抽球依序丟桶。
  3. 對球洗牌, 依序分到小桶子。

首先我們來分析一下這三種作法吧!

思路1: 分成三桶後,依序拿球隨機丟桶

  • 優點:簡單且容易理解,程式碼簡潔。
  • 缺點:隨機性較差,可能會導致某些桶子球數量不均勻。
import random

# 初始號碼球列表
balls = list(range(1, 11))

# 各桶比例
props = [0.8, 0.1, 0.1]

buckets = {
'A': [],
'B': [],
'C': []
}

# 依序抽球
for ball in balls:
# 隨機抽桶
bucket = random.choices(list(buckets.keys()), weights=props)[0]
buckets[bucket].append(ball)

# 印出各桶子裝載的內容
for bucket, content in buckets.items():
print(f'桶子 {bucket}: {content}')

思路2: 分成三桶後,隨機抽球依序丟桶

  • 優點:使用隨機抽球的方式,可以確保較好的隨機性和分布。
  • 缺點:可能需要較多的迴圈運算,如果球數量很大,效率可能較低。
import random

# 10個號碼球
balls = list(range(1, 11))

# 按比例分配球到不同桶子
bucket_a = int(10 * 0.8)
bucket_b = int(10 * 0.1)
bucket_c = int(10 * 0.1)

buckets = {'A': [], 'B': [], 'C': []}

for _ in range(bucket_a):
ball = random.choice(balls)
buckets['A'].append(ball)
balls.remove(ball)

for _ in range(bucket_b):
ball = random.choice(balls)
buckets['B'].append(ball)
balls.remove(ball)

for _ in range(bucket_c):
ball = random.choice(balls)
buckets['C'].append(ball)
balls.remove(ball)

# 印出各桶子裝載的內容
print("A桶:", buckets['A'])
print("B桶:", buckets['B'])
print("C桶:", buckets['C'])

思路3: 對球洗牌,依序分到小桶子

import random

# 10個號碼球
total = 10
balls = list(range(0, total))

# 隨機洗牌
random.shuffle(balls)

# 分成三桶後依序放入桶子
# 0 ~ A的區段
a_size = int(total * 0.8)
start = 0
end = a_size
bucket_a = balls[start:end]

# A ~ B的區段
b_size = int(total * 0.1)
start = a_size
end = a_size + b_size
bucket_b = balls[start:end]

# B ~ C的區段
c_size = int(total * 0.1)
start = a_size + b_size
end = a_size + b_size + c_size
bucket_c = balls[start:end]

print("Bucket A:", bucket_a)
print("Bucket B:", bucket_b)
print("Bucket C:", bucket_c)

優缺點分析

  • 思路1(分成三桶後,依序拿球隨機丟桶): 這方式簡單實作, 但隨機性較差, 因為是以比例抽桶子為出發點下去進行的, 且未依照球的比例下去分配。
  • 思路2(分成三桶後,隨機抽球依序丟桶): 這種方式依照桶子可容納的大小來分別抽球, 可以達到一定的隨機性且能夠依照比例分配, 但缺點是
  • 思路3(對球洗牌,依序分到小桶子): 這種方式會預先對球池進行洗牌, 之後只要按照比例切分球桶並按照可容納的量丟入即可, 易讀、易理解, 運作上較有效率。

結語

原來一個需求可以不只有一種方式可以達到目的, 我們應該深入分析之後選擇一個適合我們的方式下去進行實作,而在這裡我們也提供了三種不同的思路下去解決問題,並分析優缺點,相信這樣的技能不只能夠用在軟體開發,生活上的大小事,也都可以進行深入的分析與決策。

當然過程中也不忘ChatGPT的幫忙,至於應該怎麼問對問題呢? 不妨參考以下的篇章學習提問的技巧:


學習軟體開發的路上常常苦於網路資訊爆炸嗎? 教學何其多,但卻遇到無法明確選擇的困境呢? 歡迎加入「🔒 阿Han的軟體心法實戰營」, 這裡不給您冗餘的雜訊, 單刀直入直接送您業界開發重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。

avatar-img
118會員
266內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
阿Han的沙龍 的其他內容
我們在使用Python語言進行軟體開發時, 常常會需要dict這個資料結構來儲存複雜結構的資料, 就如同JSON一般, 我們會具有這樣的Key/Value模式組成的資料結構, 如下圖: 而當我們在Python的世界裡, 除了嚴謹規範資料欄位的@dataclass之外, 更常使用的就是「di
我們在「【🔒 Python 先修班】👆 打造友善的使用者互動CLI介面」有介紹Python的Click命令列參數設計介面的方式, 那我們除了設計出介面提供使用者互動之外, 有時候也需要一點驗證機制, 畢竟我們心裡都清楚「garbage in, garbage out」的後果, 為了減少這種狀
Python雖然是直譯式的腳本語言, 用起來非常方便, 但當我們的工具越發成熟時, 就會需要將使用方式、介面給設計好, 那通常都會用來處理後端伺服器的作業, 也比較面向IT端, 因此我們通常會以Command Line的形式與使用工具的人進行互動, 而內建模組雖然有「argparse」可以讓我們
排序這個動作在軟體開發中常常會使用到, 從使用者期望所見的順序到資料處理的效能議題都與排序息息相關, 因此掌握程式語言的排序功能是非常重要的一個環節, 而我們在閱讀他人的Go專案程式碼時也會看到排序的方式有些許不同, 那究竟有何差異呢? 就讓我們繼續看下去吧… 其實在進入今天的主題之前, 我們
我們在「【🔒 Python 先修班】⬆️ 培養良好的Coding Style讓專業度 Up!Up!Up!」談到了Coding Style, 在文末也分享了pylint的程式碼檢查工具, 雖然內建、簡單快速上手, 但隨著技術的演進, 我們總需要又快、又好、又簡單的工具做為預設的工具庫, Ruff
撰寫Python的朋友都知道multithread/multiprocess能為我們帶來效能的改進,減少硬體資源的閒置,但在撰寫的過程中常常會發現到我們所設計的工作池模式會需要將「待辦清單」的工作項目當成參數傳遞進去執行, 除了「待辦清單」之外, 其餘的參數基本上都是固定的, 基於這樣的需求之下
我們在使用Python語言進行軟體開發時, 常常會需要dict這個資料結構來儲存複雜結構的資料, 就如同JSON一般, 我們會具有這樣的Key/Value模式組成的資料結構, 如下圖: 而當我們在Python的世界裡, 除了嚴謹規範資料欄位的@dataclass之外, 更常使用的就是「di
我們在「【🔒 Python 先修班】👆 打造友善的使用者互動CLI介面」有介紹Python的Click命令列參數設計介面的方式, 那我們除了設計出介面提供使用者互動之外, 有時候也需要一點驗證機制, 畢竟我們心裡都清楚「garbage in, garbage out」的後果, 為了減少這種狀
Python雖然是直譯式的腳本語言, 用起來非常方便, 但當我們的工具越發成熟時, 就會需要將使用方式、介面給設計好, 那通常都會用來處理後端伺服器的作業, 也比較面向IT端, 因此我們通常會以Command Line的形式與使用工具的人進行互動, 而內建模組雖然有「argparse」可以讓我們
排序這個動作在軟體開發中常常會使用到, 從使用者期望所見的順序到資料處理的效能議題都與排序息息相關, 因此掌握程式語言的排序功能是非常重要的一個環節, 而我們在閱讀他人的Go專案程式碼時也會看到排序的方式有些許不同, 那究竟有何差異呢? 就讓我們繼續看下去吧… 其實在進入今天的主題之前, 我們
我們在「【🔒 Python 先修班】⬆️ 培養良好的Coding Style讓專業度 Up!Up!Up!」談到了Coding Style, 在文末也分享了pylint的程式碼檢查工具, 雖然內建、簡單快速上手, 但隨著技術的演進, 我們總需要又快、又好、又簡單的工具做為預設的工具庫, Ruff
撰寫Python的朋友都知道multithread/multiprocess能為我們帶來效能的改進,減少硬體資源的閒置,但在撰寫的過程中常常會發現到我們所設計的工作池模式會需要將「待辦清單」的工作項目當成參數傳遞進去執行, 除了「待辦清單」之外, 其餘的參數基本上都是固定的, 基於這樣的需求之下
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇Python筆記介紹了List和Dictionary Comprehensions的應用與優勢。通過具體例子展示如何利用這些生成式來進行資料篩選、轉換和整合,並提升程式碼的可讀性和效能。適合新手學習如何用簡潔的語法來快速創建和操作資料結構,幫助你在資料分析中更靈活應用Python。
Python 是一門功能強大且簡潔的程式語言,內建了多種資料結構來幫助開發者處理各種不同的需求。今天,我們將介紹五種常見的資料結構:字串、清單、元組、集合和字典,並學習它們的使用方式。
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: AI說書 - 從0開始 - 180 | RoBERTa 預訓練前言:RoBERTa 預訓練前言 AI說書 - 從0開始 - 181 | 預訓
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: AI說書 - 從0開始 - 180 | RoBERTa 預訓練前言:RoBERTa 預訓練前言 AI說書 - 從0開始 - 181 | 預訓
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 現在我們來準備 Pretrain 模型需要的函數
Thumbnail
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇Python筆記介紹了List和Dictionary Comprehensions的應用與優勢。通過具體例子展示如何利用這些生成式來進行資料篩選、轉換和整合,並提升程式碼的可讀性和效能。適合新手學習如何用簡潔的語法來快速創建和操作資料結構,幫助你在資料分析中更靈活應用Python。
Python 是一門功能強大且簡潔的程式語言,內建了多種資料結構來幫助開發者處理各種不同的需求。今天,我們將介紹五種常見的資料結構:字串、清單、元組、集合和字典,並學習它們的使用方式。
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: AI說書 - 從0開始 - 180 | RoBERTa 預訓練前言:RoBERTa 預訓練前言 AI說書 - 從0開始 - 181 | 預訓
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: AI說書 - 從0開始 - 180 | RoBERTa 預訓練前言:RoBERTa 預訓練前言 AI說書 - 從0開始 - 181 | 預訓
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 準備必備函數庫:AI說書 - 從0開始 - 163
Thumbnail
我想要一天分享一點「LLM從底層堆疊的技術」,並且每篇文章長度控制在三分鐘以內,讓大家不會壓力太大,但是又能夠每天成長一點。 整理目前手上有的素材: 準備資料集:AI說書 - 從0開始 - 162 | 準備Pretrain模型需要的資料 現在我們來準備 Pretrain 模型需要的函數
Thumbnail
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作