4 Stimmen

Kann eine Zeile in einem "Kollektiven Intelligenz" Programm nicht verstehen.

Ich arbeite mich durch "Programming Collective Intelligence". In Kapitel 4 baut Toby Segaran ein künstliches neuronales Netzwerk auf. Die folgende Funktion erscheint auf Seite des Buches:

def generatehiddennode(self,wordids,urls):
  if len(wordids)>3: return None
  # Überprüfen, ob wir bereits einen Knoten für diese Wortgruppe erstellt haben
  sorted_words=[str(id) for id in wordids]
  sorted_words.sort()
  createkey='_'.join(sorted_words)
  res=self.con.execute(
  "select rowid from hiddennode where create_key='%s'" % createkey).fetchone()

  # Falls nicht, erstelle es
  if res==None:
    cur=self.con.execute(
    "insert into hiddennode (create_key) values ('%s')" % createkey)
    hiddenid=cur.lastrowid
    # Setze einige Standardgewichtungen
    for wordid in wordids:
      self.setstrength(wordid,hiddenid,0,1.0/len(wordids))
    for urlid in urls:
      self.setstrength(hiddenid,urlid,1,0.1)
    self.con.commit()

Was ich einfach nicht verstehen kann, ist der Grund für die erste Zeile in dieser Funktion: 'if len(wordids>3): return None`. Ist es ein Debug-Code, der später entfernt werden muss?

P.S. Dies hier ist keine Hausaufgabe

0 Stimmen

Unmöglich zu sagen, wirklich, ohne mehr über den Rest des Programms zu wissen. Wenn das Programm nicht für mehr als 3 wordids vorgesehen ist, scheint dies in Ordnung zu sein (persönlich würde ich wahrscheinlich eine Ausnahme werfen, aber vielleicht wird der Rückgabewert an anderer Stelle überprüft). Wenn es für eine beliebige Anzahl von wordids gedacht ist, kann es ein Fehler sein. Beispielscode in Büchern enthält oft Fehler.

0 Stimmen

Auf den ersten Blick sieht es aus wie eine Art primitiver Fehlerüberprüfung. Es sieht so aus, als ob die Länge von wordids 3 oder weniger betragen sollte. Wenn Sie der Funktion eine wordids-Variable mit größerer Länge übergeben, wird die Funktion nichts tun.

2 Stimmen

Es führt eine Eingabebeschränkung durch, dass die Funktion nur auf maximal einem Tripel von "Wörtern" ausgeführt werden sollte. Wahrscheinlich ist es einfacher, in diesem Fall None zurückzugeben, als ein assert oder raise zu verwenden.

6voto

Gareth Rees Punkte 62623

Für ein veröffentlichtes Buch ist das ziemlich schrecklicher Code! (Du kannst alle Beispiele für das Buch hier herunterladen; die relevante Datei ist chapter4/nn.py.)

  • Kein Docstring. Was soll diese Funktion tun? Anhand ihres Namens können wir vermuten, dass sie einen der Knoten in der "versteckten Schicht" eines neuronalen Netzwerks erzeugt, aber welche Rolle spielen die wordids und urls?
  • Die Datenbankabfrage verwendet Zeichenersetzungen und ist daher anfällig für SQL-Injektionsangriffe (insbesondere da es sich um etwas mit der Websuche handelt, kommen die wordids wahrscheinlich aus einer Benutzerabfrage und können daher nicht vertrauenswürdig sein - aber vielleicht sind es IDs anstatt Wörter, also ist es in der Praxis in Ordnung, aber dennoch ein sehr schlechtes Gewohnheit).
  • Es wird nicht die Ausdruckskraft der Datenbank genutzt: Wenn Sie nur bestimmen möchten, ob ein Schlüssel in der Datenbank vorhanden ist, verwenden Sie wahrscheinlich ein SELECT EXISTS(...) anstatt die Datenbank zu bitten, Ihnen eine Menge Datensätze zu senden, die Sie dann ignorieren werden.
  • Die Funktion tut nichts, wenn bereits ein Datensatz mit createkey vorhanden war. Kein Fehler. Ist das korrekt? Wer kann das sagen?
  • Die Gewichtung für die Wörter wird auf die Anzahl der Wörter skaliert, aber die Gewichtung für die URLs ist die Konstante 0.1 (vielleicht gibt es immer 10 URLs, aber es wäre besserer Stil, hier nach len(urls) zu skalieren).

Ich könnte weiter und weiter machen, aber besser nicht.

