f# - 如何创建一个可以测试另一个函数的随机单词共现的函数?
问题描述
所以我和我的团队创建了一个函数 wordMarkovChain,它生成一个包含 nWords 个单词的随机字符串,其单词对根据共现直方图 wCooc 分布。现在我们想创建一个函数来测试新创建的 wordMarkovChain,所以我可以确认它正在正常工作。函数 diffw2 将两个同现直方图作为平均平方差的和进行比较,需要接受两个 wordCooccurrences 类型的参数 c1 和 c2 并返回一个双精度值,其中 c1 和 c2 是 M 个元素的两个同现直方图,使得c1(i, j) 是在单词 j 之后找到单词 i 的次数。
函数背后的数学应该如下所示: 1/M^2 * 从 i=0 到 M-1 的总和 从 i=0 到 M-1 的总和 (c1(i, j) - c2(i, j))^ 2.
抱歉,我无法发布图片:( 我们创建的两种类型似乎是问题所在。c1 和 c2 可以有不同的长度,但是 wordCoocurence 类型中的 wordHistogram 类型也可以有不同的长度。
问题是, 我们如何创建这样的函数?我们尝试了 for 循环,但我们认为它需要是一个递归函数。我们对整个编程概念还很陌生,正在寻找一些指导。请记住,我们这样做没有丰富的 F# 知识,尤其是它们的构建功能。
代码
// Types
type wordHistogram = (string * int) list
type wordCooccurrences = (string * wordHistogram) list
let diffw2 (c1 : wordCooccurrences) (c2 : wordCooccurrences) : double =
let mutable res = 0
let z1, z2 = c1 |> List.unzip
let z3, z4 = c2 |> List.unzip
let m1 = c1 |> List.length
let m2 = c2 |> List.length
let m = m1 + m2
for i in 0 .. (m - 1) do
for j in 0 .. (m - 1) do
for k in 0 .. ((z2.[j] |> List.length) - 1) do
res <- res + (snd z2.[j].[k] - snd z4.[j].[k]) * (snd z2.[j].[k] - snd z4.[j].[k])
(1.0 / (float(m * m))) * float(res)
解决方案
这可能会让你更接近你需要的东西。这可以使用递归函数来完成,但我通常更喜欢使用内置的高阶函数,比如fold
or fold2
when they can do the job。请参阅https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/list.fold2%5B 't1%2C't2%2C'state%5D-function-%5Bfsharp%5D
每次调用List.fold2
都会收到一个初始值(或“状态”)为 0.0 的“累加器”。这个累加器在名为“acc”的参数中传递给 lambda 函数。当 lambda 应用于两个输入列表的每个元素时,它将中间结果添加到该acc
值,然后作为List.fold2
调用的结果返回。
type wordHistogram = (string * int) list
type wordCooccurrences = (string * wordHistogram) list
let diffw2 (c1 : wordCooccurrences) (c2 : wordCooccurrences) =
let m1 = c1 |> List.length
let m2 = c2 |> List.length
let m = m1 + m2
let res =
(0.0, c1, c2) |||>
List.fold2 (fun acc (_str1, hist1) (_str2, hist2) ->
let intermedRes =
(0.0, hist1, hist2) |||>
List.fold2 (fun acc (_str1, freq1) (_str2, freq2) ->
let diff = float (freq1 - freq2)
acc + diff * diff
)
acc + intermedRes
)
(1.0 / float(m * m)) * res
推荐阅读
- r - R ggplot 基于条件的垂直线,但在 facet_grid 命令之后?
- powershell - powershell 计划作业无法运行
- reactjs - 如何在本机反应中访问其他文件夹中的资产?
- python - 如何在不关闭python窗口的情况下从一点画线并更新它
- python - 使用 python 在 JSON 有效负载中传递字符串
- javascript - Mongodb 聚合查询 $addFields
- dataframe - 在 PySpark 中重新排列列
- pdf - 使用相同的 Markdown 渲染将 Jupyter Notebook 导出为 PDF
- javascript - 我想找到这个函数来自哪里
- perl - 需要修改perl Deep::Hash::Utils