【问题标题】:Clojure Lang Arity ExceptionClojure 语言异常
【发布时间】:2018-11-09 15:22:38
【问题描述】:

我一直在尝试实现垃圾邮件分类器。我写了一个函数来获得一些概率,但是当我用两个参数调用这个函数时,我得到 clojure.lang.ArityException “传递给函数的参数数量错误”。这是我的功能:

(defn weightedprob
  [f cat]
  (let [weight 1
        ap 0.5
        basicprob (atom 0)
        totals (atom 0)
        bp (atom 0)]
    (swap! basicprob #(fprob f cat))
    (swap! totals #(reduce + (vals (get @fc f))))
    (swap! bp #(/ (+ (* weight ap) (* totals basicprob)) (+ weight totals)))
    bp))

这是电话:

(weightedprob "money" "good")

现在可以了。如果您对如何实现此功能有更好的了解,我会很高兴看到这一点。这是有效的版本:

(defn weightedprob
  [f cat]
   (let [weight 1
   ap 0.5
   basicprob (atom 0)
   totals (atom 0)
   bp (atom 0)]
  (reset! basicprob (fprob f cat))
  (reset! totals (reduce + (vals (get @fc f))))
  (reset! bp (/ (+ (* weight ap) (* @totals @basicprob)) (+ weight 
  @totals)))
  @bp))

我一直在实现的 Python 中的函数如下所示:

  def weightedprob(self,f,cat,prf,weight=1.0,ap=0.5):    
      # Calculate current  probability    
      basicprob=prf(f,cat)
      # Count the number of times this feature has appeared in    
      # all categories    
      totals=sum([self.fcount(f,c) for c in self.categories()])
      # Calculate the weighted average    
      bp=((weight*ap)+(totals*basicprob))/(weight+totals)    
      return bp 

这是来自集体智慧书,第 6 章,文档过滤

没有原子的函数:

(defn weightedprob1
 [f cat]
  (let [weight 1
        ap 0.5
        basicprob (fprob f cat)
        totals (reduce + (vals (get @fc f)))
        bp (/ (+ (* weight ap) (* totals basicprob)) (+ weight totals))]
  bp))

【问题讨论】:

  • 在你给swap!的函数中,你没有使用提供的参数。预计您的 #() 函数将接受一个参数 (%)。你的意思是(reset! basicprob (fprob f cat))?不过,看起来您甚至不应该在这里使用原子。如果您发布minimal reproducible example,我们可以建议应该如何编写。不过,以目前的形式,它应该做什么还不清楚。
  • (* totals basicprob) 之类的内容看起来完全错误。至少您必须取消引用(例如@totals)才能获得价值。这段代码有非常难闻的气味;就像有人告诉你使用原子来改变数据,现在你在任何地方都使用它们——这段代码对我来说看起来很不拘谨。正如已经建议的那样,请在此处提供有关全局的更多信息,如果这确实是您在这里采取的正确路线。
  • 如果没有原子,你将如何解决这个函数?我只能直接在 let 表达式或原子中解决这个问题。

标签: clojure


【解决方案1】:

您最初的问题是由 swap! 期望使用单个参数的函数引起的。您提供了一个不带任何参数的函数,因此出现了错误。

更正后的代码将是您已经发布的代码:

(defn weightedprob [f cat]
  (let [weight 1
        ap 0.5
        basicprob (atom 0)
        totals (atom 0)
        bp (atom 0)]
    (reset! basicprob (fprob f cat))
    (reset! totals (reduce + (vals (get @fc f))))
    (reset! bp (/ (+ (* weight ap) (* @totals @basicprob)) (+ weight @totals)))
    @bp))

不过,这根本不需要原子。原子主要只是用于管理线程之间的数据。你在这里根本不需要任何类型的突变。继续使用let

(defn weightedprob [f cat]
  (let [weight 1
        ap 0.5
        basicprob (fprob f cat)
        totals (reduce + (vals (get @fc f)))]
   (/ (+ (* weight ap) (* totals basicprob)) (+ weight totals)))) 

目前还不清楚fc 是什么,但它可能也不需要是原子。

【讨论】:

  • 是的,我做了类似的事情。你可以在上面检查。 "fc 变量会存储不同分类中不同特征的计数。例如:{'python': {'bad': 0, 'good': 6}, 'the': {'bad': 3, 'good ':3}}“。在这个例子中,“python”这个词已经出现在六个好的文档中,并且没有出现在坏文档中。
猜你喜欢
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
相关资源
最近更新 更多