【问题标题】:Optimization of equation parameter values such that largest distance between groups is created优化方程参数值,以便创建组之间的最大距离
【发布时间】:2021-05-21 17:57:25
【问题描述】:

对于特定的基因评分系统,我想建立一个基本图,以便输入的新样本值根据多个基因测量值立即被吸引到图中的健康或不健康组。假设我们有 5 个人,每个人测量 6 个基因。

Import pandas as pd
import matplotlib.pyplot as plt
import numpy as np


df = pd.DataFrame(np.array([[A, 1, 1.2, 1.4, 2, 2], [B, 1.5, 1, 1.4, 1.3, 1.2], [C, 1, 1.2, 1.6, 2, 1.4], [D, 1.7, 1.5, 1.5, 1.5, 1.4], [E, 1.6, 1.9, 1.8, 3, 2.5], [F, 2, 2.2, 1.9, 2, 2]]), columns=['Gene', 'Healthy 1', 'Healthy 2', 'Healthy 3', 'Unhealthy 1', 'Unhealthy 2'])

这将创建下表:

Gene Healthy 1 Healthy 2 Healthy 3 Unhealthy 1 Unhealthy 2
A 1.0 1.2 1.4 2.0 2.0
B 1.5 1.0 1.4 1.3 1.2
C 1.0 1.2 1.6 2.0 1.4
D 1.7 1.5 1.5 1.5 1.4
E 1.6 1.9 1.8 3.0 2.5
F 2.0 2.2 1.9 2.0 2.0

然后将每个样本的 X 和 Y 坐标在乘以它的参数/权重 * 测量值后基于将基因的贡献加在一起来计算。前 4 个基因对 Y 值有贡献,而基因 5 和 6 决定 X 值。 wA - wF 是与其基因 A-F 对应的参数/权重。

wA = .15 
wB = .25
wC = .35
wD = .45
wE = .50
wF = .60

n=0

for n in range (5):

y1 = df.iat[0,n]
y2 = df.iat[1,n]
y3 = df.iat[2,n]
y4 = df.iat[3,n]

TrueY = wA*y1+wB*y2+wC*y3+wD*y4

x1 = df.iat[4,n]
x2 = df.iat[5,n]

TrueX = (wE*x1+wF*x2)

result = (TrueX, TrueY)

n += 1

label = f"({TrueX},{TrueY})"

plt.scatter(TrueX, TrueY, alpha=0.5)
plt.annotate(label, (TrueX,TrueY), textcoords="offset points", xytext=(0,10), ha='center')

我们因此计算所有坐标并绘制它们

Plot

我现在想做的是找出如何优化 wA-wF 参数/权重,以便将健康样本推向图的原点,比如说 (0.0),而将不健康样本推向图的原点朝着一个合理的相反点,比方说(1,1)。我研究过 K-means/SVM,但作为新手编码器/生物化学家,我完全不知所措,希望能提供任何帮助。

【问题讨论】:

    标签: python machine-learning optimization plot mathematical-optimization


    【解决方案1】:

    这是一个将scipy.optimize 与您的代码结合使用的示例。 (由于您的代码包含一些语法和类型错误,因此我不得不进行一些小的更正。)

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    df = pd.DataFrame(np.array([[1, 1.2, 1.4, 2, 2],
                                [1.5, 1, 1.4, 1.3, 1.2],
                                [1, 1.2, 1.6, 2, 1.4],
                                [1.7, 1.5, 1.5, 1.5, 1.4],
                                [1.6, 1.9, 1.8, 3, 2.5],
                                [2, 2.2, 1.9, 2, 2]]),
                      columns=['Healthy 1', 'Healthy 2', 'Healthy 3', 'Unhealthy 1', 'Unhealthy 2'],
                      index=[['A', 'B', 'C', 'D', 'E', 'F']])
    
    wA = .15
    wB = .25
    wC = .35
    wD = .45
    wE = .50
    wF = .60
    
    from scipy.optimize import minimize
    
    # use your given weights as the initial guess
    w0 = np.array([wA, wB, wC, wD, wE, wF])
    
    # the objective function to be minimized
    # - it computes the (square of) the samples' distances to (0,0) resp. (1,1)
    def fun(w):
        weighted = df.values*w[:, None] # multiply all sample values by their weight
        y = sum(weighted[:4])           # compute all 5 "TrueY" coordinates
        x = sum(weighted[4:])           # compute all 5 "TrueX" coordinates
        y[3:] -= 1                      # adjust the "Unhealthy" y to the target (x,1)
        x[3:] -= 1                      # adjust the "Unhealthy" x to the target (1,y)
        return sum(x**2+y**2)           # return the sum of (squared) distances
    
    res = minimize(fun, w0)
    print(res)
    
    # assign the optimized weights back to your parameters
    wA, wB, wC, wD, wE, wF = res.x
    
    # this is mostly your unchanged code
    for n in range (5):
    
        y1 = df.iat[0,n]
        y2 = df.iat[1,n]
        y3 = df.iat[2,n]
        y4 = df.iat[3,n]
    
        TrueY = wA*y1+wB*y2+wC*y3+wD*y4
    
        x1 = df.iat[4,n]
        x2 = df.iat[5,n]
    
        TrueX = (wE*x1+wF*x2)
    
        result = (TrueX, TrueY)
    
        label = f"({TrueX:.3f},{TrueY:.3f})"
    
        plt.scatter(TrueX, TrueY, alpha=0.5)
        plt.annotate(label, (TrueX,TrueY), textcoords="offset points", xytext=(0,10), ha='center')
    
    plt.savefig("mygraph.png")
    

    这将产生参数[ 1.21773653, 0.22185886, -0.39377451, -0.76513658, 0.86984207, -0.73166533] 作为解决方案数组。由此我们可以看到健康样本聚集在 (0,0) 附近,不健康样本聚集在 (1,1) 附近:

    您可能想尝试其他优化方法 - 请参阅 scipy.optimize.minimize

    【讨论】:

    • 看起来很棒!我遇到的最后一个问题是关于以下行: y[3:] -= 1 x[3:] -= 1 对于我的实际数据集,我有 9 列,最后 4 列是“不健康”列。然后我是否应该将其更改为 y[5:] 和 x[5:] 以进行相应调整,以便现在将最后 4 列视为不健康的样本?
    • 最后,我再次为这个非常愚蠢的问题道歉。但我目前也在尝试将散点图中每个点的注释更改为对应于列标题中的名称,即 IE 健康 1、健康 2 等,而不是坐标。你介意帮忙吗?再次,非常感谢所有无价的支持。
    • 我们只需要设置label = df.columns[n]
    猜你喜欢
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    相关资源
    最近更新 更多