【问题标题】:Combinatorics with Number Sets and Correlation Calculation in PythonPython中的数字集组合和相关计算
【发布时间】:2018-01-02 18:07:51
【问题描述】:

我遇到了一个组合数学问题,我什至难以概念化如何使用 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

我正在尝试找到具有最高 Pearson 相关系数的度量 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 个测量值,并且与上面的示例数据集一样,有些测量值没有特定样本的值。度量的值既有负的也有正的,但没有界限。

提前感谢您的帮助。

【问题讨论】:

  • 您想考虑任何组合,Measure1 plus/minus Measure2 plus/minus Measure3 plus/minus Measure4 plus/minus Measure5(当然,如果所有符号都是负号,则相关性将是和所有阳性时一样)?
  • "度量值既有负值也有正值,但没有界限。"这是什么意思?
  • 上面的值都在 -3 到 +7 的范围内,但它们可以是 -10000 到 +10000 之间的任何值(尽管我相信最大值通常在 20 左右)。跨度>
  • 我应该说每个度量的系数是-1、0和1之一。

标签: python set iteration correlation combinatorics


【解决方案1】:
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();

【讨论】:

    【解决方案2】:

    用五个措施来做到这一点是可行的。

    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))
    

    例如,其中一个 measure_combinations 的内积,例如 [1,1,0,-1,-1] 与测量列的每一行将提供一系列值,GoldMeasure 可以在这些值上进行回归以获得一个相关系数,这可以针对 122 种独特的可能性进行。

    但是,对于 41 次测量,将有 18,236,498,188,585,393,202 种独特的可能性,基于 41 次重复 {-1,0,1} 的部分乘积。

    【讨论】:

    • 约泽!那么肯定需要减少措施的数量。感谢您的意见。我可能只需要 10 个就可以做到这一点,这将是大约 30,000 个独特的可能性。
    • 耐心等待15个看起来也是可能的。我讨厌成为坏消息的传播者。
    • 我真的很喜欢“每个度量的系数”的想法来简化问题!
    • 我多么希望这是我最初的想法。 :) 这是否意味着您可能会接受我的回答?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    相关资源
    最近更新 更多