Ошибка реализации R GP

Итак, я новичок в R. У меня были проблемы с импортом данных в Mathematica, поэтому я решил переключиться, так как R гораздо лучше подходит для аналитики. Я разрабатываю несколько методов машинного обучения для анализа данных, которые теперь могу импортировать. Это реализация генетического программирования, которая после завершения должна выполнить символическую регрессию для некоторых данных. Если не считать ошибок, скрипт должен быть почти завершен (нужно запрограммировать оператор композиции, сделать деление защищенным и закончить список базовых функций). У меня была предыдущая проблема при программировании сценария, который был решен (Реализация генетического программирования R Error ). Я отлаживал скрипт около дня, и у меня закончились идеи.

Мое сообщение об ошибке:

Error in makeStrName(nextGen) : object 'nextGen' not found
> 
> #Print the string versions of the five functions with the lowest RMSE evolved.
> byRMSEList<-sortByRMSE(populationsBestTenStr)
Error: object 'totalTwo' not found
> for(i in 1:5)
+ {
+   byRMSEList[[i]]
+ }
Error: object 'byRMSEList' not found

Вот мой сценарий. В настоящее время я использую RStudio. Спасибо, что нашли время помочь:

library("datasets")

operators<-list("+","*","-","/","o")
funcs<-list("x","log(x)","sin(x)","cos(x)","tan(x)")

#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, funcList)
{
  set.seed(inputSeed)
  rnd<-sample(1:length(funcList),inputLen,replace=T)
  Org<-mapFuncList(funcList,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+i,functions))
  }
  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, populationStringList)
{
  #rmse <- sqrt( mean( (sim - obs)^2))
  for(i in 1:length(populationStringList))
  {
    stringFunc<-populationStringList[[i]]
    total<-list(mode="numeric",length=length(inputData))
    topTenPercentFunctionList<-list()
    topTenPercentRMSEList<-list()
    topTenPercentStringFunctionList<-list()
    tempFunc<-function(x){x}
    for(z in 1:length(inputData))
    {
      total<-c(total,(abs(populationFuncList[[i]](inputData[[z]])-outputData[[z]])))
      tempFunc<-populationFuncList[[i]]
    }
    rmse<-sqrt(mean(total*total))
    topTenPercentVal<-length(populationFuncList)*0.1
    if(length(topTenPercentFunctionList)<topTenPercentVal||RMSE<min(topTenPercentRMSEList))
    {
      topTenPercentStringFunctionList<-c(topTenPercentStringFunctionList,stringFunc)
      topTenPercentRMSEList<-c(topTenPercentRMSEList, rmse)
      topTenPercentFunctionList<-c(topTenPercentFunctionList, tempFunc)
    }
  }
  return(topTenPercentStringFunctionList)
}
#Get random operator
getRndOp<-function(seed)
{
  set.seed(seed)
  rndOpNum<-sample(1:length(operators),1,replace=T)
  operation<-operators[[rndOpNum]]
  return(operation)
}

#Mutation Operators

#This attaches a new appendage to an organism
endNodeMutation<-function(strFunc,seed)
{
  op<-getRndOp(seed)
  strFunc<-c(strFunc,op)
  newAppendage<-generateOrganism(1,seed+2,funcs)
  strFunc<-c(strFunc,newAppendage)
  return(strFunc)
}

#This is a mutation that occurs at a random locaiton in an organism
rndNodeMutation<-function(strFunc,seed,secondSeed)
{
  op<-getRndOp(seed)
  halfStrFunc<-((length(strFunc))/2)
  set.seed(seed)
  randomStart<-sample(1:halfStrFunc,1,replace=T)
  set.seed(secondSeed)
  randomEnd<-2*(sample(1:length(halfStrFunc),1,replace=T))
  strFuncUpdate<-substr(strFunc,randomStart,randomEnd)
  strFuncUpdate<-c(strFuncUpdate,op)
  newAppendage<-generateOrganism(1,seed+2,funcs)
  strFuncUpdate<-c(strFuncUpdate,newAppendage)
  return(strFuncUpdate)
}

