R错误遗传编程的实现 [英] R Error Genetic Programming Implementation

查看:92
本文介绍了R错误遗传编程的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我是R的新手.我昨天开始学习它,因为有些数据非常难以自动导入到Mathematica和Python中.我正在构建一些机器学习技术,以对现在可以使用R导入的数据进行分析.这是一种遗传编程实现,完成后应该对某些数据进行符号回归. (我还没有创建变异或交叉运算符,建立合法函数列表等).运行脚本时出现两个错误:

So I am brand new to R. I started learning it yesterday, because there's some data that is being very resistant to automatically importing into Mathematica and Python. I'm building a few machine learning techniques to do analysis on the data that I can now import with R. This is a genetic programming implementation that when finished should do symbolic regression on some data. (I have yet to create the mutation or crossover operators, build a legit function list, etc). I get two errors when I run the script:

> Error: attempt to apply non-function
> print(bestDude)
> Error in print(bestDude) : object 'bestDude' not found

这是我的代码:

library("datasets")

#Allows me to map a name to each element in a numerical list.
makeStrName<-function(listOfItems)
{
  for(i in 1:length(listOfItems))
  {
        names(listOfItems)[i]=paste("x",i,sep="")
  }
  return(listOfItems)
}

#Allows me to replace each random number in a vector with the corresponding 
#function in a list of functions.

mapFuncList<-function(funcList,rndNumVector)
{
  for(i in 1:length(funcList))
  {
    replace(rndNumVector, rndNumVector==i,funcList[[i]])
  }
  return(rndNumVector)
}

#Will generate a random function from the list of functions and a random sample.
generateOrganism<-function(inputLen,inputSeed, functions)
{
  set.seed(inputSeed)
  rnd<-sample(1:length(functions),inputLen,replace=T)
  Org<-mapFuncList(functions,rnd)
  return(Org)
}

#Will generate a series of "Organisms"
genPopulation<-function(popSize,initialSeed,initialSize,functions)
{
  population<-list("null")
  for(i in 2:popSize)
  {
    population <- c(population,generateOrganism(initialSize,initialSeed, functions))
    initialSeed <- initialSeed+1
  }
  populationWithNames<-makeStrName(population)
  return(populationWithNames)
}

#Turns the population of functions (which are actually strings in "") into
#actual functions. (i.e. changes the mode of the list from string to function).

populationFuncList<-function(Population)
{
  Population[[1]]<-"x"
  funCreator<-function(snippet)
    txt=snippet
  function(x)
  {
    exprs <- parse(text = txt)
    eval(exprs) 
  }
  listOfFunctions <- lapply(setNames(Population,names(Population)),function(x){funCreator(x)})
  return(listOfFunctions)
}

#Applies a fitness function to the population. Puts the best organism in
#the hallOfFame.
evalPopulation<-function(populationFuncList, inputData,outputData)
{   
  #rmse <- sqrt( mean( (sim - obs)^2))

  hallOfFame<-list(1000000000)
  for(i in 1:length(populationFuncList))
  {
        total<-list()
        for(z in 1:length(inputData))
        {
          total<-c(total,(abs(populationFuncList[[i]](inputData[[z]])-outputData[[z]])))
        }
        rmse<-sqrt(mean(total*total))
                   if(rmse<hallOfFame[[1]]) {hallOfFame[[1]]<-rmse}
  }
  return(hallOfFame)
}

#Function list, input data, output data (data to fit to)
funcs<-list("x","log(x)","sin(x)","cos(x)","tan(x)")
desiredFuncOutput<-list(1,2,3,4,5)
dataForInput<-list(1,2,3,4,5)

#Function calls
POpulation<-genPopulation(4,1,1,funcs)
POpulationFuncList<-populationFuncList(POpulation)
bestDude<-evalPopulation(POpulationFuncList,dataForInput,desiredFuncOutput)
print(bestDude)

由于Hack-R的建议,代码现在可以正常工作了.因此,这里是完成代码,以防其他人遇到类似的麻烦.

