Python 按分類樣本數占比生成並隨機獲取樣本數據


按分類樣本數占比生成並隨機獲取樣本數據

By:授客 QQ1033553122

開發環境

win 10

python 3.6.5

 

需求

已知樣本分類,每種分類的樣本占比數,及樣本總數,需要隨機獲取這些分類的樣本。比如,我有4種任務,分別為任務A,任務B,任務C,任務D, 每種任務需要重復執行的總次數為1000,每次執行隨機獲取一種任務來執行,不同分類任務執行次數占比為 A:B:C:D = 3:5:7:9

 

 

代碼實現

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-


__author__ = 'shouke'


import random

def get_class_instance_by_proportion(class_proportion_dict, amount):
    """
    根據每種分類的樣本數比例,及樣本總數,為每每種分類構造樣本數據
    class_proportion_dict: 包含分類及其分類樣本數占比的字典:{"分類(id)": 分類樣本數比例}
    amount: 所有分類的樣本數量總和

    返回一個列表:包含所有分類樣本的list

    """

    bucket = []
    proportion_sum = sum([weight for group_id, weight in class_proportion_dict.items()])
    residuals = {} # 存放每種分類的樣本數計算差值
    for class_id, weight in class_proportion_dict.items():
        percent = weight / float(proportion_sum)
        class_instance_num = int(round(amount * percent))
        bucket.extend([class_id for x in range(class_instance_num)])
        residuals[class_id] = amount * percent - round(amount * percent)
    if len(bucket) < amount:
        # 計算獲取的分類樣本總數小於給定的分類樣本總數,則需要增加分類樣本數,優先給樣本數計算差值較小的分類增加樣本數,每種分類樣本數+1,直到滿足數量為止
        for class_id in [l for l, r in sorted(residuals.items(), key=lambda x: x[1], reverse=True)][: amount - len(bucket)]:
            bucket.append(class_id)
    elif len(bucket) > amount:
        # # 計算獲取的分類樣本總數大於給定的分類樣本總數,則需要減少分類樣本數,優先給樣本數計算差值較大的分類減少樣本數,每種分類樣本數-1,直到滿足數量為止
        for class_id in [l for l, r in sorted(residuals.items(), key=lambda x: x[1])][: len(bucket) - amount]:
            bucket.remove(class_id)

    return bucket


class A:
    def to_string(self):
        print('A class instance')

class B:
    def to_string(self):
        print('B class instance')

class C:
    def to_string(self):
        print('C class instance')

class D:
    def to_string(self):
        print('D class instance')

classes_map = {1: A, 2: B, 3:C, 4: D}
class_proportion_dict = {1: 3, 2: 5, 3:7, 4: 9} # {分類id: 樣本數比例} ,即期望4個分類的樣本數比例為為 3:5:7:9
class_instance_num = 1000 # 樣本總數
result_list = get_class_instance_by_proportion(class_proportion_dict, class_instance_num)

for class_id in class_proportion_dict:
    print('%s %s' % (classes_map[class_id], result_list.count(class_id)))

# 制造樣本並隨機獲取樣本
random.shuffle(result_list)
while result_list:
    class_id = random.sample(result_list, 1)[0]
    classes_map[class_id]().to_string()
    result_list.remove(class_id)

  

 

運行結果

 

 

 

 

 

說明

以上方式大致實現思路就是在知道總樣本數的情況下,提前為每種分類生成樣本,然后隨機獲取,按這種方式可以實現比較准確的結果,但是得提前知道樣本總數及不同分類樣本數占比

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM