无法理解“集体智慧”计划中的一句话

时间:2010-11-18 14:58:33

标签: python debugging

我正在完成“Programming collective intelligence”。在第4章中,Toby Segaran构建了一个人工神经网络。本书页面上显示以下功能:

def generatehiddennode(self,wordids,urls):
  if len(wordids)>3: return None
  # Check if we already created a node for this set of words
  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()

  # If not, create it
  if res==None:
    cur=self.con.execute(
    "insert into hiddennode (create_key) values ('%s')" % createkey)
    hiddenid=cur.lastrowid
    # Put in some default weights
    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()

我无法理解的是这个函数第一行的原因:'if len(wordids> 3):return None`。它是一个需要稍后删除的调试代码吗?

P.S。这不是作业

3 个答案:

答案 0 :(得分:6)

对于已出版的书籍,这是非常可怕的代码! (您可以下载该书的所有示例from here;相关文件为chapter4/nn.py。)

  • 没有docstring。这个函数应该做什么?从它的名字,我们可以猜测它正在生成神经网络“隐藏层”中的一个节点,但wordidsurls扮演什么角色?
  • 数据库查询使用字符串替换,因此易受SQL注入攻击(特别是因为这与网络搜索有关,因此wordids可能来自用户查询,因此可能不受信任 - 但是,也许他们是ids而不是单词所以它在实践中是可以的,但仍然是一个非常糟糕的习惯进入)。
  • 不使用数据库的强大功能:如果您只想确定数据库中是否存在密钥,那么您可能希望使用SELECT EXISTS(...)而不是要求数据库向您发送一堆你将要忽略的记录。
  • 如果已有createkey的记录,则函数不执行任何操作。没错。那是对的吗?谁能说出来?
  • 单词的权重按比例缩放为单词数,但网址的权重是常量0.1(也许总共有10个网址,但是按{{1这里)。

我可以继续,但最好不要。

无论如何,为了回答你的问题,看起来这个函数正在为neural network的隐藏层中的节点添加数据库条目。我认为,这个神经网络有输入层中的单词和输出层中的URL。该应用程序的想法是尝试训练神经网络以基于查询中的单词找到良好的搜索结果(URL)。查看函数len(urls),它接受​​参数trainquery。据推测(因为没有文档字符串我必须猜测)(wordids, urlids, selectedurl)是用户搜索的字词,wordids是搜索引擎为用户提供的网址,urlids是用户的网址采摘。我们的想法是培训神经网络以更好地预测用户将选择哪些网址,从而将这些网址放在未来的搜索结果中。

因此,神秘的代码行阻止了在隐藏层中创建的节点,其中包含指向输入层中三个以上节点的链接。在搜索应用程序的上下文中,这是有道理的:在过于专业化的查询中训练网络是没有意义的,因为这些查询不会经常重复,以使培训值得。

答案 1 :(得分:1)

您可能应该为代码发布更多上下文。以下是 Programming Collective Intelligence 中的段落,它紧接在该代码之前:

  

此功能将创建一个新节点   每次都在隐藏层中   通过了它的组合词   以前从未见过。该   函数然后创建默认加权   单词和隐藏之间的联系   节点,以及查询节点和   这个返回的URL结果   查询。

我意识到它仍然没有帮助回答你的问题,但它可以通过减少猜测来帮助Gareth Rees解决问题。无论如何,Gareth仍然是正确的,因为他很聪明。目的是限制隐藏节点可以关联的单词节点的数量,并且作者选择任意数量为3。

再次与Gareth达成一致,该段应该完全属于文档字符串,并且该行的目的应该是在该行上方的注释中。我希望下一版不那么草率。

答案 2 :(得分:0)

详细说明上述评论,请看这个简单的脚本......

def doSomething(wordids):
  if len(wordids)>3: return None
  print("The rest of the function executes")


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

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

。 。因此,如果wordid的长度超过3,则该函数不执行任何操作。通常检查函数的输入,但通常在更高级的情况下使用异常处理错误。