The code is now working thanks to Hack-R's suggestions. So here's the finalized code in case someone else runs into a similar trouble.

library("datasets")

#Allows me to map a name to each element in a numerical list.
makeStrName<-function(listOfItems)
{
  for(i in 1:length(listOfItems))
  {
    names(listOfItems)[i]=paste("x",i,sep="")
  }
  return(listOfItems)
}

#Allows me to replace each random number in a vector with the corresponding 
#function in a list of functions.

mapFuncList<-function(funcList,rndNumVector)
{
  for(i in 1:length(funcList))
  {
    rndNumVector[rndNumVector==i]<-funcList[i]
  }
  return(rndNumVector)
}

#Will generate a random function from the list of functions and a random sample.
generateOrganism<-function(inputLen,inputSeed, functions)
{
  set.seed(inputSeed)
  rnd<-sample(1:length(functions),inputLen,replace=T)
  Org<-mapFuncList(functions,rnd)
  return(Org)
}

#Will generate a series of "Organisms"
genPopulation<-function(popSize,initialSeed,initialSize,functions)
{
  population<-list()
  for(i in 1:popSize)
  {
    population <- c(population,generateOrganism(initialSize,initialSeed,functions))
    initialSeed <- initialSeed+1
  }
  populationWithNames<-makeStrName(population)
  return(populationWithNames)
}

#Turns the population of functions (which are actually strings in "") into
#actual functions. (i.e. changes the mode of the list from string to function).

funCreator<-function(snippet)
{
  txt=snippet
  function(x)
  {
    exprs <- parse(text = txt)
    eval(exprs) 
  }
}

#Applies a fitness function to the population. Puts the best organism in
#the hallOfFame.
evalPopulation<-function(populationFuncList, inputData,outputData)
{   
  #rmse <- sqrt( mean( (sim - obs)^2))

  hallOfFame<-list(1000000000)
  for(i in 1:length(populationFuncList))
  {
    total<-vector(mode="numeric",length=length(inputData))
    for(z in 1:length(inputData))
    {
      total<-c(total,(abs(populationFuncList[[i]](inputData[[z]])-outputData[[z]])))
    }
    rmse<-sqrt(mean(total*total))
    if(rmse<hallOfFame[[1]]) {hallOfFame[[1]]<-rmse}
  }
  return(hallOfFame)
}

#Function list, input data, output data (data to fit to)
funcs<-list("x","log(x)","sin(x)","cos(x)","tan(x)")
desiredFuncOutput<-list(1,2,3,4,5)
dataForInput<-list(1,2,3,4,5)

#Function calls
POpulation<-genPopulation(4,1,1,funcs)
POpulationFuncList <- lapply(setNames(POpulation,names(POpulation)),function(x){funCreator(x)})

bestDude<-evalPopulation(POpulationFuncList,dataForInput,desiredFuncOutput)
print(bestDude)

推荐答案

在函数evalPopulation中,您试图将populationFuncList[[i]]当作函数使用,但是当您将参数POpulationFuncList传递给替换变量populationFuncList,它不是一个函数,它是一个列表.

In your function evalPopulation you're attempting to apply populationFuncList[[i]] as if it were a function, but when you pass in the argument POpulationFuncList to replace the variable populationFuncList it's not a function, it's a list.

我不确定您要做什么,所以不确定您要采用哪种方式解决此问题.如果您打算使用一个函数,则应更改要引用该函数的对象的名称,并将其作为参数删除,或者至少将一个函数作为参数而不是列表作为参数传入.

I'm not sure what you were trying to do, so I'm not sure which way you want to fix this. If you meant to use a function you should change the name of the object you're referencing to the function and remove it as an argument or at least pass a function in as an argument instead of the list.

OTOH,如果您打算使用列表POpulationFuncList,那么您就不应该像应用函数一样使用它,而不是使用列表.

OTOH if you meant to use the list POpulationFuncList then you just shouldn't be applying it as if it were a function instead of a list.

顺便说一句,如果您不给他们这样的名字,这可能会更加明显.

On a side note, this probably would be more apparent if you didn't give them such similar names.

