python中多元核密度估计的条件采样

Sip*_*Sip 5 python scipy scikit-learn

人们可以使用 scikitlearn ( https://scikit-learn.org/stable/modules/ generated/sklearn.neighbors.KernelDensity.html#sklearn.neighbors.KernelDensity) 和 scipy ( https:// /docs.scipy.org/doc/scipy/reference/ generated/ scipy.stats.gaussian_kde.html )

两者都允许从估计分布中进行随机抽样。有没有办法在两个库(或任何其他库)中进行条件采样?在 2 变量 (x,y) 的情况下,这意味着来自 P(x|y)(或 P(y|x))的样本,因此来自概率函数的横截面(并且该横截面必须重新缩放至其曲线下的单位面积)。

x = np.random.random(100)
y =np.random.random(100)
kde = stats.gaussian_kde([x,y])
# sampling from the whole pdf:
kde.resample()
Run Code Online (Sandbox Code Playgroud)

我正在寻找类似的东西

# sampling y, conditional on x
kde.sample_conditional(x=1.5) #does not exist
Run Code Online (Sandbox Code Playgroud)

Dav*_*ero 1

此函数根据所有其他列有条件地对一列进行采样。

def conditional_sample(kde, training_data, columns, values, samples = 100):
    if len(values) - len(columns) != 0:
        raise ValueError("length of columns and values should be equal")
    if training_data.shape[1] - len(columns) != 1:
        raise ValueError(f'Expected {training_data.shape[1] - 1} columns/values but {len(columns)} have be given')  
    cols_values_dict = dict(zip(columns, values))
    
    #create array to sample from
    steps = 10000  
    X_test = np.zeros((steps,training_data.shape[1]))
    for i in range(training_data.shape[1]):
        col_data = training_data.iloc[:, i]
        X_test[:, i] = np.linspace(col_data.min(),col_data.max(),steps)
    for col in columns: 
        idx_col_training_data = list(training_data.columns).index(col)
        idx_in_values_list = list(cols_values_dict.keys()).index(col)
        X_test[:, idx_col_training_data] = values[idx_in_values_list] 
        
    #compute probability of each sample
    prob_dist = np.exp(kde.score_samples(X_test))/np.exp(kde.score_samples(X_test)).sum()
    
    #sample using np.random.choice
    return X_test[np.random.choice(range(len(prob_dist)), p=prob_dist, size = (samples))]
Run Code Online (Sandbox Code Playgroud)