Auf jeden Fall, um Ihre Frage zu beantworten, scheint es, dass diese Funktion einen Datenbankeintrag für einen Knoten in der versteckten Schicht eines neuronalen Netzwerks hinzufügt. Dieses neuronale Netzwerk hat, denke ich, Wörter in der Eingabeschicht und URLs in der Ausgabeschicht. Die Idee der Anwendung besteht darin, zu versuchen, ein neuronales Netzwerk zu trainieren, um basierend auf den Wörtern in der Abfrage gute Suchergebnisse (URLs) zu finden. Siehe die Funktion trainquery, die die Argumente (wordids, urlids, selectedurl) erhält. Vermutlich (da kein Docstring vorhanden ist, muss ich raten) waren wordids die vom Benutzer gesuchten Wörter, urlids sind die URLs, die die Suchmaschine dem Benutzer angeboten hat, und selectedurl ist die vom Benutzer ausgewählte. Die Idee besteht darin, das neuronale Netzwerk besser darauf vorzubereiten, vorauszusagen, welche URLs Benutzer wählen werden, und diese URLs daher in zukünftigen Suchergebnissen weiter oben zu platzieren.

Die geheimnisvolle Codezeile verhindert also, dass Knoten in der versteckten Schicht mit Verknüpfungen zu mehr als drei Knoten in der Eingabeschicht erstellt werden. Im Zusammenhang mit der Suchanwendung macht das Sinn: Es gibt keinen Grund, das Netzwerk auf Anfragen zu trainieren, die zu spezialisiert sind, da diese Anfragen nicht oft genug wiederkehren, um das Training lohnenswert zu machen.

0 Stimmen

Ich stimme voll und ganz mit deiner Kritik überein. Sowohl der Code als auch die Erklärung der Mathematik, die den Algorithmen zugrunde liegt, sind in diesem Buch schlampig. Als Vorschlag solltest du wahrscheinlich deine Antwort bearbeiten, um deine tatsächliche Antwort zuerst und die Kritik danach zu setzen. Wie bei einem guten Zeitungsartikel haben die besten Antworten das prägnante Wesentliche oben und den Beiwerk unten.

0 Stimmen

Danke. Ich dachte schon, ich sei eine Art Python-Gott und der einzige, der gemerkt hat, dass der Code in diesem Buch schlecht ist. Danke, dass du mich wieder auf den Boden der Tatsachen zurückgebracht hast. Dieses Buch ist eine interessante Einführung in maschinelles Lernen, aber der Code hat mich zum Weinen gebracht.

1voto

gotgenes Punkte 36305

Es wäre wahrscheinlich hilfreich gewesen, etwas mehr Kontext für den Code zu veröffentlichen. Hier ist der Absatz in Programming Collective Intelligence, der diesem Code unmittelbar vorausgeht:

Diese Funktion erstellt jedes Mal einen neuen Knoten im versteckten Layer, wenn sie eine Kombination von Wörtern erhält, die sie noch nie zuvor gesehen hat. Die Funktion erstellt dann standardgewichtete Verbindungen zwischen den Wörtern und dem versteckten Knoten sowie zwischen dem Abfrageknoten und den von dieser Abfrage zurückgegebenen URL-Ergebnissen.

Ich weiß, dass es immer noch nicht hilft, deine Frage zu beantworten, aber es hätte Gareth Rees geholfen, weniger spekulieren zu müssen. Gareth hat es sowieso richtig erraten, da er klug ist. Die Absicht besteht darin, die Anzahl der Wortknoten zu begrenzen, mit denen ein versteckter Knoten verknüpft sein kann, und der Autor hat die willkürliche Zahl von 3 gewählt.

Nur um mit Gareth übereinzustimmen, sollte dieser Absatz unbedingt im Docstring gestanden haben, und der Zweck der betreffenden Zeile sollte in einem Kommentar über der Zeile stehen. Ich hoffe, die nächste Ausgabe ist nicht so schlampig.

0voto

learnvst Punkte 14567

Um auf die obigen Kommentare einzugehen, schauen Sie sich dieses einfache Skript an...

def doSomething(wordids):
  if len(wordids)>3: return None
  print("Der Rest der Funktion wird ausgeführt")

blah = [2,3,4];
doSomething(blah)

blah = [2,3,4,5];
doSomething(blah)

. . also, wenn die Länge von wordids größer als 3 ist, macht die Funktion nichts. Es ist üblich, die Eingaben von Funktionen zu überprüfen, aber Fehler werden normalerweise in fortgeschritteneren Fällen mit Ausnahmen behandelt.

1 Stimmen

Ich vermute, dass der OP weiß, was die Zeile tut, nur nicht warum.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X