DataFrames
В качестве обучающего набора можно использовать dataframe, но сначала его нужно преобразовать в массив. Для указания способа преобразования используется DataFrameMapper
. Например, PCA можно применить к некоторым числовым столбцам dataframe, а кодирование с одним активным состоянием — к категориальным столбцам.
Сопоставление преобразования
Рассмотрим следующий набор данных.
julia> using ScikitLearn
julia> using DataFrames: DataFrame, missing
julia> @sk_import preprocessing: (LabelBinarizer, StandardScaler)
PyObject <class 'sklearn.preprocessing._data.StandardScaler'>
julia> data = DataFrame(pet=["cat", "dog", "dog", "fish", "cat", "dog", "cat", "fish"],
children=[4., 6, 3, 3, 2, 3, 5, 4],
salary=[90, 24, 44, 27, 32, 59, 36, 27])
8×3 DataFrame
│ Row │ pet │ children │ salary │
│ │ String │ Float64 │ Int64 │
├─────┼────────┼──────────┼────────┤
│ 1 │ cat │ 4.0 │ 90 │
│ 2 │ dog │ 6.0 │ 24 │
│ 3 │ dog │ 3.0 │ 44 │
│ 4 │ fish │ 3.0 │ 27 │
│ 5 │ cat │ 2.0 │ 32 │
│ 6 │ dog │ 3.0 │ 59 │
│ 7 │ cat │ 5.0 │ 36 │
│ 8 │ fish │ 4.0 │ 27 │
Сопоставление столбцов с преобразованиями
Модуль сопоставления содержит список пар. Первый элемент — это имя столбца из DataFrame или список, содержащий один или несколько столбцов (пример с несколькими столбцами мы рассмотрим позже). Второй — это объект, выполняющий преобразование, которое будет применено к этому столбцу:
Примечание. ScikitLearn.DataFrameMapper
будет доступен только после импорта DataFrames
.
julia> mapper = DataFrameMapper([(:pet, LabelBinarizer()),
([:children], StandardScaler())]);
Разница между указанием селектора столбцов как :column
(в виде одного символа) и [:column]
(в виде списка с одним элементом) заключается в форме массива, который передается преобразователю. В первом случае будет передан одномерный массив, а во втором — двумерный массив с одним столбцом, т. е. вектор-столбец.
Тестирование преобразования
Можно использовать сокращение fit_transform!
, чтобы и подогнать модель, и посмотреть, как выглядят преобразованные данные. В этом и других примерах вывод округляется до двух цифр с помощью round
, чтобы учесть погрешности округления на различном оборудовании:
julia> round.(fit_transform!(mapper, copy(data)), digits=2)
8×4 Array{Float64,2}:
1.0 0.0 0.0 0.21
0.0 1.0 0.0 1.88
0.0 1.0 0.0 -0.63
0.0 0.0 1.0 -0.63
1.0 0.0 0.0 -1.46
0.0 1.0 0.0 -0.63
1.0 0.0 0.0 1.04
0.0 0.0 1.0 0.21
Обратите внимание, что первые три столбца — это результаты выполнения LabelBinarizer (соответствующие cat
, dog
и fish
соответственно), а четвертый столбец — это стандартизированное значение количества детей. В общем случае столбцы упорядочиваются согласно порядку, заданному при создании DataFrameMapper.
Теперь, когда преобразование обучено, мы проверяем, что оно работает с новыми данными:
julia> sample = DataFrame(pet = ["cat"], children = [5.])
1×2 DataFrame
│ Row │ pet │ children │
│ │ String │ Float64 │
├─────┼────────┼──────────┤
│ 1 │ cat │ 5.0 │
julia> round.(transform(mapper, sample), digits=2)
1×4 Array{Float64,2}:
1.0 0.0 0.0 1.04
Преобразование нескольких столбцов
Для преобразований может потребоваться несколько столбцов. В этих случаях имена столбцов можно указать в виде списка:
julia> @sk_import decomposition: PCA
PyObject <class 'sklearn.decomposition._pca.PCA'>
julia> mapper2 = DataFrameMapper([([:children, :salary], PCA(1))]);
Теперь выполнение fit_transform!
запустит PCA для столбцов children
и salary
и возвратит первый главный компонент:
julia> round.(fit_transform!(mapper2, copy(data)), digits=1)
8×1 Array{Float64,2}:
47.6
-18.4
1.6
-15.4
-10.4
16.6
-6.4
-15.4
Несколько преобразователей для того же столбца
К одному и тому же столбцу можно применить несколько преобразователей, указав их в списке:
julia> @sk_import impute: SimpleImputer
PyObject <class 'sklearn.impute._base.SimpleImputer'>
julia> mapper3 = DataFrameMapper([([:age], [SimpleImputer(),
StandardScaler()])]; missing2NaN=true);
julia> data_3 = DataFrame(age= [1, missing, 3]);
julia> fit_transform!(mapper3, data_3)
3×1 Array{Float64,2}:
-1.224744871391589
0.0
1.224744871391589
Столбцы, которым не требуется преобразование
Сохраняются только столбцы, перечисленные в DataFrameMapper
. Чтобы сохранить столбец, но не применять к нему никаких преобразований, используйте nothing
в качестве преобразователя:
julia> mapper3 = DataFrameMapper([(:pet, LabelBinarizer()), (:children, nothing)]);
julia> round.(fit_transform!(mapper3, copy(data)))
8×4 Array{Float64,2}:
1.0 0.0 0.0 4.0
0.0 1.0 0.0 6.0
0.0 1.0 0.0 3.0
0.0 0.0 1.0 3.0
1.0 0.0 0.0 2.0
0.0 1.0 0.0 3.0
1.0 0.0 0.0 5.0
0.0 0.0 1.0 4.0
Перекрестная проверка
Теперь, когда мы можем объединить признаки из DataFrame, можно использовать перекрестную проверку, чтобы проверить, работает ли модель.
julia> @sk_import linear_model: LinearRegression
PyObject <class 'sklearn.linear_model._base.LinearRegression'>
julia> using ScikitLearn.CrossValidation: cross_val_score
julia> pipe = Pipelines.Pipeline([(:featurize, mapper), (:lm, LinearRegression())]);
julia> round.(cross_val_score(pipe, data, data[!,:salary]), digits=2)
3-element Array{Float64,1}:
-1.09
-5.3
-15.38