Python 迭代二维回归相关截断正态/拉普拉斯分布

Python 迭代二维回归相关截断正态/拉普拉斯分布,python,random,distribution,Python,Random,Distribution,我需要你的帮助来创建一个正常的或更好的截断的拉普拉斯分布,它线性地依赖于另一个拉普拉斯分布变量 不幸的是,到目前为止,我在推导的y分布中使用NaN实现了这一点: import numpy as np from matplotlib import pyplot as plt from scipy.stats import gaussian_kde, truncnorm slope = 0.2237 intercept = 1.066 spread = 4.8719 def dependency

我需要你的帮助来创建一个正常的或更好的截断的拉普拉斯分布,它线性地依赖于另一个拉普拉斯分布变量

不幸的是,到目前为止,我在推导的y分布中使用NaN实现了这一点:

import numpy as np
from matplotlib import pyplot as plt
from scipy.stats import gaussian_kde, truncnorm

slope = 0.2237
intercept = 1.066
spread = 4.8719

def dependency(x):
    y_lin = slope * x + intercept
    lower = slope / spread * 3 * x
    upper = slope * spread / 3 * x + 2 * intercept

    y_lin_noise = np.random.laplace(loc=0, scale=spread, size=len(y_lin)) + y_lin

    y_lin_noise[y_lin_noise < lower] = np.nan  # This is the desperate solution where
    y_lin_noise[y_lin_noise > upper] = np.nan  # NaNs are introduced

    return y_lin_noise

max = 100
min = 1
mean = 40
sigma = 25

x = truncnorm((min-mean)/sigma, (max-mean)/sigma, loc=mean, scale=sigma).rvs(5000)
y = dependency(x)

# Plotting
xx = np.linspace(np.nanmin(x), np.nanmax(x), 100)
yy = slope * xx + intercept
lower = slope/spread*3*xx
upper = slope*spread/3*xx + 2*intercept

mask = ~np.isnan(y) & ~np.isnan(x)
x = x[mask]
y = y[mask]

xy = np.vstack([x, y])
z = gaussian_kde(xy)(xy)
idz = z.argsort()
x, y, z = x[idz], y[idz], z[idz]

fig, ax = plt.subplots(figsize=(5, 5))
plt.plot(xx, upper, 'r-.', label='upper constraint')
plt.plot(xx, lower, 'r--', label='lower constraint')

ax.scatter(x, y, c=z, s=3)
plt.xlabel(r'$\bf X_{laplace}$')
plt.ylabel(r'$\bf Y_{{derived}}$')
plt.plot(xx, yy, 'r', label='regression model')
plt.legend()
plt.tight_layout()
plt.show()
将numpy导入为np
从matplotlib导入pyplot作为plt
从scipy.stats导入gaussian_kde,truncnorm
斜率=0.2237
截距=1.066
价差=4.8719
def依赖项(x):
y_lin=斜率*x+截距
下=坡度/扩展*3*x
上限=坡度*扩展/3*x+2*截距
y_lin_noise=np.random.laplace(loc=0,scale=spread,size=len(y_lin))+y_lin
y_lin_noise[y_lin_noise上限]=np.nan#NaNs
返回y_林_噪音
最大值=100
最小值=1
平均值=40
西格玛=25
x=truncnorm((最小平均值)/sigma,(最大平均值)/sigma,loc=mean,scale=sigma)。rvs(5000)
y=依赖关系(x)
#策划
xx=np.linspace(np.nanmin(x),np.nanmax(x),100)
yy=斜率*xx+截距
下=坡度/扩展*3*xx
上=坡度*扩展/3*xx+2*截距
掩码=~np.isnan(y)&~np.isnan(x)
x=x[遮罩]
y=y[遮罩]
xy=np.vstack([x,y])
z=高斯分布(xy)(xy)
idz=z.argsort()
x、 y,z=x[idz],y[idz],z[idz]
图,ax=plt.子批次(图尺寸=(5,5))
plt.plt(xx,上,'r-',标签='上约束')
plt.plot(xx,下,'r--',label='lower constraint')
最大散射(x,y,c=z,s=3)
plt.xlabel(r'$\bf X{laplace}$')
plt.ylabel(r'$\bf Y{{{derived}}}$')
plt.plot(xx,yy,'r',label='回归模型')
plt.legend()
plt.紧_布局()
plt.show()

最后我想得到的是一个没有NaN的y分布,因此对于每个x,在上/下阈值范围内都有一个对应的y。也就是说,围绕回归线的上下截短分布

我期待着新的想法


