python - 三变量相关性分析:将一个变量分类为区间,以实现其他两个变量之间更好的相关性
问题描述
在这篇文章和我无法理解 Johnson-Neyman [JN] 区间计算方法之后,我正在考虑开箱即用并考虑其他算法来进行三变量(三个变量之间的多元)相关分析。考虑下面的 Pandas 数据框:
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"]
子组之间的关联性在双变量相关分析算法方面强于总数据框,例如 Pearson、Kendall、Spearman 和点双列方法。重要的是要考虑到我们并不确切知道有多少感兴趣的分区。它可以是两个或更多。但是如果它使方法变得不必要地复杂,我们也可以假设这个数字。df["x"]
df["y"]
我更喜欢传统方法(例如,scipy.optimize
模块)而不是启发式方法,因为它们可以帮助我更好地理解基础数学,但除此之外也值得赞赏。提前感谢您的支持。
PS1。这是我第一次失败的尝试分成两组:
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:长度必须匹配才能进行比较
那么我可能可以自己解决问题。
PS2。我意识到,没有一种双变量相关分析方法能代表良好的拟合。所以我使用了线性回归的 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]))
这导致:
这是一个非常奇怪的结果!
解决方案
推荐阅读
- hibernate-search - 带有 Infinispan 目录提供程序的 Hibernate Search 6
- php - 带循环计算的 PHP
- python - 如何在数据框路径中使用变量名
- linux - 使用模板文件和输入文件在子目录下生成多个文件
- javascript - 复杂数组需要更新和添加新对象但只添加
- typescript - 使用 Firebase 9 兼容模式时出现打字稿错误
- bash - Bash - 将现有变量值分配给新变量。新变量值不返回分配的值
- sql - SQL Server:获取最新插入/更新行的有效索引?
- django - 两个容器之间的Django“连接失败”
- python - 如何创建自定义序列化处理程序?