h***s 发帖数: 2499 | 1 现有一个Java 写的gbm 的scoring code, 剧长因为是很多tree。
现在我想把这个code搬到spark上去run,所以需要改写.
我的理解是把所有x 建立一个rdd,每一个row是一个(key,vector),然后rdd.map((k,v
)=>
(k,tree(vector))), 这个思路对不对?
如果对的话,我就要确保 我的tree function take a vector as input and return
the
score.对吧?
vector里面的x1,x2,x3,...的位置要确保一致对吧?
哪里能找到一些类似的code?谢谢。 | h***s 发帖数: 2499 | | E*********g 发帖数: 185 | 3 思路是对的,格式可以很flexible。List, Vector, Tuple或多个数值做参数都可以
取决于你的score function用什么数据类型
不知道你这个tree function是什么意思
假定你的gbm模型scoring function是 score(Tuple), Tuple= (x1, x2,...)
val data = sc.textFile(data_file)
.map(_.split(","))
.map(x=> (x._1, (x._2, x._3, ...)))
//数据格式RDD(y, (x1,x2,...))。如果x太多的话,先把y split出来,
再split剩下的就好。 Tuple有22个参数限制, 如果x多于22个的话,不妨直接用List
val scores = data.map(x=> (x._1, score(x._2))
,v
【在 h***s 的大作中提到】 : 现有一个Java 写的gbm 的scoring code, 剧长因为是很多tree。 : 现在我想把这个code搬到spark上去run,所以需要改写. : 我的理解是把所有x 建立一个rdd,每一个row是一个(key,vector),然后rdd.map((k,v : )=> : (k,tree(vector))), 这个思路对不对? : 如果对的话,我就要确保 我的tree function take a vector as input and return : the : score.对吧? : vector里面的x1,x2,x3,...的位置要确保一致对吧? : 哪里能找到一些类似的code?谢谢。
| h***s 发帖数: 2499 | 4 非常感谢你的回答。能否继续请教一下。
score是要产生预测的y,所以data里没有y,只有快上千的x1..x999,所以不用split y
吧?由于x太多了,我只能用vector或者list?
其实我的问题还有一点麻烦的地方,我的score function是另一个软件产生的java
code。 很长所以手动改很烦,所以我试图保持原样看能不能wrap起来放到spark api里
。 以下是score function的例子,
private double XB_TOTAL_ACTIV_MNTH_P1Q; /*XB_TOTAL_ACTIV_MNTH_P1Q 是我的x1
,其他省略了 ×/
/*这里是用vector values[]赋值给x1
public void setDoubleVariables(double [] values) {
if (values.length != doubleVariables.length) {
System.out.println("Error! expecting " + doubleVariables.length + "
values for double predictors.");
} else {
XB_TOTAL_ACTIV_MNTH_P1Q = values[1];
}
}
这是一个tree function(x1)= score1;
private class tree_1 {
/* Tree 1 of 993 */
public double score() {
double target;
int node;
boolean done;
/* N terminal nodes = 6, Depth = 5 */
target = 0.0;
node = 1; /* start at root node */
done = false; /* set at terminal node */
while (!done) switch (node) {
case 1:
if (XB_POS_ACTIV_MNTH_L12M < 3.5) node = 2;
else node = 3;
break;
case 2:
............ /* skipped all cases here */
default: /* error */
target = 0.0;
done = true;
node = 0;
break;
}
return target;
}
}
tree_1 tree_1_obj=new tree_1();
把所有tree(x)都加起来是我的score
public double TreeNet_1_1() {
double response = 0.0;
response += init;
response+=tree_1_obj.score();
return response;
}
这样的写法有先赋值的一步把values[]里的x1等先搬到XB_TOTAL_ACTIV_MNTH_P1Q 里,
然后后面的tree()是用XB_TOTAL_ACTIV_MNTH_P1Q做的计算,而不是直接用values[0].
如果这样的写法我直接放到.map()里能work吗?
List
【在 E*********g 的大作中提到】 : 思路是对的,格式可以很flexible。List, Vector, Tuple或多个数值做参数都可以 : 取决于你的score function用什么数据类型 : 不知道你这个tree function是什么意思 : 假定你的gbm模型scoring function是 score(Tuple), Tuple= (x1, x2,...) : val data = sc.textFile(data_file) : .map(_.split(",")) : .map(x=> (x._1, (x._2, x._3, ...))) : //数据格式RDD(y, (x1,x2,...))。如果x太多的话,先把y split出来, : 再split剩下的就好。 Tuple有22个参数限制, 如果x多于22个的话,不妨直接用List :
| E*********g 发帖数: 185 | 5 没有y没关系, 你这里需要一个unique key for each record, 因为
后面要把scores加起来
这个XB_TOTAL_ACTIV_MNTH_P1Q 是global?
XB_TOTAL_ACTIV_MNTH_P1Q是怎么传给tree_1.score()的?
这JAVA code不改不行, 写得太烂了,就你这999个不同名字
的feature, 就只能手工处理,为什么不用数组或List呢
给你一个大概的思路:
1.首先score函数要能接受外部参数, 用List, Array都无所谓
2.所有的tree可以放到一个parallel List里,并行计算, 比如
val trees = List(new tree_1(), new tree_2()...).par
for (val tree <- trees){
val scores = data.map((key, features) => (key, tree.score(features)))
}
3.scores相加的话还要特殊的处理,因为并行计算以后的顺序是不定的
要group by key, 再相加
你如果对并行计算的机制不熟,那就别想能简简单单地直接搞定了
你这个tree model如果直接在spark里面训练出来,那就容易多了
y
x1
【在 h***s 的大作中提到】 : 非常感谢你的回答。能否继续请教一下。 : score是要产生预测的y,所以data里没有y,只有快上千的x1..x999,所以不用split y : 吧?由于x太多了,我只能用vector或者list? : 其实我的问题还有一点麻烦的地方,我的score function是另一个软件产生的java : code。 很长所以手动改很烦,所以我试图保持原样看能不能wrap起来放到spark api里 : 。 以下是score function的例子, : private double XB_TOTAL_ACTIV_MNTH_P1Q; /*XB_TOTAL_ACTIV_MNTH_P1Q 是我的x1 : ,其他省略了 ×/ : /*这里是用vector values[]赋值给x1 : public void setDoubleVariables(double [] values) {
| h***s 发帖数: 2499 | 6 有id作为unique的key, 可以生成key-vector pair。
在tree函数之前有个function给所有变量赋值,把vector里的值传给变量
XB_TOTAL_ACTIV_MNTH_P1Q,然后tree就直接根据这些变量计算。
这个code是salford软件自动生成的,所以写成这样,上千的不同名字的变量都hard
coded
1.我可以改写tree函数成接受外部array把feature的值传进来,但是每个tree只需要5
,6个out of hundreds.每个tree还不同的features。 我可以在textpad里一起replace
改,但是只可能每个tree都定义所有hundreds of变量,虽然只用5,6个,这样可以吗?
有可能不改吗,维持两个function吗?一个从vector到XB_TOTAL_ACTIV_MNTH_P1Q=?的
赋值函数,一个tree函数根据XB_TOTAL_ACTIV_MNTH_P1Q计算?spark api允许自定义函
数里
有global 变量吗?
2. 这里并行计算的意义是根据每个tree生成一个新的rdd对吗?你的code的for loop里的
score会是什么样的rdd,是所有tree还是一个tree的score?
3.有id做key,这里reduce相加group by id该怎么写?
万谢
【在 E*********g 的大作中提到】 : 没有y没关系, 你这里需要一个unique key for each record, 因为 : 后面要把scores加起来 : 这个XB_TOTAL_ACTIV_MNTH_P1Q 是global? : XB_TOTAL_ACTIV_MNTH_P1Q是怎么传给tree_1.score()的? : 这JAVA code不改不行, 写得太烂了,就你这999个不同名字 : 的feature, 就只能手工处理,为什么不用数组或List呢 : 给你一个大概的思路: : 1.首先score函数要能接受外部参数, 用List, Array都无所谓 : 2.所有的tree可以放到一个parallel List里,并行计算, 比如 : val trees = List(new tree_1(), new tree_2()...).par
| E*********g 发帖数: 185 | 7
:有id作为unique的key, 可以生成key-vector pair。
:
:在tree函数之前有个function给所有变量赋值,把vector里的值传给变量
:XB_TOTAL_ACTIV_MNTH_P1Q,然后tree就直接根据这些变量计算。
:
:这个code是salford软件自动生成的,所以写成这样,上千的不同名字的变量都hard
:coded
:
:1.我可以改写tree函数成接受外部array把feature的值传进来,但是每个tree只需要
5
:,6个out of hundreds.每个tree还不同的features。 我可以在textpad里一起
replace
:改,但是只可能每个tree都定义所有hundreds of变量,虽然只用5,6个,这样可以
吗?
可以
每棵树一个类是很糟糕的, 有没有可能做成一个类,不同参数
:
:有可能不改吗,维持两个function吗?一个从vector到XB_TOTAL_ACTIV_MNTH_P1Q=?的
:赋值函数,一个tree函数根据XB_TOTAL_ACTIV_MNTH_P1Q计算?spark api允许自定义函
:数里
:有global 变量吗?
没有这种global变量, 你看看能不能建一个map/dictionary, 把这些变量名map到一个
array
第一个函数在大数据里没什么意义,输出打印在slave node上,master node上看不到
可以直接赋一个特殊值
:2. 这里并行计算的意义是根据每个tree生成一个新的rdd对吗?你的code的for loop
里的
:score会是什么样的rdd,是所有tree还是一个tree的score?
是一棵树。 我也没有特别好的方法直接加, 可以把结果存到同一个父目录,不同子目
录:
val trees = List(new tree_1(), new tree_2()...).par
val rand = scala.util.Random
for (tree <- trees){
val scores = data.map((key, features) => (key, tree.score(features)))
scores.saveAsTextFile("PATH/"+rand.nextInt(10000000))
}
:3.有id做key,这里reduce相加group by id该怎么写?
把上面的目录一次load进来
val final_scores = sc.textFile("PATH/*")
.map(_.replaceAll("(|)","").split(","))
.map(x=> (x(0),x(1)))
.reduceByKey(_+_)
.map(_.mkString(",").replaceAll("(|)",""))
.coalesce(1)
.saveAsTextFile("......")
输出结果 id, score
【在 h***s 的大作中提到】 : 有id作为unique的key, 可以生成key-vector pair。 : 在tree函数之前有个function给所有变量赋值,把vector里的值传给变量 : XB_TOTAL_ACTIV_MNTH_P1Q,然后tree就直接根据这些变量计算。 : 这个code是salford软件自动生成的,所以写成这样,上千的不同名字的变量都hard : coded : 1.我可以改写tree函数成接受外部array把feature的值传进来,但是每个tree只需要5 : ,6个out of hundreds.每个tree还不同的features。 我可以在textpad里一起replace : 改,但是只可能每个tree都定义所有hundreds of变量,虽然只用5,6个,这样可以吗? : 有可能不改吗,维持两个function吗?一个从vector到XB_TOTAL_ACTIV_MNTH_P1Q=?的 : 赋值函数,一个tree函数根据XB_TOTAL_ACTIV_MNTH_P1Q计算?spark api允许自定义函
|
|