алгоритм в Python для оптимального разделения в поезде, валидации и тестировании - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь оптимизировать распределение выборок по наборам для обучения, проверки и тестирования, например 80%, 10%, 10%. Конкретные проблемы возникают при составлении этих наборов для универсальных зависимостей, которые говорят : «Если банк дерева содержит бегущий текст (а не случайные перемешанные предложения), убедитесь, что вы разбили данные по границам документа». Я просмотрел довольно a несколько страниц о распределении выборки, но все они, похоже, основаны на случайности.

Итак, вот фактические данные моих 80 образцов:

split=[10,10,80]
file2len = {'f0': 2472, 'f1': 1480, 'f2': 592, 'f3': 1439, 'f4': 2310, 'f5': 2081, 'f6': 2201, 'f7': 2647, 'f8': 1998, 'f9': 861, 'f10': 2373, 'f11': 1473, 'f12': 475, 'f13': 2227, 'f14': 3117, 'f15': 2461, 'f16': 880, 'f17': 2781, 'f18': 1041, 'f19': 1620, 'f20': 1294, 'f21': 2274, 'f22': 2640, 'f23': 1920, 'f24': 1756, 'f25': 1476, 'f26': 1675, 'f27': 1484, 'f28': 1432, 'f29': 872, 'f30': 951, 'f31': 1175, 'f32': 655, 'f33': 642, 'f34': 1905, 'f35': 1078, 'f36': 950, 'f37': 1684, 'f38': 1140, 'f39': 1045, 'f40': 771, 'f41': 1035, 'f42': 694, 'f43': 1730, 'f44': 1105, 'f45': 932, 'f46': 1437, 'f47': 2678, 'f48': 1883, 'f49': 1807, 'f50': 951, 'f51': 1924, 'f52': 1417, 'f53': 1739, 'f54': 1902, 'f55': 1950, 'f56': 1959, 'f57': 1630, 'f58': 1588, 'f59': 784, 'f60': 1475, 'f61': 1765, 'f62': 3996, 'f63': 1345, 'f64': 1330, 'f65': 579, 'f66': 1989, 'f67': 806, 'f68': 1301, 'f69': 1888, 'f70': 1380, 'f71': 786, 'f72': 1650, 'f73': 2723, 'f74': 1648, 'f75': 1378, 'f76': 1274, 'f77': 1458, 'f78': 529, 'f79': 2939}
totalt=sum(file2len.values())

Вот функция распределения, которую я использую:

import random
def makedevtraintest(file2len, totalt, split):
    splitfiles=[]
    actualdistri=[]
    infilelist=list(file2len.keys())
    for spli in split:
        already=0
        thisselection=[]
        goal=spli/100*totalt
        while already<goal and infilelist:
            f = random.choice(infilelist)
            already+=file2len[f]
            infilelist.remove(f)
            thisselection+=[f]
        actualdistri+=[already]
        splitfiles+=[thisselection]
    assert infilelist==[]
    return splitfiles, actualdistri

И затем я называю это грубой силой 10000 раз для получения наилучшего распределения:

minidis = 100
for i in range(10000):
    splitfiles, actualdistri = makedevtraintest(file2len, totalt, split)
    dis = abs(actualdistri[-1]/totalt*100-split[-1])        
    if dis<minidis:
        optisplitfiles, optiactualdistri = splitfiles, actualdistri
        minidis=dis
        print('yay',i,dis,[t/totalt for t in actualdistri])
print([t/totalt for t in optiactualdistri])

, что дает вполне приличные результаты: [0.10004576586813117, 0.10002209386737367, 0.7999321402644951] (хотя мой алгоритм будет давать результаты только там, где последний набор образцов не заполнен, <80%). </p>

Мне было интересно, существует ли неэкспоненциальный алгоритм для поиска оптимального распределения, наиболее близкого к 80,10,10. Это похоже на обычную проблему алгоритмики, но я не могу придумать правильные условия поиска, чтобы ее найти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...