大数据/由于零方差而自动列消除你好
我正在分析一个非常大的数据集,列中至少有大约 2000 个参数。 我的示例具有约 250k 行的这些参数值。 我的问题是列,而不是行。
我为所有样本定义了一个离散分类,两个离散值,例如 A 类和 B 类。
我正在另一个软件中进一步分析数据,如果它检测到方差为零(或非常接近)的参数,则该软件会失败。
我不想手动完成这项工作(正如你可以从 2000 列中想象到的那样)。
我正在寻找一种尽可能自动化的方法来删除 A 类或 B 类方差为零(或低于定义的非常小的阈值)的列。 我按照步骤完成工作,但我不想手动选择任何列来进行删除。
任何帮助将不胜感激。提前致谢。
回复:大数据/由于零方差而自动列消除布雷迪,
下面的脚本对您的脚本进行了轻微修改,应该作为起点。(对 stdev 进行一些细微修改,与阈值进行比较)。 如您所知,我需要一个实际的脚本来进一步进行,因为此删除将由脚本自动完成。 JMP 数据选择之后的下一阶段内部代码在遇到零方差时尤其会出现问题。 您之前的版本(即下面)证明这些可以被删除。我虽然试图避免删除带有均值差异但方差为零的参数。
我无法使用依赖于实际参数平均值和分布的阈值。例如 我无法指定实际差异,因为这需要深入检查所有 2000 个参数,不可行。 不确定我是否提到过,但 2000 年只是冰山一角,更多的还在后面。 然而,单个数据集包含大约 2000 个参数。
我可以使用 p_value 来过滤传入或传出的参数,具体取决于哪些参数会导致我们的内部代码失败。 我认为从这个角度来看,t 检验可能是一个更好的选择。 但是,我不知道如何插入 t 检验并提取 p_value ....所以我可以将其添加为附加过滤器。
我感觉我有两个选择...
1)我要么按原样使用下面的代码,而不进行进一步的 2 个样本均值比较。 即使平均值不同,它也会删除所有此类情况。 然后,我需要记录那些被删除的列名称(需要帮助),以便在整个研究结束时,我可以将注意力转向它们并在 jmp 中分析它们以检测均值差异(如果有)。 从百分比来看,这将是一个小得多的参数分析集,我预计零方差情况将是数据集的很小一部分。
2)或者我的第二个选择是添加 t 检验或任何其他提供标准化阈值的检验,以微调显着差异的总体。 例如。 我可以使用 p_value 来确认或拒绝显着性。
你怎么认为 ?
谢谢
-------------------------------------------------- -------------------------------------------------- -------------
名称默认为此处( 1 );
dt = 当前数据表();
dtcol1 = 列(dt, 1);
dt1 = dt << 子集(行(dt<<获取行其中(ascolumn(dtcol1) == dtcol1[1])), 不可见, 选定的列(0));
dt2 = dt << 子集(行(dt<<获取行其中(ascolumn(dtcol1) != dtcol1[1])), 不可见, 选定的列(0));
// 获取所有连续数据列
colList = dt << 获取列名(数字,连续);
// 遍历所有列并找到没有方差的列
For( i = N Items( collist ), i >= 1, i--,
If( (列标准差( 列( dt1, colList[i] ) ) ) >= 0.01 & 列标准差( 列( dt2, colList[i] ) ) >= 0.01,
colList = 删除( colList, i, 1 )
)
);
// 删除没有方差的列
dt<<删除列(colList);
关闭(dt1,nosave);
关闭(dt2,nosave);
注意:stdev 的阈值尚未确定。 0.01 只是一个例子。 会对此进行微调。
回复:大数据/由于零方差而自动列消除<<经过编辑以反映有 ~250,000 行,而不是 ~2,000,这是列数。>>
Altug,有件事我想澄清一下:你有大约 25 万行数据,分为两组,我假设(默认情况下)它们的大小大致相同。 如果是这样,则每组包含 125,000 个样本的 t 检验的功效 = 0.9,可检测到小于 1/50 西格玛的差异。 鉴于您只有在一个或两个西格玛水平非常低时才达到这一点(测试手段),那么您认为如此小的(相对于西格玛)差异是否具有实际重要性? 即,如果您有 2 个进程,且 sigma 大致 = 1 个单位,那么 0.018 个单位的均值差异对您来说重要吗? 这就是当每组中有 125,000 个项目时 t 检验的敏感度。
如果在您的设置中,如此小的差异并不重要,那么您最好使用等价检验(最简单的形式 2,同时,单边 t 检验),它允许您指定差异有多大是有意义的。 差异小于该量的手段被认为实际上是等效的。 使用这种方法,只要平均值实际上相等并且至少有一个组标准差低于阈值,就可以删除给定的列。
这是一些信息和示例:
http://www.jmp.com/support/help/Equivalence_Test.shtml
回复:大数据/由于零方差而自动列消除谢谢杜安。
我试图通过特定的输出和比较来确定脚本中的参数是否与 A 类和 B 类不同。 我并不是试图分析中间结果表然后做出决定。
我在给定数据集中有 2000 个参数列以及许多大小相当的数据集。
对于给定参数,该过程需要自动删除在两个类 A 和 B 之间发现几乎相同的相关列。
我最初将其写为零方差寻求逻辑,但问题是两个具有零方差但具有不同平均值的参数不应被删除。 从那时起,我开始更改逻辑以包含用于比较 2 个样本均值检验的检验。
我的问题是我在脚本编写方面非常新手,不知道如何从给定平台的结果中调用参数。
我的数据中的另一个问题是您在脚本中指定了所有参数,这样做甚至可能被证明非常耗时(也许有一个足够简单的方法)。
Brady 的脚本实际上近乎完美,只是我需要添加 2 个样本的均值测试,并了解如何使用其输出作为附加过滤器。
感谢您的帮助。
回复:大数据/由于零方差而自动列消除精确的测试可能需要很长时间才能计算,并且考虑到数据表中有 250,000 行,我敢打赌在这种情况下它们不会被计算。我建议改为使用
Summarize YByX()
命令计算所有 Fit Y By X 组合,并为每个 y/x 组合生成 p 值和 LogWorth 值的数据表。然后您可以确定正确的列以进一步调查。您需要在单独的步骤中测试零方差。
回复:大数据/由于零方差而自动列消除布雷迪
我在一个示例数据集(还不是很大的数据集)上对此进行了测试,以了解其中的机制。 我已经能够修改它以在圣上设置阈值。开发人员。而不是要求0。 我剩下的问题是,我不想在以下情况下删除数据
stdev<=阈值(即接近0)和数据平均值(A类和B类的参数)是不同的。
因此,我需要添加一个测试来比较 A 和 B 的平均值,作为进一步的附加约束。
我正在考虑 Kolmogorov-Smirnov 测试...在这种情况下我可以简单地声明“如果 KS <= thrreshold(实际上接近 0)则删除参数”
事实上,我想做的是向下选择下一步不同的参数。 所以我开始想也许最好的办法就是应用 KS(不需要 stdev)。
JMP 帮助提供
名称默认为此处( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
obj = Oneway( Y( : 身高 ), X( : 性别 ) );
obj << 柯尔莫哥洛夫·斯米尔诺夫精确检验( 1 );
这可以翻译成我的情况吗(在当前循环内)
obj=Oneway( Y(:Column( dt1, colList[i] ), X( Column( dt2, colList[i] ) ) );
obj << 柯尔莫哥洛夫·斯米尔诺夫精确检验( 1 );
但我不知道如何从这个 obj 对象中提取 KS 值。
顺便说一句,我认为 2000 列的 cpu 时间不会困扰我,因为我愿意采取任何措施来避免对数据进行任何手动操作。
非常感谢。
回复:大数据/由于零方差而自动列消除吉姆,
在此感谢您的指导。 我会尝试一下。再次感谢。
回复:大数据/由于零方差而自动列消除你的理解是正确的,布雷迪。唯一要强调的是,有 250,000 行,这变成了 2000 x 250,000 的矩阵。
回复:大数据/由于零方差而自动列消除由于选择反转与两次选择,这个块与前一个块相比又花了十分之一秒。 在更大的桌子上获得更大的收益。
dtcol1 = column(dt, 1);
dt << select where(ascolumn(dtcol1) == dtcol1[1]);
dt1 = dt << subset(selected rows(1), invisible, selected columns(0));
dt << Invert Row Selection;
dt2 = dt << subset(selected rows(1), invisible, selected columns(0));
回复:大数据/由于零方差而自动列消除Altug,我已经测试了我的代码,虽然它避免了显式循环,这很好,但是当表变大时, << get all value as matrix () 函数实在太昂贵了,而且收益(如果有的话) vstd() 与表操作相比,太小了,无法抵消这一点。
对于您的大小的桌子,修改吉姆的代码(以允许您的组)将会更快。 其核心是 JMP 表操作非常快。 我什至不相信矩阵运算(也非常快)比列函数更快。
最初对表进行子集化以创建两个子表(每个组一个子表)是物超所值的(假设您有足够的内存来容纳所有 3 个表),因为反复获取行子集的成本很高。
下面的代码(再次对 Jim 的代码进行了轻微修改,以允许您的两个组)在大约 2.5 秒内运行了 100K 行和 1K 列,而我第一次提交的例程花费了 6 秒多的时间。
在你这么大的桌子上,这看起来仍然有点慢……希望其他人会有更好的主意。
Names Default To Here( 1 );
dt = current datatable();
dtcol1 = column(dt, 1);
dt1 = dt << subset(rows(dt<<GET rows="" where="">= 1, i--,
If( (Col Std Dev( Column( dt1, colList[i] ) ) ) != 0 & Col Std Dev( Column( dt2, colList[i] ) ) != 0,
colList = Remove( colList, i, 1 )
)
);
// Delete the columns with no variance
dt<<DELETE columns=""></DELETE></GET>
回复:大数据/由于零方差而自动列消除阿尔图格,
如果我正确理解你的问题:
- 您有一个列(例如,名为“组”),有 2 个值(例如“A”和“B”)。
- 您有 2000 列包含数字数据。
- 您希望删除属于“A”组的行的标准偏差或属于“B”组的行的标准偏差低于某个阈值(或两者)的任何列。
对于您的大小的表来说,性能(和内存使用)将成为一个问题。 我不确定下面的方法是否能在您拥有的大小的桌子上工作或快速工作,但请尝试一下。
首先,创建一个表,其中“a/b”列是第一列,其余列是感兴趣的参数列。
然后试试这个。<BR />
干杯,
布雷迪
dt = Current Data Table();
mat = dt << Get All Columns As Matrix(); //this get the A/B column as 1s and 2s. which is which not important.
//create subtables... note A & B will be reversed if B occurs first in dt; the result is unaffected.
matA = mat[loc(mat[0,1]==1), 0];
matB = mat[loc(mat[0,1]==2), 0];
//compute stddevs for each column in each subtable
stdvA = vstd(matA);
stdvB = vstd(matB);
//locate columns of sufficiently low variance
cols = loc(stdvA == 0 | stdvB == 0);
//delete them. Ignore row (1) of the cols vector; it is 1 (corresponding to column 1 in dt).
try(dt << delete columns((dt << get column names)[cols[2::nrow(cols)]]));
回复:大数据/由于零方差而自动列消除这是一个简单的示例脚本,可以完成您想要的操作。
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA\semiconductor capability.jmp" );
// Get all continuous data columns
colList = dt << get column names( numeric, continuous );
// Loop across all columns and find those with no variance
For( i = N Items( collist ), i >= 1, i--,
If( Col Std Dev( Column( dt, colList[i] ) ) != 0,
colList = Remove( colList, i, 1 )
)
);
// Delete the columns with no variance
dt<<DELETE columns=""></DELETE>