2016-06-11 12 views
1

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) 

Antwort

1

In Ihrer Funktion evalPopulation Sie versuchen populationFuncList[[i]] anzuwenden, als ob es sich um eine Funktion waren, aber wenn man in dem Argument übergeben POpulationFuncList die Variable populationFuncList es ist nicht eine Funktion zu ersetzen, ist es eine Liste.

Ich bin mir nicht sicher, was Sie versucht haben, also bin ich mir nicht sicher, auf welche Art Sie das beheben möchten. Wenn Sie eine Funktion verwenden möchten, sollten Sie den Namen des Objekts, auf das Sie verweisen, in die Funktion ändern und als Argument entfernen oder zumindest eine Funktion als Argument anstelle der Liste übergeben.

OTOH Wenn Sie die Liste POpulationFuncList verwenden wollten, dann sollten Sie es nicht anwenden, als wäre es eine Funktion anstelle einer Liste.

Auf einer Randnotiz wäre dies wahrscheinlich mehr offensichtlich, wenn Sie ihnen solche ähnlichen Namen nicht geben würden.

Ein weiteres mögliches Problem ist, dass Sie scheinen nicht-numerischen Ergebnisse in einer Ihrer Listen:

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

$x2 
[1] 2 

$x3 
[1] 1 

$x4 
[1] 1 

Sie nicht den absoluten Wert des Zeichens nehmen kann „x“, so wollte ich nur um sicherzustellen, dass Sie sich dessen bewusst sind.

Ein drittes Problem ist, dass Sie Mathe auf ein nicht numerisches Objekt namens total tun. Sie müssen den Typ entweder in numerisch ändern oder entsprechend indizieren.

Jetzt ist es mir unmöglich, genau zu wissen, welche der unendlich vielen Möglichkeiten Sie wählen sollten, um dies zu beheben, weil ich die Details Ihres Anwendungsfalles nicht kenne. Hier ist jedoch eine mögliche Lösung, die Sie an die Besonderheiten des Anwendungsfalles anpassen können:

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 
+0

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? –

+0

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. –

+0

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. –

Verwandte Themen