У меня есть небольшая проблема комбинаторики, и мне трудно даже представить, как я буду это делать с помощью itertools. Мой набор данных выглядит так:

GoldMeasure Measure1 Measure2 Measure3 Measure4 Measure5 3+4-5

  30.501       -1      -1       -1        -1       -1     -1
  30.658       -1      -1        0        -1       -1      0
  31.281       -1               -1        -1        1     -3
  31.506        7      -1       -1         1       -1      1
  31.554       -1      -1       -1        -1       -1     -1
  31.613       -1      -1       -1         1               0
  31.838       -1      -1       -1        -1              -2
  31.954       -1      -1       -1         1       -1      1
  33.073        1       1                  1       -1      2
  33.592       -2      -2        2         0       -2      4

Coefficient: -0.054    0.119   0.690     0.474   -0.441  0.723

Я пытаюсь найти лучшую комбинацию мер 1-5, которая имеет самый высокий коэффициент корреляции Пирсона с золотой мерой. В приведенном выше наборе данных лучшим единичным показателем является Третья мера с коэффициентом 0,69. Однако, если вы добавите Третью Меру к Четвертой, а затем вычтите Меру Пятую, вы получите новую комбинированную меру с коэффициентом 0,72. По сути, я хочу определить коэффициент корреляции для всех возможных комбинаций этих пяти мер. Эти комбинации могут быть 2/5 тактов, 3/5 тактов (как в примере выше), 4/5 тактов или все пять тактов.

Порядок в некоторой степени важен. Это правда, что аддитивная комбинация мер 3, 4 и 5 такая же, как аддитивная комбинация мер 5, 3 и 4; однако я также пытаюсь включить арифметический оператор в качестве другого варианта (сложение или вычитание). Таким образом, 3 + 4 + 5 то же самое, что 5 + 3 + 4, но 3 + 4-5 не то же самое, что 5 + 3-4.

Будем очень признательны за любое руководство или помощь. Фактический набор данных состоит из 46 показателей, и, как и в приведенном выше примере набора данных, есть некоторые показатели, не имеющие значений для конкретных выборок. Значения мер могут быть как отрицательными, так и положительными, но не ограничены.

Спасибо заранее за любую помощь.

0
user9164951 2 Янв 2018 в 21:07

2 ответа

Лучший ответ
from collections import defaultdict
import statistics
import itertools
import scipy.stats
import heapq

#Please add a filename here and use a .csv format.
F=open('filename','r').readlines();

F[0].strip().split(',');
HEADER=[r.strip() for r in F[0].strip().split(',')[2:]];

DDF={};
DDP={};
DDN={};
DDG={};
#Please replace missing values using Excel into "NAA". I have replaced the "NAA"/missing values with average of the column. You may also consider ignoring missing rows before doing correlation between 2 columns.
for f in F[1:]:
    DATA=f.strip().split(',');
    ATAD=[[i.strip(),j.strip()] for i,j in zip(HEADER,DATA[2:])];
    for atad in ATAD:
        if atad[0].strip() in DDF.keys():
            DDF[atad[0].strip()].append(atad[1].strip());
        else:
            DDF[atad[0].strip()]=[atad[1].strip()];

    if F[0].strip().split(',')[1].strip() in DDG.keys():
        DDG[F[0].strip().split(',')[1].strip()].append(float(DATA[1].strip()));
    else:
        DDG[F[0].strip().split(',')[1].strip()]=[float(DATA[1].strip())];

for ke in DDF.keys():
    AVGP=statistics.mean([float(u) for u in DDF[ke.strip()] if u.strip()!='NAA']);
    NEWP=[float(nr.strip()) if nr.strip()!='NAA' else AVGP for nr in DDF[ke.strip()]];
    if ke in DDP.keys():
        DDP[ke.strip()]=NEWP;
    else:
        DDP[ke.strip()]=NEWP;
    AVGN=statistics.mean([-1*float(e) for e in DDF[ke.strip()] if e.strip()!='NAA']);
    NEWN=[-1*float(ne.strip()) if ne.strip()!='NAA' else AVGN for ne in DDF[ke.strip()]];
    if 'minus_'+ke.strip() in DDN.keys():
        DDN['minus_'+ke.strip()]=NEWN;
    else:
        DDN['minus_'+ke.strip()]=NEWN;
U=0;
L1=DDP.keys()+DDN.keys();
N=range(1,len(L1));
U=[0,0,-1];

for n in N:
    DDU=[];
    for subset in itertools.combinations(L1,n):
        S=[];
        SSET=[sset.strip().replace('minus_','') if sset.strip().startswith('minus_') else sset.strip() for sset in list(subset)];
        if len(set(SSET))>=len(subset):
            TMP=[DDN[p.strip()] if p.strip().startswith('minus_') else DDP[p.strip()] for p in subset];
            for y in range(0,len(TMP[0])):
                for x in TMP:
                    S.append(x[y]);
            SUM=[sum(S[w:w + n]) for w in range(0, len(S),n)];
            K=['+'.join(list(subset)).strip()]+[' vs Cq TREC']+list(scipy.stats.pearsonr(SUM,DDG['Cq TREC']));
            if str(K[-2])!='nan':
                DDU.append([K[-2],K]);
    DDU.sort(key=lambda x: x[0],reverse=True);
    for ea in DDU[0:3]:
        print repr(n).strip()+','+ea[1][0].strip().replace('+minus_','-').replace('minus_','-')+' '+ea[1][1].strip()+','+repr(ea[1][-2]).strip();
1
mparida 12 Янв 2018 в 15:40

Сделать это можно с помощью пяти мер.

from itertools import product
from numpy import negative, array_equal

choices = [1, 0, -1]
measures = 5
limit = len(choices)**measures//2+1
count = 0
measure_combinations = []
for p in product(*([choices]*5)):
    measure_combinations.append(list(p))
    count += 1
    if count == limit:
        break

print (len(measure_combinations))

Например, внутреннее произведение одной из комбинаций показателей, скажем [1,1,0, -1, -1] с каждой строкой столбцов мер предоставит серию значений, по которым GoldMeasure может быть регрессирован для получения коэффициента корреляции , и это могло быть сделано для 122 уникальных возможностей.

Однако для 41 измерения будет 18 236 498 188 585 393 202 уникальных возможности, основанных на части произведения 41 повторения {-1,0,1}.

1
Bill Bell 2 Янв 2018 в 19:48