簡體   English   中英

創建一個由Julia中的所有多項式組合組成的新特征矩陣

[英]Create a new feature matrix consisting of all polynomial combinations in Julia

我試圖找到一些有效的 function 來生成一個新的特征矩陣,該特征矩陣由 Julia 中原始矩陣的所有多項式組合組成。例如,如果我有一個數據幀/矩陣如下:

X
1個 3個
2個 4個

然后我要生成的數據框/矩陣是:

X x^2 y^2 x*y
1個 3個 1個 9 3個
2個 4個 4個 16 8個

在 Python 中給出相同的 output 的 function 將是:

mpoly =  PolynomialFeatures(degree=degree,include_bias=False)    
x = mpoly.fit_transform(df[varnm].values)

目前,在 Julia 中,我創建並使用了下面的 function:

function poly(data, vars, deg)
    df = data
    mat = Matrix(df[:,vars])
    if deg == 1
        p = mat
        varnm = vars
    end
    if deg == 2
        (n, s) = size(mat)
        p = mat
        varnm = vars
        for i in 1:s
            for j in i:s
                p = hcat(p,mat[:,i].*mat[:,j])
                if vars[i] == vars[j]
                    varnm = vcat(varnm,vars[i]*"_2")
                else
                    varnm = vcat(varnm,vars[i]*"_"*vars[j])
                end
            end
        end
    end
    return p, varnm
end

它給了我我想要的,但它非常慢......有誰知道一個有效的 function 嗎? 或者如何使當前的 function 更有效率? 謝謝!

由於 DataFrames.jl 是以最佳和高效的方式編寫的,我寧願建議使用其功能的解決方法。 為此使用transform function 怎么樣:

julia> df = DataFrame(x=[1, 2], y=[3, 4])
2×2 DataFrame
 Row │ x      y     
     │ Int64  Int64 
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> function op(vecs...)
         power2 = broadcast(x->x.^2, vecs)
         return hcat(power2..., .*(vecs...))
       end

julia> transform!(df, All() => op => ["x^2", "y^2", "x*y"])
2×5 DataFrame
 Row │ x      y      x^2    y^2    x*y   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      9      3
   2 │     2      4      4     16      8

或者,使用hcat function:

julia> df = DataFrame(x=[1, 2], y=[3, 4]);

julia> df = hcat(df, df.^2, .*(eachcol(df)...), makeunique=true)
2×5 DataFrame
 Row │ x      y      x_1    y_1    x1    
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      9      3
   2 │     2      4      4     16      8

julia> rename!(df, "x_1" => "x^2", "y_1" => "y^2", "x1" => "x*y")
2×5 DataFrame
 Row │ x      y      x^2    y^2    x*y   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      9      3
   2 │     2      4      4     16      8

但是,如果您更喜歡操作並實現 arrays:

julia> mat = [1;2;;3;4]
2×2 Matrix{Int64}:
 1  3
 2  4

julia> hcat(mat, mat.^2, .*(eachcol(mat)...))
2×5 Matrix{Int64}:
 1  3  1   9  3
 2  4  4  16  8

結果是一樣的。

更新:

但我有一個問題:我嘗試使用超過兩列的數據(例如三列:x1、x2、x3),但是。*(eachcol(mat)...) 給了我 (x1.*x2.*x3 ),而不是 (x1.*x2)、(x1.*x3)、(x2.*x3)。 后者正是我想要的。

然后應該有一些調整:

julia> function op(vecs...)
         power2 = broadcast(x->x.^2, vecs)
         prods = map(
           (idx)->vecs[idx[1]] .* vecs[idx[2]],
           combinations(1:length(vecs), 2)
         )

         return hcat(power2..., prods...)
       end;

julia> df = DataFrame(x=[1, 2], y=[3, 4], z=[2, 1])
2×3 DataFrame
 Row │ x      y      z     
     │ Int64  Int64  Int64 
─────┼─────────────────────
   1 │     1      3      2
   2 │     2      4      1

julia> transform!(df, All() => op => ["x^2", "y^2", "z^2", "x*y", "x*z", "y*z"])
2×9 DataFrame
 Row │ x      y      z      x^2    y^2    z^2    x*y    x*z    y*z   
     │ Int64  Int64  Int64  Int64  Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────────────────────────────────
   1 │     1      3      2      1      9      4      3      2      6
   2 │     2      4      1      4     16      1      8      2      4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM