Treinar e avaliar um modelo
Saiba como criar modelos de machine learning, coletar métricas e medir o desempenho com ML.NET. Embora este exemplo treine um modelo de regressão, os conceitos são aplicáveis na maioria dos outros algoritmos.
Dividir dados para treinamento e teste
A meta de um modelo de machine learning é identificar padrões dentro de dados de treinamento. Esses padrões são usados para fazer previsões usando novos dados.
Os dados podem ser modelados por uma classe como HousingData
.
public class HousingData
{
[LoadColumn(0)]
public float Size { get; set; }
[LoadColumn(1, 3)]
[VectorType(3)]
public float[] HistoricalPrices { get; set; }
[LoadColumn(4)]
[ColumnName("Label")]
public float CurrentPrice { get; set; }
}
Considerando os dados a seguir, que são carregados em uma IDataView
.
HousingData[] housingData = new HousingData[]
{
new HousingData
{
Size = 600f,
HistoricalPrices = new float[] { 100000f ,125000f ,122000f },
CurrentPrice = 170000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 200000f, 250000f, 230000f },
CurrentPrice = 225000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 126000f, 130000f, 200000f },
CurrentPrice = 195000f
},
new HousingData
{
Size = 850f,
HistoricalPrices = new float[] { 150000f,175000f,210000f },
CurrentPrice = 205000f
},
new HousingData
{
Size = 900f,
HistoricalPrices = new float[] { 155000f, 190000f, 220000f },
CurrentPrice = 210000f
},
new HousingData
{
Size = 550f,
HistoricalPrices = new float[] { 99000f, 98000f, 130000f },
CurrentPrice = 180000f
}
};
Use o método TrainTestSplit
para dividir os dados em conjuntos de treinamento e teste. O resultado será um objeto TrainTestData
que contém dois membros IDataView
, um para o conjunto de treinamento e outro para o conjunto de teste. A porcentagem de divisão de dados é determinada pelo parâmetro testFraction
. O snippet a seguir contém 20% dos dados originais do conjunto de testes.
DataOperationsCatalog.TrainTestData dataSplit = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
IDataView trainData = dataSplit.TrainSet;
IDataView testData = dataSplit.TestSet;
Preparar os dados
Os dados precisam ser pré-processados antes de treinar um modelo de machine learning. Mais informações sobre a preparação de dados podem ser encontradas no artigo sobre como preparar dados e no transforms page
.
Os algoritmos do ML.NET têm restrições quanto aos tipos de coluna de entrada. Além disso, os valores padrão são usados para nomes de coluna de entrada e saída quando nenhum valor é especificado.
Trabalhando com tipos de coluna esperados
Os algoritmos de aprendizado de máquina em ML.NET esperam um vetor flutuante de tamanho conhecido como entrada. Aplique o atributo VectorType
ao modelo de dados quando todos os dados já estiverem em formato numérico e forem processados juntos (ou seja, pixels de imagem).
Se os dados não forem todos numéricos e você quiser aplicar diferentes transformações de dados em cada uma das colunas individualmente, use o método Concatenate
depois que todas as colunas tiverem sido processadas para combinar todas as colunas individuais em um único vetor de recurso que é saída para uma nova coluna.
O snippet a seguir combina as colunas Size
e HistoricalPrices
em um único vetor de características que é direcionado para uma nova coluna chamada Features
. Como há uma diferença nas escalas, NormalizeMinMax
é aplicado à coluna Features
para normalizar os dados.
// Define Data Prep Estimator
// 1. Concatenate Size and Historical into a single feature vector output to a new column called Features
// 2. Normalize Features vector
IEstimator<ITransformer> dataPrepEstimator =
mlContext.Transforms.Concatenate("Features", "Size", "HistoricalPrices")
.Append(mlContext.Transforms.NormalizeMinMax("Features"));
// Create data prep transformer
ITransformer dataPrepTransformer = dataPrepEstimator.Fit(trainData);
// Apply transforms to training data
IDataView transformedTrainingData = dataPrepTransformer.Transform(trainData);
Trabalhando com nomes de coluna padrão
ML.NET algoritmos usam nomes de coluna padrão quando nenhum é especificado. Todos os treinadores têm um parâmetro chamado featureColumnName
para as entradas do algoritmo e, quando aplicável, eles também têm um parâmetro para o valor esperado chamado labelColumnName
. Por padrão, esses valores são Features
e Label
respectivamente.
Usando o método Concatenate
durante o pré-processamento para criar uma nova coluna chamada Features
, não é necessário especificar o nome da coluna de recurso nos parâmetros do algoritmo, pois ele já existe no IDataView
pré-processado. A coluna de rótulo é CurrentPrice
, mas como o atributo ColumnName
é usado no modelo de dados, ML.NET renomeia a coluna CurrentPrice
para Label
o que remove a necessidade de fornecer o parâmetro labelColumnName
para o avaliador de algoritmo de aprendizado de máquina.
Se você não quiser usar os nomes de coluna padrão, passe os nomes das colunas de rótulo e de recurso como parâmetros ao definir o estimador do algoritmo de aprendizado de máquina como demonstrado pelo snippet subsequente:
var UserDefinedColumnSdcaEstimator = mlContext.Regression.Trainers.Sdca(labelColumnName: "MyLabelColumnName", featureColumnName: "MyFeatureColumnName");
Dados de cache
Por padrão, quando os dados são processados, eles são carregados ou transmitidos lentamente, o que significa que os treinadores podem carregar os dados do disco e iterá-los várias vezes durante o treinamento. Portanto, o armazenamento em cache é recomendado para conjuntos de dados que cabem na memória, a fim de reduzir o número de vezes que os dados são carregados do disco. O cache é feito como parte de um EstimatorChain
usando AppendCacheCheckpoint
.
É recomendável usar AppendCacheCheckpoint
antes de qualquer treinador no pipeline.
Usando o seguinte EstimatorChain
, adicionando AppendCacheCheckpoint
antes que o StochasticDualCoordinateAscent
treinador armazene em cache os resultados dos estimadores anteriores para uso posterior pelo treinador.
// 1. Concatenate Size and Historical into a single feature vector output to a new column called Features
// 2. Normalize Features vector
// 3. Cache prepared data
// 4. Use Sdca trainer to train the model
IEstimator<ITransformer> dataPrepEstimator =
mlContext.Transforms.Concatenate("Features", "Size", "HistoricalPrices")
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.AppendCacheCheckpoint(mlContext);
.Append(mlContext.Regression.Trainers.Sdca());
Treinar o modelo de machine learning
Depois que os dados forem pré-processados, use o método Fit
para treinar o modelo de machine learning com o algoritmo de regressão StochasticDualCoordinateAscent
.
// Define StochasticDualCoordinateAscent regression algorithm estimator
var sdcaEstimator = mlContext.Regression.Trainers.Sdca();
// Build machine learning model
var trainedModel = sdcaEstimator.Fit(transformedTrainingData);
Extrair parâmetros de modelo
Após o modelo ter sido treinado, extraia o aprendido ModelParameters
para inspeção ou retreinamento. O LinearRegressionModelParameters
fornece os desvios e os coeficientes aprendidos ou os pesos do modelo treinado.
var trainedModelParameters = trainedModel.Model as LinearRegressionModelParameters;
Nota
Outros modelos têm parâmetros específicos para suas tarefas. Por exemplo, o algoritmo K-Means coloca dados em cluster com base em centroides e o KMeansModelParameters
contém uma propriedade que armazena esses centroides aprendidos. Para saber mais, visite a documentação da API Microsoft.ML.Trainers
e procure classes que contêm ModelParameters
em seu nome.
Avaliar a qualidade do modelo
Para ajudar a escolher o modelo de melhor desempenho, é essencial avaliar seu desempenho em dados de teste. Use o método Evaluate
para medir várias métricas para o modelo treinado.
Nota
O método Evaluate
produz métricas diferentes dependendo de qual tarefa de machine learning foi executada. Para obter mais detalhes, visite a documentação da API Microsoft.ML.Data
e procure classes que contêm Metrics
em seu nome.
// Measure trained model performance
// Apply data prep transformer to test data
IDataView transformedTestData = dataPrepTransformer.Transform(testData);
// Use trained model to make inferences on test data
IDataView testDataPredictions = trainedModel.Transform(transformedTestData);
// Extract model metrics and get RSquared
RegressionMetrics trainedModelMetrics = mlContext.Regression.Evaluate(testDataPredictions);
double rSquared = trainedModelMetrics.RSquared;
No exemplo de código anterior:
- O conjunto de dados de teste é pré-processado usando as transformações de preparação de dados definidas anteriormente.
- O modelo de machine learning treinado é usado para fazer previsões nos dados de teste.
- No método
Evaluate
, os valores na colunaCurrentPrice
do conjunto de dados de teste são comparados com a colunaScore
das previsões recém-geradas para calcular as métricas do modelo de regressão, sendo uma delas, o R-Squared, que é armazenado na variávelrSquared
.
Nota
Neste pequeno exemplo, o R-Squared é um número que não está no intervalo de 0 a 1 devido ao tamanho limitado dos dados. Em um cenário real, você deve esperar ver um valor entre 0 e 1.