#Crossover Operators

#Crossover operator that attaches otherStrFunc to strFunc at the endpoint of strFunc
crossoverConcatenationOperator<-function(strFunc,otherStrFunc)
{
  newStrFunc<-c(strFunc,otherStrFunc)
  return(newStrFunc)
}

#Crossover Operation that starts and ends at random points in the concatenation
randomCrossoverOperator<-function(strFunc,otherStrFunc,seed,secondSeed)
{
  set.seed(seed)
  wholeLength<-(length(strFunc)+length(otherStrFunc))
  startRndNum<-sample(1:length(strFunc),1,replace=T)
  set.seed(secondSeed)
  endRndNum<-sample(length(strFunc):wholeLength,1,replace=T)
  concatenatedFunc<-c(strFunc,otherStrFunc)
  newFunc<-substr(concatenatedFunc,startRndNum,endRndNum)
  return(newFunc)
}
evolve<-function(strFuncList,tenPercentStrFuncList)
{
  #Detach the bottom ninety percent to the top ten percent
  evolveList<-substr(strFuncList,length(tenPercentStrFuncList),length(strFuncList))
  #Get sizes. Will use a random mutation, then random crossover, then
  #random mutation, then random crossover at percentages with 0.05,0.45,0.05,0.45
  #respectively
  size<-length(evolveList)
  mutateNum<-0.1*size
  crossoverNum<-0.9*size
  halfMutateNum<-0.05*size
  halfCrossoverNum<-0.45*size
  roundedMutateNum<-floor(mutateNum)
  roundedCrossoverNum<-floor(crossoverNum)
  roundedHalfMutateNum<-floor(halfMutateNum)
  roundedHalfCrossoverNum<-floor(halfCrossoverNum)

  #Calls the functions for those percentage of organisms in that order
  for(i in 1:roundedHalfMutateNum)
  {
    set.seed(i)
    rndOne<-sample(0:1000,1,replace=T)
    set.seed(i+10000)
    rndTwo<-sample(0:10000,1,replace=T)
    newFunc<-rndNodeMutation(evolveList[[i]],rndOne,rndTWo)
    evolveList[[i]]<-newFunc
  }
  for (i in roundedHalfMutateNum:(roundedHalfCrossoverNum+roundedHalfMutateNum))
  {
    set.seed(i)
    rndOne<-sample(0:1000,1,replace=T)
    set.seed(i+10000)
    rndTwo<-sample(0:10000,1,replace=T)
    newFunc<-rndCrossoverOperation(evolveList[[i]],evolveList[[i+1]],rndOne,rndTwo)
    firstSubstr<-substr(evolveList,1,i-1)
    secondSubstr<-substr(evolveLIst,i+2,length(evolveList))
    halfSubstr<-c(firstSubstr,newFunc)
    evolveList<-c(halfSubstr,secondSubstr)
  }
  for(i in (roundedHalfCrossoverNum+roundedHalfMutateNum):(roundedHalfCrossoverNum+roundedMutateNum))
  {
    set.seed(i)
    rndOne<-sample(0:1000,1,replace=T)
    set.seed(i+10000)
    rndTwo<-sample(0:10000,1,replace=T)
    newFunc<-rndNodeMutation(evolveList[[i]],rndOne,rndTWo)
    evolveList[[i]]<-newFunc
  }
  for(i in (roundedHalfCrossoverNum+roundedMutateNum):(roundedCrossoverNum+roundedHalfMutateNum))
  {
    set.seed(i)
    rndOne<-sample(0:1000,1,replace=T)
    set.seed(i+10000)
    rndTwo<-sample(0:10000,1,replace=T)
    newFunc<-rndCrossoverOperation(evolveList[[i]],evolveList[[i+1]],rndOne,rndTwo)
    firstSubstr<-substr(evolveList,1,i-1)
    secondSubstr<-substr(evolveLIst,i+2,length(evolveList))
    halfSubstr<-c(firstSubstr,newFunc)
    evolveList<-c(halfSubstr,secondSubstr)
  }
}

#Calculates the root mean squared of the functions in a string list.
#Then sorts the list by RMSE.
sortByRMSE<-function(strL)
{
  for (z in 1:length(strL))
  {
    for(i in 1:length(strL))
    {
      nonStrFuncList<-lapply(strL,function(x){funCreator(x)})
      totalTwo<-c(totalTwo,(abs(nonStrFuncList[[z]](inputData[[i]])-outputData[[i]])))
    }
    rmse<-sqrt(mean(totalTwo*totalTwo))
    strFuncsLists<-strL[order(sapply(strL, '[[', rmse))]
  }
  return(strFuncsLists)
}

#Data, Output Goal
desiredFuncOutput<-list(1,4,9,16,25)
dataForInput<-list(1,2,3,4,5)

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

#Get and save top ten percent in bestDudes
bestDudes<-evalPopulation(POpulationFuncList,dataForInput,desiredFuncOutput,POpulation)
#Evolve the rest
NewBottomNinetyPercent<-evolve(POpulation,bestDudes)
#Concatenate the two to make a new generation
nextGen<-c(bestDudes,NewBottomNinetyPercent)

#Declare lists,
populationsBestTenStr<-list()
populationsFuncList<-list()

#Run ten generations.
for(i in 1:10)
{
  nextGen<-makeStrName(nextGen)
  populationsFuncList<-lapply(setNames(nextGen,names(nextGen)),function(x){funCreator(x)})
  populationsBestTenStr<-evalPopulation(populationsFuncList,dataForInput,desiredFuncOutput,nextGen)
  nextGen<-evolve(populations,populationsBestTenStr)
}

#Print the string versions of the five functions with the lowest RMSE evolved.
byRMSEList<-sortByRMSE(populationsBestTenStr)
for(i in 1:5)
{
  byRMSEList[[i]]
}

person Novice Polymath    schedule 27.06.2016    source источник


Ответы (1)


person    schedule
comment
У меня есть это в моем коде. См. #Данные, цель вывода. Исправлена ​​картаStrFunc, спасибо за подсказку - person Novice Polymath; 28.06.2016
comment
Это чуть выше вызова evalPopulation в коде, который я разместил. - person Novice Polymath; 28.06.2016
comment
@ novice-polymath Хорошо, я исправил еще одну ошибку, и теперь она работает через evolve, но я не знаю, что вы пытались сделать с substr. Кажется, что значения POpulation произвольно обрезаются. Я вижу комментарий к этой строке, но я действительно не понимаю. Можете ли вы помочь мне? Мне нужно идти на встречу, но я вернусь к этому позже сегодня. - person Hack-R; 28.06.2016
comment
@NovicePolymath предполагалось просто удалить bestDudes из POpulation? - person Hack-R; 28.06.2016
comment
Да. По сути, идея состоит в том, чтобы оставить первые десять процентов (bestDudes) одинаковыми, а затем использовать операторы кроссовера и мутации для нижних девяноста процентов. В функциях случайной мутации и случайного кроссовера я использую его для развития популяции, избегая раздувания. Таким образом, он (в идеале) выбирает случайные места для изменения вещей и отбрасывает то, что находится за пределами начальной и конечной позиций. Могу я спросить, почему мой substr был сломан, чтобы я не повторил ту же ошибку снова? Просмотрел изменения и не понял. - person Novice Polymath; 28.06.2016
comment
@NovicePolymath Подстрока, о которой я говорил, была evolveList<-substr(strFuncList,length(tenPercentStrFuncList),length(strFuncList)). Объекты, которые я загружаю в него, strFuncList=POpulation,tenPercentStrFuncList=bestDudes. Таким образом, для каждого элемента POpulation в моем примере были сохранены только символы 1:4. Если что-то не напутано, POpulation содержит такие элементы, как sin(x). Таким образом, substr превратил этот элемент, например, в sin(, что мне показалось неправильным. - person Hack-R; 28.06.2016