Optimization 朱莉娅:优化函数

Optimization 朱莉娅:优化函数,optimization,julia,Optimization,Julia,我正在努力学习编写好的代码。我想把下面的统计数字编出来 (注1{A}=1如果为真,则为0如果为假) 在哪里 及 这是最有效的编码方式吗 编辑: 谢谢大家的建议。你能解释一下为什么你的代码更高效吗?我想学习如何在将来继续编写好代码 针对@user3580870进行测试我们有两个示例 @time [cohens_kappa(X, k) for k in 1:15] 0.000507 seconds (1.58 k allocations: 269.016 KB) @time [cohen

我正在努力学习编写好的代码。我想把下面的统计数字编出来

(注1{A}=1如果为真,则为0如果为假)

在哪里

这是最有效的编码方式吗

编辑: 谢谢大家的建议。你能解释一下为什么你的代码更高效吗?我想学习如何在将来继续编写好代码

针对@user3580870进行测试我们有两个示例

@time [cohens_kappa(X, k) for k in 1:15]
  0.000507 seconds (1.58 k allocations: 269.016 KB)

@time [cohens_kappa2(X, k) for k in 1:15]
  0.000336 seconds (166 allocations: 12.375 KB)

@time [cohens_kappa3(X, k) for k in 1:15]
  0.000734 seconds (303 allocations: 84.109 KB)

看起来你的第二个建议没有那么快,但是它比我的原始版本分配的更少,所以对于非常大的向量可能更快

这里是另一个版本,它提供了显著的改进:

   function cohens_kappa2(x::Vector{Int}, k::Int)
     d = Dict{Int,Int}()
     n = length(x)
     c1 = Int[]
     pnew = 0
     for i=1:n
       p = get(d,x[i],0)
       if p>0
         c1[p] += 1
       else
         pnew += 1
         d[x[i]] = pnew
         push!(c1,1)
       end
     end
     c2 = zeros(Int,pnew)
     for i=(k+1):n
       if x[i-k]==x[i] c2[d[x[i]]] += 1 ; end
     end
     num, dentmp = 0.0, 0.0
     for i=1:pnew
       pjjk = c2[i]/(n-k)
       pj = c1[i] / n
       num += pjjk - pj^2
       dentmp += pj^2
     end
     return (num / (1.0-dentmp))
   end
一般来说,优化几乎总是可能的,但就像从自然界中提取石油一样,程序员的成本和精力也在不断增加


在一个测试用例中,上面的代码给了我5到10倍的加速。您的数据结果如何?

还有一个优化可用。要查找自相关性,您只需使用逻辑索引找到的减少的匹配向量:

function cohens_kappa_2(x::vector{Int},k:Int)

  ...

  # Autocorrelation dictionary
  dxx=Dict{Int,Int}()

  # k-step element-wise matches
  xx=(x[1:end-k])[x[1:end-k] .== x[1+k:end]]

  # Populate the dictionary
  for exx in xx
    dxx[exx] += 1 # Warning! pseudo-code
  end

  ...

end
关键的洞察是,统计数据的自相关部分只“关心”与前面k步元素匹配的元素,因此我们可以先检查这一点


请注意,之所以使用字典,是因为它的哈希允许唯一元素的线性时间分辨率。相比之下,unique函数将实现某种形式的排序、堆或树结构,其平均性能为O(N*lnN)。

添加另一个版本。这一个比我在另一个答案中给出的更长的展开版本稍慢。另一方面,它更干净,并且使用
数据结构
包的
计数器
。在代码中,
cc
统计所有元素及其频率,
cc2
统计相同元素的距离对。资料来源:

using DataStructures     # install with Pkg.add("DataStructures")

function cohens_kappa3(x::Vector{Int}, k::Int)
      n = length(x)
      cc = counter(x)
      cc2 = counter(x[[i<=k ? false : x[i]==x[i-k] for i=1:n]])
      num, den = 0.0,1.0
      for (val,freq) in cc
          pj2 = (freq/n)^2
          num += cc2[val]/(n-k)-pj2
          den -= pj2
      end
      return num/den
end
使用数据结构#与Pkg.add一起安装(“数据结构”)
函数cohens_kappa3(x::Vector{Int},k::Int)
n=长度(x)
cc=计数器(x)

cc2=计数器(x[[iBTW]另一个答案中的代码已经实现了此优化,但不太清楚(如果x[i-k]==x[i]c2[d[x[i]]]+=1,则在
行中)。当前,
unique
函数使用线性扫描和
Set
类型变量来跟踪元素。因此,它与
Dict
一样有效。在任何情况下,请使用
@edit unique([1,2,2,3])
查看
unique
的实际代码。假设向量的支持度为K值和长度N。问题中的算法生成K个向量。生成过程采用K*N比较。相比之下,答案中的算法只扫描向量固定次数(两次)。当K较大时,答案算法应具有更大的优势。(数据中的K是多少?)在我的数据中,K通常相当小(小于10),优化Julia代码的必读内容是。甚至建议每隔一段时间重新读取一次(Julia正在增长和变化)。由于数据中的K<10,效率上的差异并不显著。请尝试使用K=100的数据(例如,
X=rand(1:100,N)
并使N变大,因此运行时间大约为0.01秒,以便更好地计时)
using DataStructures     # install with Pkg.add("DataStructures")

function cohens_kappa3(x::Vector{Int}, k::Int)
      n = length(x)
      cc = counter(x)
      cc2 = counter(x[[i<=k ? false : x[i]==x[i-k] for i=1:n]])
      num, den = 0.0,1.0
      for (val,freq) in cc
          pj2 = (freq/n)^2
          num += cc2[val]/(n-k)-pj2
          den -= pj2
      end
      return num/den
end