{"id":2350,"date":"2019-11-26T11:21:02","date_gmt":"2019-11-26T02:21:02","guid":{"rendered":"https:\/\/julialang.kr\/?p=2350"},"modified":"2019-11-26T11:32:58","modified_gmt":"2019-11-26T02:32:58","slug":"julia%ec%97%90%ec%84%9c-%ec%8b%9c%ea%b3%84%ec%97%b4-%eb%8d%b0%ec%9d%b4%ed%84%b0-%ec%b2%98%eb%a6%ac-%ec%98%88%ec%a0%9c-%eb%b3%91%eb%a0%ac%ec%b2%98%eb%a6%ac-with-gp","status":"publish","type":"post","link":"https:\/\/julialang.kr\/?p=2350","title":{"rendered":"Julia\uc5d0\uc11c \uc2dc\uacc4\uc5f4 \ub370\uc774\ud130 \ucc98\ub9ac \uc608\uc81c \u2013  \ubcd1\ub82c\ucc98\ub9ac (with GP)"},"content":{"rendered":"\n<p>\ud574\ub2f9 \uc81c\ubaa9\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \uae30\uc874\uc5d0 \uc62c\ub9b0 &#8220;Julia\uc5d0\uc11c \uc2dc\uacc4\uc5f4 \ub370\uc774\ud130 \ucc98\ub9ac \uc608\uc81c&#8221;\ub4e4\uc744 \ucc38\uc870 \ud558\uba74\ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc5ec\uae30\uc11c\ub294 \ub2e4\uc911 \ud504\ub85c\uc138\uc2a4\ub85c Genetic Programming(GP)\uc744 \ubcd1\ub82c\ucc98\ub9ac \ud558\ub294 \ubc29\ubc95\uc744 \ubcf4\uc5ec \uc90d\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\ub2e4\uc911 \ud504\ub85c\uc138\uc2a4\uac00 train, test\ud560 \ub370\uc774\ud130\ub294 SharedArray\ub85c \uacf5\uc720 \ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc544\ub798 \ubaa8\ub4c8\uc740 &#8220;\/home\/shpark\/julia_test\/exproptimizatoin\/examples&#8221; \ud3f4\ub354 \uc788\ub2e4\uace0 \uac00\uc815<br>WS.jl :  \uc5f0\uc2b5\uc6a9 \ub370\uc774\ud130\ub97c \ub9cc\ub4dc\ub294 \ubaa8\ub4c8 \/ \uc774 \uac8c\uc2dc\uae00\uc5d0\uc11c\ub294 WindowSlider \uad6c\uc870\uccb4\ub9cc \uc0ac\uc6a9\ud568<br>GP2.jl: Genetic Programming \uc801\uc6a9 \ubaa8\ub4c8<br>\uc544\ub798\uc5d0 \uc18c\uc2a4\ub97c \uac8c\uc81c \ud569\ub2c8\ub2e4.<br>\uadf8\ub9ac\uace0 GP2 \ud65c\uc6a9\uc740 jupyter notebook\uc73c\ub85c \ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4<\/p>\n\n\n\n<p> <a href=\"https:\/\/julialang.kr\/wp-content\/uploads\/2019\/11\/gp_parallel.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"\uad6c\ud604\uc18c\uc2a4(Julia Notebook \u2013 html \ubc84\uc804)  (\uc0c8\ud0ed\uc73c\ub85c \uc5f4\uae30)\">\uad6c\ud604\uc18c\uc2a4(Julia Notebook \u2013 html \ubc84\uc804) <\/a><\/p>\n\n\n\n<p>\uc774 \uc608\uc81c\uc5d0\uc11c\ub294 GP\ub97c \ud1b5\ud574  f(x1,x2) = 0.9 x1^2 + 0.7 <em>x1<\/em> x2 + 0.3 x2 \uc758 \uadfc\uc0ac\uc2dd\uc744 \ucc3e\uace0 \ud559\uc2b5 \ub418\uc9c0 \uc54a\uc740 \ub370\uc774\ud130 \ub300\ud55c <br>prediction\uc744 \ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p><strong>GP2.jl \uc18c\uc2a4<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module GP2\nusing Distributed \nusing Random\nusing ExprOptimization\nusing SharedArrays\n\nmutable struct DGrammar\n  grammar::Array{String,1}\n  function DGrammar()\n    grammar = Array{String,1}(undef,0)\n    push!(grammar,\"@grammar begin\")\n    push!(grammar,\"end\")\n    new(grammar)\n  end\nend\n#=\nexamples:\ngrmmar = DGrammar()\ngrmmar(\"R = R + R\")\ngrmmar(\"R = R - R\")\n=#\nfunction (g::DGrammar)(r::String)\n   insert!(g.grammar,2,r)\nend\n#=\nReturn Grammar\ngrmmar()\n=#\nfunction (g::DGrammar)()\n   eval(Meta.parse(join(g.grammar,\"\\n\")))\nend\n\nmutable struct Vars\n  v::Vector{String}\nfunction Vars()\n    v = Vector{String}(undef,0)\n    new(v)\n  end\nend\nfunction (vs::Vars)(s::String)\n  push!(vs.v,s)\nend\nfunction (vs::Vars)()\n  vars = \"([\"*join(vs.v,\",\")*\"])\"\nend\n\nfunction train(gp::GeneticProgram, grammar::Grammar, \n  train_x::Array{Float64,2},train_y::Array{Float64,1},nJob::Int64=1)\n  #=\n  nJob\uc774 1 \ubcf4\ub2e4 \ud06c\uba74 \ubcd1\ub82c\ucc98\ub9ac\n  =#\n  if nJob > 1\n    pids = addprocs(nJob)\n    module_dir = \"\/home\/shpark\/julia_test\/exproptimizatoin\/examples\"\n    # everywhere \uc0ac\uc6a9\uc2dc \uac01 process\uc5d0 \uac12\uc744 \ub118\uaca8 \uc8fc\ub824\uba74 interpolation\uc73c\ub85c \ub118\uaca8 \uc918\uc57c \ud55c\ub2e4.\n    @everywhere push!(LOAD_PATH, $module_dir) \n    eval(macroexpand(Distributed,quote @everywhere using GP2 end))\n    nr,nc = size(train_x)  \n    shared_train_x = SharedArray{Float64}((nr,nc),pids=pids)\n    shared_train_y = SharedArray{Float64}((nr,1),pids=pids)\n    shared_train_x[:,:] = train_x\n    shared_train_y[:,:] = train_y\n      \n    rps = [@spawnat i GP2._train_parallel(gp,grammar,\n          shared_train_x,shared_train_y)  \n        for i in pids]\n    ms = map(x->fetch(rps[x]),1:length(rps))\n    # nJob\uac1c\uc758 \ud504\ub85c\uc138\uc2a4\uc5d0\uc11c \uac00\uc838\uc628 \uacb0\uacfc\uc911 loss\uac00 \uac00\uc7a5 \uc791\uc740\n    # \uac1c\uccb4\ub97c \uace8\ub77c \ub0b8\ub2e4.\n    # m\uc758 \ud0c0\uc785 \ubc0f \ub0b4\ubd80 fields\ub97c \uc54c\ub824\uba74\n    # type\ud655\uc778 : typeof(m)\n    # fields \ud655\uc778 : fieldnames(typeof(m))\n    r = ms[argmin([m.loss for m in ms ])]\n    rmprocs(pids)    \n  else\n    r = _train(gp,grammar,train_x,train_y)\n  end\n  return r\nend\n\n\nfunction _train(gp::GeneticProgram, grammar::Grammar, \n  train_x::Array{Float64,2},train_y::Array{Float64,1})\n    \n  S = SymbolTable(grammar)\n  \n  function loss(tree::RuleNode, grammar::Grammar)\n    ex = get_executable(tree,grammar)\n    nr,nc = size(train_x)\n    \u03a3\u0394y = 0 \n    for r in 1:nr\n      for c in 1:nc\n        x = train_x[r,c]      \n        S[Symbol(\"x\",c)] = x        \n      end\n      y_fit = Core.eval(S,ex)      \n      y = train_y[r]\n      \u03a3\u0394y += (y - y_fit)^2\n    end  \n    los = sqrt(\u03a3\u0394y)\/nr\n  end    \n  results_gp = optimize(gp, grammar, :R, loss,verbose=true)\n  return results_gp  \nend\n  \nfunction _train_parallel(gp::GeneticProgram, grammar::Grammar, \n  train_x::SharedArray,train_y::SharedArray)\n  \n  S = SymbolTable(grammar)\n  \n  function loss(tree::RuleNode, grammar::Grammar)\n    ex = get_executable(tree,grammar)\n    nr,nc = size(train_x)\n    \u03a3\u0394y = 0 \n    for r in 1:nr\n      for c in 1:nc\n        x = train_x[r,c]      \n        S[Symbol(\"x\",c)] = x        \n      end\n      y_fit = Core.eval(S,ex)      \n      y = train_y[r]\n      \u03a3\u0394y += (y - y_fit)^2\n    end  \n    los = sqrt(\u03a3\u0394y)\/nr\n  end    \n  results_gp = optimize(gp, grammar, :R, loss,verbose=true)\n  return results_gp\nend\n\nfunction predict(results_gp::ExprOptResult,grammar::Grammar,test_x::Array{Float64,2})\n  #=\n  Prediction \n  =#\n  S = SymbolTable(grammar)\n  ex = results_gp.expr\n  nr,nc = size(test_x)\n  y = Array{Float64,1}(undef,0)\n  for r in 1:nr\n    for c in 1:nc\n      x = test_x[r,c]\n      S[Symbol(\"x\",c)] = x\n    end\n    push!(y, Core.eval(S,ex))\n  end\n  y\nend    \n\nend # module GP2<\/code><\/pre>\n\n\n\n<p><strong>WS.jl \uc18c\uc2a4<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module WS\nusing Random\nusing DataFrames\nusing CSV\n\nmutable struct WindowSlider\n  w::Int # window_size - number of time steps to look back\n  o::Int # offset between last reading and temperature\n  r::Int # response_size - number of time steps to predict\n  l::Int # maximum length to slide - (#observation - w)\n  p::Int # final predictors - (#predictors * w)\n  names::Array{Symbol,1}\n  function WindowSlider(;window_size::Int=5)\n    w = window_size\n    o = 0\n    r = 1\n    l = 0\n    p = 0\n    names = Array{Symbol,1}(undef,0)\n    new(w,o,r,l,p,names)\n  end\nend\n\nfunction re_init(arr::Array{Float64,1})\n  cumsum!(arr,arr;dims=1)\n  return arr .- arr[1]\nend\n\nfunction collect_windows(ws::WindowSlider,X::DataFrame;window_size::Int=5, offset::Int=0,previous_y = false)\n  N, cols = size(X)\n  cols -= 1\n  ws.o = offset\n  ws.w = window_size\n  ws.l = N - (ws.w + ws.r) + 1\n  ws.p = previous_y ? (cols + 1) * ws.w : cols * ws.w\n  \n  # create the names of the variables in the window\n  # Check first if we need to create that for the response itself\n  x = previous_y ? deepcopy(X) : select(X,Not(names(X)[end]))\n  \n  for col in names(x)\n    for i in 1:ws.w\n      #= python\uc5d0\uc11c\ub294 \u0394t(1)\uc744 \uceec\ub7fc \uc774\ub984\uc73c\ub85c \uc0ac\uc6a9\ud558\uace0 \uc788\uc73c\ub098\n      \uc904\ub9ac\uc544\uc5d0\uc11c\ub294 \uad04\ud638\ub4f1 \ud2b9\uc218 \ubb38\uc790\ub294 Symbol\ub85c \ud5c8\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4\n      \uc904\ub9ac\uc544\uc758 DataFrame\uc758 \uceec\ub7fc\uc740 symbol\uc774 \uc0ac\uc6a9\ub418\uace0 \ucc38\uc870\uc2dc\uc5d0\ub3c4 \n      symbol\uc774 \uc0ac\uc6a9\ub41c\ub2e4.\n      \uc608\ub97c \ub4e4\uc5b4 df.\u0394t_1 \uc740 \ud558\uc6a9\ub418\ub098 df.\u0394t(1)\uc740 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4.\n      =#\n      # t(1),..,t(w1),x1(1),...,x1(w)\n      name = Symbol(col,\"_\",i)\n      push!(ws.names,name)\n    end\n  end  \n  \n  # Incorporate the timestamps where we want to predict\n  # t(w),..,t(w+r-1)\n  for k in 1:ws.r\n    name = Symbol(\"\u0394t\",\"_\",ws.w + k)\n    push!(ws.names, name)\n  end\n  push!(ws.names, :Y)\n  \n  df = DataFrame(zeros(ws.l,ws.p + ws.r + 1), ws.names) \n  \n  # Populate by rows in the new dataframe\n  for i in 1:ws.l    \n    # 2\ucc28\uc6d0 \ubc30\uc5f4 0 \ud06c\uae30\uc758 cols\uac1c\uc758 \uceec\ub7fc\uc744 \uac00\uc9c4 \ubc30\uc5f4\ub85c \ucd08\uae30\ud654\n    slices = Array{Float64,1}(undef,0)\n    # Flatten the lags of predictions\n    _, cols = size(x)\n    # Julia\uc5d0\uc11c a[1:3] \uc774\uba74 1 \ubd80\ud130 3 \uae4c\uc9c0 index\uc758 3\uac1c\uc758 \uac12\uc744 \uac00\uc838\uc628\ub2e4.\n    # Python\uc5d0\uc11c\ub294 1 \ubd80\ud130 2\uae4c\uc9c0 2\uac1c\uc758 \uac12\uc744 \uac00\uc838\uc628\ub2e4.\n    for p in 1:cols\n      line = X[i:ws.w + i - 1,p]\n      # Reinitialization at every window for \u0394t\n      if p == 1 \n        line = re_init(line) \n      end\n      \n      # Concatenate the lines in one slice\n      push!(slices, line...)\n    end\n    \n    # Incorporate the timestamps where we want to predict\n    # predict \ub77c\uc778\uc758 \uc989 \uc708\ub3c4\uc6b0\uc5d0\uc11c w+r \ubc88\uc9f8\uc758 \n    line = re_init(X[i:ws.w + ws.r + i - 1, 1])[end]\n    y = X[ws.w + ws.r + i - 1, end]\n    push!(slices,line..., y...)\n    \n    # Incorporate the slice to the cake(df)\n    df[i,:] .= slices\n  end\n  return df\nend\n\n\nfunction _data_set(;N::Int=600,window_size::Int=5, seed::Int=123)\n  Random.seed!(seed)\n  N = N\n  #t = Float64[0:N-1...]\n  t = Float64[0:N-1;]\n  t = t .+ rand(N) \/ 4\n  t = t .- rand(N) \/ 7\n  t = round.(t; digits=2)\n  x1 = round.(rand(N)*5;digits=2)\n  x2 = round.(rand(N)*5;digits=2)\n  x3 = round.(rand(N)*5;digits=2)\n  n  = round.(rand(N)*2;digits=2)\n\n  x1_1 = circshift(x1,1) # t-1\n  x2_1 = circshift(x2,1) # t-1\n  x3_3 = circshift(x3,3) # t-3  \n\n  y = @. log(abs(2 + x1))-x2_1^2 + 0.02*x3_3*exp(x1_1)\n  y = @. round(y+n,digits=2) \n  \u0394t = t[2:end] .- t[1:end-1]\n  insert!(\u0394t,1,0)\n  df = DataFrame([t \u0394t x1 x2 x3 y],[:t,:\u0394t,:x1,:x2,:x3,:y])\n  return df\nend\n\nstruct Dataset\n  t::Array{Float64,1}\n  n_train::UnitRange{Int64}\n  n_test::UnitRange{Int64}\n  train::DataFrame\n  test::DataFrame\n  train_windows::DataFrame\n  test_windows::DataFrame\n  train_windows_y_inc::DataFrame\n  test_windows_y_inc::DataFrame\nend\n\nfunction data_set(;N::Int=600,window_size::Int=5, seed::Int=2018,\n                n_train=1:160,n_test=161:200)\n  \n  df = _data_set(N=N,window_size=window_size,seed=seed)\n  t = df.t\n  train = df[n_train,2:end]\n  test = df[n_test,2:end]  \n  train_windows = collect_windows(WindowSlider(),train,previous_y=false)    \n  test_windows = collect_windows(WindowSlider(),test,previous_y=false)\n  train_windows_y_inc = collect_windows(WindowSlider(),train,previous_y=true)    \n  test_windows_y_inc = collect_windows(WindowSlider(),test,previous_y=true)\n  return Dataset(t,n_train, n_test,\n    train,test,\n    train_windows,test_windows,\n    train_windows_y_inc,test_windows_y_inc)\nend\n\nfunction data_kospi(;N::Int=600,window_size::Int=5, seed::Int=2018,\n                n_train=1:160,n_test=161:200)\n  df = CSV.read(\"kospi.csv\")  \n  df2 = df[n_train[1]:n_test[end],:]\n  select!(df2, Not([:close,:date]))\n  # \ub2e4\uc74c\ub0a0 \uc885\uac00\n#   next_day_close = df[n_train[2]:n_test[end]+1,end]\n#   _,nc = size(df2)\n#   insertcols!(df2,nc+1,:next_day_close=>next_day_close)\n  #=\n  \uac01 \uceec\ub7fc \ub370\uc774\ud130\ub97c \uc815\uaddc\ud654 \ud55c\ub2e4.\n  \ub2e8 train data\uc758 max\uac12\uc73c\ub85c train \ubc0f test \ub370\uc774\ud130\ub97c \uc815\uaddc\ud654 \ud55c\ub2e4.\n  \uc989 train\uc2dc \uc801\uc6a9\ub418\uc5c8\ub358 \uc870\uac74\uc744 test data\uc5d0 \uc801\uc6a9\ud55c\ub2e4.\n  =#  \n  for i in 1:size(df2)[2]\n    c_max = max(df2[n_train,i]...)\n    df2[!,i] = df2[!,i]\/c_max  \n  end \n  t = Float64[(n_train[1]:n_test[end])...]\n  \u0394t=ones(n_test[end])\n  insertcols!(df2,1,:t=>t)\n  insertcols!(df2,2,:\u0394t=>\u0394t)\n\n  train= df2[n_train,2:end]\n  test= df2[n_test,2:end]  \n  train_windows= collect_windows(WindowSlider() ,train,previous_y=false,window_size=window_size)    \n  test_windows= collect_windows(WindowSlider(),test,previous_y=false,window_size=window_size)\n  train_windows_y_inc= collect_windows(WindowSlider(),train,previous_y=true,window_size=window_size)    \n  test_windows_y_inc= collect_windows(WindowSlider(),test,previous_y=true,window_size=window_size)\n  return Dataset(t,n_train, n_test,\n    train,test,\n    train_windows,test_windows,\n    train_windows_y_inc,test_windows_y_inc)\nend\n\nend # module WS<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\ud574\ub2f9 \uc81c\ubaa9\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \uae30\uc874\uc5d0 \uc62c\ub9b0 &#8220;Julia\uc5d0\uc11c \uc2dc\uacc4\uc5f4 \ub370\uc774\ud130 \ucc98\ub9ac \uc608\uc81c&#8221;\ub4e4\uc744 \ucc38\uc870 \ud558\uba74\ub429\ub2c8\ub2e4. \uc5ec\uae30\uc11c\ub294 \ub2e4\uc911 \ud504\ub85c\uc138\uc2a4\ub85c Genetic Programming(GP)\uc744 \ubcd1\ub82c\ucc98\ub9ac \ud558\ub294 \ubc29\ubc95\uc744 \ubcf4\uc5ec \uc90d\ub2c8\ub2e4. \ub2e4\uc911 \ud504\ub85c\uc138\uc2a4\uac00 train, test\ud560 \ub370\uc774\ud130\ub294 SharedArray\ub85c \uacf5\uc720 \ud569\ub2c8\ub2e4. \uc544\ub798 \ubaa8\ub4c8\uc740 &#8220;\/home\/shpark\/julia_test\/exproptimizatoin\/examples&#8221; \ud3f4\ub354 \uc788\ub2e4\uace0 \uac00\uc815WS.jl : \uc5f0\uc2b5\uc6a9 \ub370\uc774\ud130\ub97c \ub9cc\ub4dc\ub294 \ubaa8\ub4c8 \/ \uc774 \uac8c\uc2dc\uae00\uc5d0\uc11c\ub294 WindowSlider \uad6c\uc870\uccb4\ub9cc \uc0ac\uc6a9\ud568GP2.jl: Genetic Programming \uc801\uc6a9 \ubaa8\ub4c8\uc544\ub798\uc5d0 \uc18c\uc2a4\ub97c \uac8c\uc81c \ud569\ub2c8\ub2e4.\uadf8\ub9ac\uace0 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"default","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[18,19,20,29,22],"tags":[],"_links":{"self":[{"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/posts\/2350"}],"collection":[{"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/julialang.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2350"}],"version-history":[{"count":5,"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/posts\/2350\/revisions"}],"predecessor-version":[{"id":2357,"href":"https:\/\/julialang.kr\/index.php?rest_route=\/wp\/v2\/posts\/2350\/revisions\/2357"}],"wp:attachment":[{"href":"https:\/\/julialang.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/julialang.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/julialang.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}