【发布时间】:2021-02-04 12:10:30
【问题描述】:
我是 Clojure 领域的新手,也是函数式编程的新手。我正在尝试编写一个函数来计算给定词汇表(只是单词列表)和一组概率(每个单词出现的概率)的特定单词列表出现的概率。我正在使用简化的词袋模型,并且假设每个结果都是独立的。
例如,给定:
- 词汇(相关概率):sleep (0.3)、dog (0.09)、a (0.2)、the (0.05)、cow (0.17)、boat (0.04)、everything (0.15)
- 句子:
(list 'the 'dog 'boat)
我希望它计算 (0.05) * (0.09) * (0.04) = 0.00018
我已经有一个函数可以获取每个单词的概率,它可以按预期工作。我把它贴在这里供参考:
(defn lookup-probability [w outcomes probs]
(if (not= w (first outcomes)) ;;if the current element is not equal to the word we're looking for...
(lookup-probability w (rest outcomes) (rest probs)) ;;...keep cycling through the vocabulary
(first probs) ;;once we find the right word, fetch the corresponding entry in the probability list
)
)
这是我感到困惑的部分:
(def sentenceprobs '()) ;;STEP 1
(defn compute-BOW-prob [sentence vocabulary probabilities]
(if (not(empty? sentence))
(def sentenceprobs (conj sentenceprobs (lookup-probability (first sentence) vocabulary probabilities)) ;;STEP 2
(compute-BOW-prob (rest sentence) vocabulary probabilities) ;;STEP 3
)
(product sentenceprobs) ;;STEP 4 (the product function just multiplies all the elements of a list together)
)
)
这是我的总体策略:
- 首先定义一个空列表“sentenceprobs”,我将在其中存储句子中每个单词的概率
- 如果句子非空,则将第一个单词的概率添加到列表“sentenceprobs”
- 在句子的其余部分递归调用函数(减去我们刚刚找到概率的单词,ofc)
- 一旦句子为空,即我们已经获取了每个单词的概率,返回“sentenceprobs”中所有元素的乘积
如果我只想使用该功能一次,这很好用。但是,如果我想多次调用它,sentenceprobs 仍然包含上一次调用的所有概率。该函数仍将运行,但它只是给了我错误的概率(小得多)。 所以我尝试在函数的最后重置 sentenceprobs 的值以使其“可重用”:
(def sentenceprobs '())
(defn compute-BOW-prob [sentence vocabulary probabilities]
(if (not(empty? sentence))
(def sentenceprobs (conj sentenceprobs (lookup-probability (first sentence) vocabulary probabilities))
(compute-BOW-prob (rest sentence) vocabulary probabilities)
)
(product sentenceprobs)
)
(def sentenceprobs '()) ;; <---THIS IS WHAT I ADDED
)
当我这样做时,该函数根本不会返回任何内容。从某种意义上说,这是意料之中的,因为函数必须在此列表上返回一个操作,因此将其设为空可能会搞砸。但我认为,由于我在退出 if 语句之前递归并返回一个值,所以这不是问题。我想我错了哈哈。
我在 Internet 上进行了一些探索,似乎这不是 def 在 Clojure 中的工作方式,但我不知道如何解决它。有谁知道我怎样才能做到这一点?非常感谢。
【问题讨论】:
-
只是一般提示:切勿在
defn或类似名称中使用def。仅使用def作为顶级元素。 (总有一天你可以做到,但到那时你就会对 Clojure 有足够的了解。所以,现在不要这样做。)
标签: clojure functional-programming nlp