C++ 将Python转换为Rcpp

C++ 将Python转换为Rcpp,c++,r,rcpp,C++,R,Rcpp,我无法将此ptyhon转换为Rcpp 该脚本是分类和回归树逻辑的一部分: # Calculate the Gini index for a split dataset def gini_index(groups, classes): # count all samples at split point n_instances = float(sum([len(group) for group in groups])) # sum weighted Gini index f

我无法将此ptyhon转换为Rcpp

该脚本是分类和回归树逻辑的一部分:

# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
    # count all samples at split point
    n_instances = float(sum([len(group) for group in groups]))
    # sum weighted Gini index for each group
    gini = 0.0
    for group in groups:
        size = float(len(group))
        # avoid divide by zero
        if size == 0:
            continue
        score = 0.0
        # score the group based on the score for each class
        for class_val in classes:
            p = [row[-1] for row in group].count(class_val) / size
            score += p * p
        # weight the group score by its relative size
        gini += (1.0 - score) * (size / n_instances)
    return gini

# test Gini values
print(gini_index([[[1, 1], [1, 0]], [[1, 1], [1, 0]]], [0, 1]))
>>0.5
print(gini_index([[[1, 0], [1, 0]], [[1, 1], [1, 1]]], [0, 1]))
>>0
我试图通过提供两个向量和循环来加速它。 向量是实际组和建议组。 实际组对应于上面每个嵌套列表中的最后一个元素:

1,0,1,0
建议的组对应于嵌套列表的分组方式(前两个元素在一个组中;后两个元素在另一个组中)

<我的C++ + Rcpp没有足够的力量来看出这里出了什么问题:

float gini_index(NumericVector y, NumericVector g){
  int n_records = y.size();
  float gini = 0.0;
  NumericVector groups = unique(y);
  int group_count = groups.size();
  for(int i_g=0; i_g<group_count; i_g++){
    float size = 0;
    for(int i;i<n_records;i++){
      if(g[i]==groups[i_g]){
        size++;
      }
    }
    float score = 0.0;
    for(int i_y=0; i_y<n_records; i_y++){
      float class_count=0;
      if(y[i_y]==groups[i_g]){
        class_count++;}
      float p=0;
      if(size==0){
        p=0;
      }
      else{
        p = class_count/size;
      }
      std::cout<<p<<std::endl;
      score = score + p*p;
    }
    gini = gini+(1.0-score)*(size/n_records);  
  }
return(gini);
}


y<-c(1,1,2,2)
g<-c(1,2,1,2)
gini_index(y,g)




 > gini_index(y,g)
    0
    0.5
    0
    0.5
    0
    0
    0
    0
    [1] 0.25
浮动基尼指数(数值向量y,数值向量g){ int n_记录=y.大小(); 浮动基尼=0.0; 数值向量组=唯一(y); int group_count=groups.size();
对于(int i_g=0;i_g而言,您的一个循环中有一个错误:
i
未初始化。在我的情况下,该错误导致循环根本未被计算。如果正确修复,结果看起来会更好:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
float gini_index(NumericVector y, NumericVector g){
  int n_records = y.size();
  float gini = 0.0;
  NumericVector groups = unique(y);
  int group_count = groups.size();
  for(int i_g=0; i_g<group_count; i_g++){
    float size = 0;
    for(int i = 0;i<n_records;i++){ // !!!
      if(g[i]==groups[i_g]){
        size++;
      }
    }
    float score = 0.0;
    for(int i_y=0; i_y<n_records; i_y++){
      float class_count=0;
      if(y[i_y]==groups[i_g]){
        class_count++;}
      float p=0;
      if(size==0){
        p=0;
      }
      else{
        p = class_count/size;
      }
      Rcpp::Rcout<<p<<std::endl;
      score = score + p*p;
    }
    gini = gini+(1.0-score)*(size/n_records);  
  }
  return(gini);
}

/*** R
y<-c(1,1,2,2)
g<-c(1,2,1,2)
gini_index(y,g)
*/
顺便说一句:

  • 为什么返回的是
    float
    而不是
    double
  • 增量应写为
    ++i
  • C++具有
    +=

如果有人试图重新创建,我最终会使用这个答案。我最初接受的答案非常有用,但在其他情况下会打印出错误的答案

float gini_index(NumericVector y, NumericVector g){
  float gini = 0.0;
  NumericVector classes = unique(y);
  int class_count = classes.size();
  int n_instances = y.size();

  float p;
  for(int group=0; group<class_count; group++){
    float size = 0;
    for(int i=0; i<g.size();i++){
      if(g[i]==classes[group]){
        size++;
      }
    }
    if(size==0){
      p=0;
    }
    float score =0.0;
    if(size!=0){
      for(int class_val=0; class_val<classes.size(); class_val++){
        float correctly_assigned = 0;
        for(int i=0; i<g.size();i++){
          if(g[i]==classes[group] && y[i]==classes[class_val])
            correctly_assigned++;
        }
        p = correctly_assigned/size;
        score = score +p*p;
      }
      gini = gini+ (1.0-score)*(size / n_instances);
    }
  }
  return gini;
}
浮动基尼指数(数值向量y,数值向量g){ 浮动基尼=0.0; 数值向量类=唯一(y); int class_count=classes.size(); int n_实例=y.size(); 浮动p;
对于(int group=0;group)您的代码只打印0,并在此处返回0。什么是正确的?对不起。我已经修改了。这里没有更改。使用gThank的新值,您……基于此……“而浮点占用的内存更少,速度更快。一般来说,您应该使用浮点,除非您遇到浮点不够精确的情况。”@user2723494这是一个0分的答案,而排名靠前的答案主张没有太大差异(如果有的话)此外,R的<代码>数字< /代码>类型对应于<代码>双。因此,在C++中,您可以使用<代码>浮点< /代码>,结果在R.Ex.Read上转换为<代码>双< /代码>。讽刺的是,当您使用谷歌时,“浮点而不是双”,我引用的行是谷歌自动应答。
> gini_index(y,g)
0 2
0
0
0.5
0.5
1 2
0.5
0.5
0
0
[1] 0.5
float gini_index(NumericVector y, NumericVector g){
  float gini = 0.0;
  NumericVector classes = unique(y);
  int class_count = classes.size();
  int n_instances = y.size();

  float p;
  for(int group=0; group<class_count; group++){
    float size = 0;
    for(int i=0; i<g.size();i++){
      if(g[i]==classes[group]){
        size++;
      }
    }
    if(size==0){
      p=0;
    }
    float score =0.0;
    if(size!=0){
      for(int class_val=0; class_val<classes.size(); class_val++){
        float correctly_assigned = 0;
        for(int i=0; i<g.size();i++){
          if(g[i]==classes[group] && y[i]==classes[class_val])
            correctly_assigned++;
        }
        p = correctly_assigned/size;
        score = score +p*p;
      }
      gini = gini+ (1.0-score)*(size / n_instances);
    }
  }
  return gini;
}