谢谢您并向您致意。

您要做的基本上是重试超出您界限的值。您可以定义一个函数,对每个值执行此操作,或者您可以定义初始值,并通过答案循环“更正”超出范围的值,如下所示:

import numpy as np
from matplotlib import pyplot as plt
from scipy.stats import gaussian_kde, truncnorm

slope = 0.2237
intercept = 1.066
spread = 4.8719


#slow but effective
def truncated_noise(y, lower, upper):
    while True:
        y_noise = np.random.laplace(loc=0, scale=spread, size=1) + y
        if upper > y_noise > lower:
            return y_noise


def refine_noise(y, y_lin_noise, lower, upper):
    for i in range(len(y_lin_noise)):
        if upper[i] < y_lin_noise[i] or lower[i] > y_lin_noise[i]:
            y_lin_noise[i] = truncated_noise(y[i], lower[i], upper[i])
    return y_lin_noise


def dependency(x):
    y_lin = slope * x + intercept
    lower = slope / spread * 3 * x
    upper = slope * spread / 3 * x + 2 * intercept

    y_lin_noise = np.random.laplace(loc=0, scale=spread, size=len(y_lin)) + y_lin

    y_lin_noise = refine_noise(y_lin, y_lin_noise, lower, upper)

    return y_lin_noise

max = 100
min = 1
mean = 40
sigma = 25

x = truncnorm((min-mean)/sigma, (max-mean)/sigma, loc=mean, scale=sigma).rvs(5000)
y = dependency(x)

# Plotting
xx = np.linspace(np.nanmin(x), np.nanmax(x), 100)
yy = slope * xx + intercept
lower = slope/spread*3*xx
upper = slope*spread/3*xx + 2*intercept


xy = np.vstack([x, y])
z = gaussian_kde(xy)(xy)
idz = z.argsort()
x, y, z = x[idz], y[idz], z[idz]

fig, ax = plt.subplots(figsize=(5, 5))
plt.plot(xx, upper, 'r-.', label='upper constraint')
plt.plot(xx, lower, 'r--', label='lower constraint')

ax.scatter(x, y, c=z, s=3)
plt.xlabel(r'$\bf X_{laplace}$')
plt.ylabel(r'$\bf Y_{{derived}}$')
plt.plot(xx, yy, 'r', label='regression model')
plt.legend()
plt.tight_layout()
plt.show()
将numpy导入为np
从matplotlib导入pyplot作为plt
从scipy.stats导入gaussian_kde,truncnorm
斜率=0.2237
截距=1.066
价差=4.8719
#慢而有效
def截断_噪声(y、下部、上部):
尽管如此:
y_噪声=np.随机.拉普拉斯(loc=0,比例=spread,大小=1)+y
如果上部>y_噪波>下部:
返回y_噪声
def优化噪音(y、y、lin噪音、下部、上部):
对于范围内的i(len(y_lin_噪声)):
如果上[i]y_林_噪声[i]:
y_-lin_噪声[i]=截断的_噪声(y[i],下[i],上[i])
返回y_林_噪音
def依赖项(x):
y_lin=斜率*x+截距
下=坡度/扩展*3*x
上限=坡度*扩展/3*x+2*截距
y_lin_noise=np.random.laplace(loc=0,scale=spread,size=len(y_lin))+y_lin
y_-lin_噪波=细化_噪波(y_-lin,y_-lin_噪波,下部,上部)
返回y_林_噪音
最大值=100
最小值=1
平均值=40
西格玛=25
x=truncnorm((最小平均值)/sigma,(最大平均值)/sigma,loc=mean,scale=sigma)。rvs(5000)
y=依赖关系(x)
#策划
xx=np.linspace(np.nanmin(x),np.nanmax(x),100)
yy=斜率*xx+截距
下=坡度/扩展*3*xx
上=坡度*扩展/3*xx+2*截距
xy=np.vstack([x,y])
z=高斯分布(xy)(xy)
idz=z.argsort()
x、 y,z=x[idz],y[idz],z[idz]
图,ax=plt.子批次(图尺寸=(5,5))
plt.plt(xx,上,'r-',标签='上约束')
plt.plot(xx,下,'r--',label='lower constraint')
最大散射(x,y,c=z,s=3)
plt.xlabel(r'$\bf X{laplace}$')
plt.ylabel(r'$\bf Y{{{derived}}}$')
plt.plot(xx,yy,'r',label='回归模型')
plt.legend()
plt.紧_布局()
plt.show()

