Also ich bin brandneu zu R. Ich fing gestern damit an, es zu lernen, weil es einige Daten gibt, die sehr widerstandsfähig gegenüber dem automatischen Import in Mathematica und Python sind. Ich erstelle ein paar maschinelle Lerntechniken, um eine Analyse der Daten durchzuführen, die ich jetzt mit R importieren kann. Dies ist eine genetische Programmierimplementierung, die, wenn sie fertig ist, eine symbolische Regression für einige Daten durchführen sollte. (Ich muss noch die Mutations- oder Crossover-Operatoren erstellen, eine Legit-Funktionsliste erstellen usw.). Ich bekomme zwei Fehler, wenn ich das Skript ausführen:R Fehler Genetische Programmierung Implementierung
> Error: attempt to apply non-function > print(bestDude) > Error in print(bestDude) : object 'bestDude' not found
Dies ist mein Code:
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)
Der Code arbeitet jetzt dank Hack-R Vorschläge. Also hier ist der finalisierte Code für den Fall, dass jemand anderes in ähnliche Schwierigkeiten gerät.
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)
Hey, danke für die Hilfe. Die Art, wie ich meine Liste von Funktionen verwende, basiert auf: http://stackoverflow.com/questions/12117223/create-a-list-of-functions-from-vector-of-characters Das Beispiel, das ich bin Verwenden ist am unteren Rand. Ich bin mir ziemlich sicher, dass die Art, wie ich es benutze, korrekt ist. Das einzige, was ich mir vorstellen kann, ist, wenn die Liste der Funktionen zurückgegeben wird und dann auf diese Weise angewendet wird, oder dass die Verwendung eines Iterators in einer for-Schleife zum sequentiellen Zugriff auf verschiedene Funktionen nicht funktioniert. Sind Listen wie C++ - Arrays in dem Sinne, dass sie von konstanter Länge sein müssen? –
Der Fehler klingt, als wäre es ein Problem mit der Verwendung meiner Funktionsliste. Danke, dass du darauf hingewiesen hast. Daran habe ich nicht gedacht. –
Gern geschehen. Aber deins ist keine Liste von Funktionen, es ist nur eine Liste ***. Es enthält 4 Elemente - eine Zeichenfolge ("x") und drei Ziffern (2, 1, 1). Deshalb haben Sie den Fehler in Ihrer Frage und warum der Fehler verschwindet, wenn Sie die Liste nicht als Funktion verwenden. Um Ihre anderen Fragen zu beantworten, müssen Sie keine konstante Länge haben. *** Wenn Sie meinen, dass Ihr Beispiel sich von dem tatsächlichen Code unterscheidet, in dem Ihr aktueller Code eine Liste von Funktionen hat, dann sollten Sie den Code in Ihrer Frage so aktualisieren, dass wir sehen können, was schief gelaufen ist. –