[英]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.