我不知道你想用它做什么,但我知道这不再是一个随机拉普拉斯分布,所以如果你的函数需要它,千万不要这样做

您要做的基本上是重试超出您边界的值。您可以定义一个函数,对每个值执行此操作,或者您可以定义初始值,并通过答案循环“更正”超出范围的值,如下所示:

import numpy as np
from matplotlib import pyplot as plt
from scipy.stats import gaussian_kde, truncnorm

slope = 0.2237
intercept = 1.066
spread = 4.8719


#slow but effective
def truncated_noise(y, lower, upper):
    while True:
        y_noise = np.random.laplace(loc=0, scale=spread, size=1) + y
        if upper > y_noise > lower:
            return y_noise


def refine_noise(y, y_lin_noise, lower, upper):
    for i in range(len(y_lin_noise)):
        if upper[i] < y_lin_noise[i] or lower[i] > y_lin_noise[i]:
            y_lin_noise[i] = truncated_noise(y[i], lower[i], upper[i])
    return y_lin_noise


def dependency(x):
    y_lin = slope * x + intercept
    lower = slope / spread * 3 * x
    upper = slope * spread / 3 * x + 2 * intercept

    y_lin_noise = np.random.laplace(loc=0, scale=spread, size=len(y_lin)) + y_lin

    y_lin_noise = refine_noise(y_lin, y_lin_noise, lower, upper)

    return y_lin_noise

max = 100
min = 1
mean = 40
sigma = 25

x = truncnorm((min-mean)/sigma, (max-mean)/sigma, loc=mean, scale=sigma).rvs(5000)
y = dependency(x)

# Plotting
xx = np.linspace(np.nanmin(x), np.nanmax(x), 100)
yy = slope * xx + intercept
lower = slope/spread*3*xx
upper = slope*spread/3*xx + 2*intercept


xy = np.vstack([x, y])
z = gaussian_kde(xy)(xy)
idz = z.argsort()
x, y, z = x[idz], y[idz], z[idz]

fig, ax = plt.subplots(figsize=(5, 5))
plt.plot(xx, upper, 'r-.', label='upper constraint')
plt.plot(xx, lower, 'r--', label='lower constraint')

ax.scatter(x, y, c=z, s=3)
plt.xlabel(r'$\bf X_{laplace}$')
plt.ylabel(r'$\bf Y_{{derived}}$')
plt.plot(xx, yy, 'r', label='regression model')
plt.legend()
plt.tight_layout()
plt.show()
将numpy导入为np
从matplotlib导入pyplot作为plt
从scipy.stats导入gaussian_kde,truncnorm
斜率=0.2237
截距=1.066
价差=4.8719
#慢而有效
def截断_噪声(y、下部、上部):
尽管如此:
y_噪声=np.随机.拉普拉斯(loc=0,比例=spread,大小=1)+y
如果上部>y_噪波>下部:
返回y_噪声
def优化噪音(y、y、lin噪音、下部、上部):
对于范围内的i(len(y_lin_噪声)):
如果上[i]y_林_噪声[i]:
y_-lin_噪声[i]=截断的_噪声(y[i],下[i],上[i])
返回y_林_噪音
def依赖项(x):
y_lin=斜率*x+截距
下=坡度/扩展*3*x
上限=坡度*扩展/3*x+2*截距
y_lin_noise=np.random.laplace(loc=0,scale=spread,size=len(y_lin))+y_lin
y_-lin_噪波=细化_噪波(y_-lin,y_-lin_噪波,下部,上部)
返回y_林_噪音
最大值=100
最小值=1
平均值=40
西格玛=25
x=truncnorm((最小平均值)/sigma,(最大平均值)/sigma,loc=mean,scale=sigma)。rvs(5000)
y=依赖关系(x)
#策划
xx=np.linspace(np.nanmin(x),np.nanmax(x),100)
yy=斜率*xx+截距
下=坡度/扩展*3*xx
上=坡度*扩展/3*xx+2*截距
xy=np.vstack([x,y])
z=高斯分布(xy)(xy)
idz=z.argsort()
x、 y,z=x[idz],y[idz],z[idz]
图,ax=plt.子批次(图尺寸=(5,5))
plt.plt(xx,上,'r-',标签='上约束')
plt.plot(xx,下,'r--',label='lower constraint')
最大散射(x,y,c=z,s=3)
plt.xlabel(r'$\bf X{laplace}$')
plt.ylabel(r'$\bf Y{{{derived}}}$')
plt.plot(xx,yy,'r',label='回归模型')
plt.legend()
plt.紧_布局()
pl