另一个潜在的问题是,您似乎在其中一个列表中出现了非数字结果:

Another potential problem is that you seem have non-numeric results in one of your lists:

> populationFuncList(POpulation)
$x1
[1] "x"

$x2
[1] 2

$x3
[1] 1

$x4
[1] 1

您不能采用字符"x"的绝对值,所以我只是想确保您知道这一点.

You can't take the absolute value of the character "x", so I just wanted to make sure you're aware of this.

第三个问题是您正在对名为total的非数字数据类型的对象进行数学运算.您需要将类型更改为数字或对其进行适当索引.

A third problem is that you're doing math on a non-numeric data typed object called total. You need to either change the type to numeric or index it appropriately.

现在,对于我来说,不可能确切地知道应选择无数种可能性中的哪一种来解决此问题,因为我不知道用例的细节.但是,这是一种可能的解决方案,您应该能够适应用例的具体要求:

Now it's impossible for me to know exactly which of an infinite number of possibilities you should choose to fix this, because I don't know the details of your use case. However, here is one possible solution which you should be able to adapt to the specifics of the use case:

library("datasets")

#Allows me to map a name to each element in a numerical list.
makeStrName<-function(listOfItems)
{
  for(i in 1:length(listOfItems))
  {
    names(listOfItems)[i]=paste("x",i,sep="")
  }
  return(listOfItems)
}

#Allows me to replace each random number in a vector with the corresponding 
#function in a list of functions.

mapFuncList<-function(funcList,rndNumVector)
{
  for(i in 1:length(funcList))
  {
    replace(rndNumVector, rndNumVector==i,funcList[[i]])
  }
  return(rndNumVector)
}

#Will generate a random function from the list of functions and a random sample.
generateOrganism<-function(inputLen,inputSeed, functions)
{
  set.seed(inputSeed)
  rnd<-sample(1:length(functions),inputLen,replace=T)
  Org<-mapFuncList(functions,rnd)
  return(Org)
}

#Will generate a series of "Organisms"
genPopulation<-function(popSize,initialSeed,initialSize,functions)
{
  population<-list("null")
  for(i in 2:popSize)
  {
    population <- c(population,generateOrganism(initialSize,initialSeed, functions))
    initialSeed <- initialSeed+1
  }
  populationWithNames<-makeStrName(population)
  return(populationWithNames)
}

#Turns the population of functions (which are actually strings in "") into
#actual functions. (i.e. changes the mode of the list from string to function).

populationFuncList<-function(Population)
{
  Population[[1]]<-"x"
  funCreator<-function(snippet)
    txt=snippet
  function(x)
  {
    exprs <- parse(text = txt)
    eval(exprs) 
  }
  listOfFunctions <- lapply(setNames(Population,names(Population)),function(x){funCreator(x)})
  return(listOfFunctions)
}

#Applies a fitness function to the population. Puts the best organism in
#the hallOfFame.
evalPopulation<-function(myList=myList, dataForInput,desiredFuncOutput)
{   
  #rmse <- sqrt( mean( (sim - obs)^2))

  hallOfFame<-list(1000000000)
  for(i in 1:length(populationFuncList))
  {
    total<-0
    for(z in 1:length(dataForInput))
    {
      total<-c(total,(abs(myList[[i]]+(dataForInput[[z]])-desiredFuncOutput[[z]])))
    }
    rmse<-sqrt(mean(total*total))
    if(rmse<hallOfFame[[1]]) {hallOfFame[[1]]<-rmse}
  }
  return(hallOfFame)
}

#Function list, input data, output data (data to fit to)
funcs<-list("x","log(x)","sin(x)","cos(x)","tan(x)")
desiredFuncOutput<-list(1,2,3,4,5)
dataForInput<-list(1,2,3,4,5)

#Function calls
POpulation<-genPopulation(4,1,1,funcs)
myList <-populationFuncList(POpulation)[2:4]
bestDude<-evalPopulation(myList,dataForInput,desiredFuncOutput)
print(bestDude)
[[1]]
[1] 1.825742

这篇关于R错误遗传编程的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