三变量相关分析:将一个变量分类为区间,以实现其他两个变量之间更好的相关性

2024-06-07 07:03:00 发布

您现在位置:Python中文网/ 问答频道 /正文

<^ >this post和我无法理解约翰逊-奈曼[JN]区间计算方法,我正在考虑走出方框,并考虑其他算法做三变量(多元变量之间的三个变量)的相关性分析。考虑下面的熊猫数据帧:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import pearsonr, spearmanr, kendalltau, pointbiserialr

np.random.seed(42)

x1 = np.random.rand(10) * 10
x2 = np.random.rand(10) * 10
x3 = np.random.rand(10) * 10

x = np.concatenate((x1, x2, x3))

y1 = 1.5 * x1 + (np.random.rand(10) - 0.5) * 3.5
y2 = 0.5 * x2 + (np.random.rand(10) - 0.5) * 4.1
y3 = 3.0 * x3 + (np.random.rand(10) - 0.5) * 2.4

y = np.concatenate((y1, y2, y3))

M = [1.5, 5.5]

m1 = np.random.rand(10) * M[0]
m2 = np.random.rand(10) * (M[1] - M[0]) + M[0]
m3 = np.random.rand(10) * 2 + M[1]

m = np.concatenate((m1, m2, m3))

df = pd.DataFrame({'X': x, 'Y': y, 'M': m})
df = df.sample(frac=1).reset_index(drop=True)

现在我需要一个函数:

classify_moderator(dataframe=df, predictor="x", response="y", moderator="m")

它为m返回一个或多个值的列表,该列表将数据帧划分为两个或多个重要的相关组。例如,对于上面的数据帧,我们应该得到M = [1.5, 5.5],其中df["m"] < M[0]M[0] < df["m"] < M[1]M[1] < df["m"]的组df["x"]df["y"]的子组之间的关联在二元相关分析算法(如Pearson、Kendall、Spearman和Point Biserial方法)方面强于总数据帧。重要的是,我们不知道到底有多少感兴趣的分区。它可以是两个或更多。但如果它使方法变得不必要的复杂,我们也可以假设这个数字

与启发式方法相比,我更喜欢传统方法(如scipy.optimize模块),因为它们可以帮助我更好地理解基础数学,但在其他方面也很受欢迎。提前感谢您的支持

p.S.1.这里是我第一次尝试分成两组失败:

def groupedCor(modValue, dataframe, predictor, response, moderator):

    df1 = dataframe.loc[dataframe[moderator] < modValue]
    df2 = dataframe.loc[modValue <= dataframe[moderator]]

    return pearsonr(df1[predictor], df1[response])[1] + pearsonr(df2[predictor], df2[response])[1]

M1 = (df["M"].max() - df["M"].min()) / 2 + df["M"].min()

M1 = fmin(groupedCor, x0=M1, args=(df, "X", "Y", "M"))

作为我尝试做的一个例子。如果我能理解上述代码段失败的原因:

ValueError: Lengths must match to compare

那我就可以自己解决这个问题了

p.S.2.我意识到,没有一种双变量相关分析方法能够代表良好的拟合。所以我使用了线性回归的r平方:

from sklearn.linear_model import LinearRegression

def groupedScore(modValue, dataframe, predictor, response, moderator):
    df1 = dataframe[dataframe[moderator] < modValue]
    df2 = dataframe[modValue <= dataframe[moderator]]

    x1 = df1[predictor].values
    x1_ = x1.reshape((-1, 1))
    y1 = df1[response].values
    model1 = LinearRegression().fit(x1_, y1)

    x2 = df2[predictor].values
    x2_ = x2.reshape((-1, 1))
    y2 = df2[response].values
    model2 = LinearRegression().fit(x2_, y2)

    return (model1.score(x1_, y1) + model2.score(x2_, y2)) / 2

def groupedScore_v(x, dataframe, predictor, response, moderator):
    return [[groupedScore(xi, dataframe, predictor, response, moderator) for xi in x[2:-1]], x[2:-1]]

scores = groupedScore_v(np.sort(df["M"].values).tolist(), df, "X", "Y", "M")

plt.plot(np.asarray(scores[1]), np.asarray(scores[0]))

其结果是:

这是一个非常可怕的结果


Tags: importdataframedfresponsenprandompredictordf1