Изучая ML.Net, я хочу предсказать текучесть кадров.У меня есть доступный набор данных с сочетанием числовых и строковых значений.
Это все просто исследование в моей попытке познакомиться с ML.net.Поэтому мой подход состоял в том, чтобы просто шаг за шагом изучить варианты, чтобы я действительно понимал каждый шаг как можно лучше.
- Загрузка данных
- Подготовка набора данных ивыполнить категорическое преобразование для строковых объектов
- Отображение набора данных после применения преобразований
- Затем разделить набор данных на поезд и проверить набор данных
- Обучить модель с помощью алгоритма классификации
- Оценка по тестовому набору данных
- Вывести весовые характеристики модели
- Сделать с ней несколько классных вещей
Модель выглядит следующим образоми основанный на наборе данных истощения с открытым исходным кодом от IBM.https://www.kaggle.com/pavansubhasht/ibm-hr-analytics-attrition-dataset
Модель:
public class Employee
{
[LoadColumn(0)]
public int Age { get; set; }
[LoadColumn(1)]
//[ColumnName("Label")]
public string Attrition { get; set; }
[LoadColumn(2)]
public string BusinessTravel { get; set; }
[LoadColumn(3)]
public int DailyRate { get; set; }
[LoadColumn(4)]
public string Department { get; set; }
[LoadColumn(5)]
public int DistanceFromHome { get; set; }
[LoadColumn(6)]
public int Education { get; set; }
[LoadColumn(7)]
public string EducationField { get; set; }
[LoadColumn(8)]
public int EmployeeCount { get; set; }
[LoadColumn(9)]
public int EmployeeNumber { get; set; }
[LoadColumn(10)]
public int EnvironmentSatisfaction { get; set; }
[LoadColumn(11)]
public string Gender { get; set; }
[LoadColumn(12)]
public int HourlyRate { get; set; }
[LoadColumn(13)]
public int JobInvolvement { get; set; }
[LoadColumn(14)]
public int JobLevel { get; set; }
[LoadColumn(15)]
public string JobRole { get; set; }
[LoadColumn(16)]
public int JobSatisfaction { get; set; }
[LoadColumn(17)]
public string MaritalStatus { get; set; }
[LoadColumn(18)]
public int MonthlyIncome { get; set; }
[LoadColumn(19)]
public int MonthlyRate { get; set; }
[LoadColumn(20)]
public int NumCompaniesWorked { get; set; }
[LoadColumn(21)]
public string Over18 { get; set; }
[LoadColumn(22)]
public string OverTime { get; set; }
[LoadColumn(23)]
public int PercentSalaryHike { get; set; }
[LoadColumn(24)]
public int PerformanceRating{ get; set; }
[LoadColumn(25)]
public int RelationshipSatisfaction{ get; set; }
[LoadColumn(26)]
public int StandardHours{ get; set; }
[LoadColumn(27)]
public int StockOptionLevel{ get; set; }
[LoadColumn(28)]
public int TotalWorkingYears{ get; set; }
[LoadColumn(29)]
public int TrainingTimesLastYear{ get; set; }
[LoadColumn(30)]
public int WorkLifeBalance{ get; set; }
[LoadColumn(31)]
public int YearsAtCompany{ get; set; }
[LoadColumn(32)]
public int YearsInCurrentRole{ get; set; }
[LoadColumn(33)]
public int YearsSinceLastPromotion{ get; set; }
[LoadColumn(34)]
public int YearsWithCurrManager { get; set; }
}
Свойства строк затем преобразуются (как объяснено здесь https://docs.microsoft.com/en-us/dotnet/machine-learning/how-to-guides/prepare-data-ml-net#work-with-categorical-data)
var categoricalEstimator = mlContext.Transforms.Categorical.OneHotEncoding("Attrition")
.Append(mlContext.Transforms.Categorical.OneHotEncoding("BusinessTravel"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("EducationField"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Gender"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("JobRole"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("MaritalStatus"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Over18"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("OverTime"));
ITransformer categoricalTransformer = categoricalEstimator.Fit(dataView);
IDataView transformedData = categoricalTransformer.Transform(dataView);
Теперь я хочу проверить, что имеетизменено (https://docs.microsoft.com/en-us/dotnet/machine-learning/how-to-guides/inspect-intermediate-data-ml-net#convert-idataview-to-ienumerable). Теперь у меня есть проблема в том, что после применения преобразования к свойствам строки схема изменилась и теперь содержит ожидаемые векторы.
Таким образом, происходит следующее. Модель Employeeсхема больше не соответствует схеме из объекта transformedData и пытается вписать свойство Vector в свойство String и выдает следующую ошибку "Невозможно привязать столбец IDataView 'Attrition' типа 'Vector' к полю или свойству'Attrition' типа 'System.String'. "
IEnumerable<Employee> employeeDataEnumerable =
mlContext.Data.CreateEnumerable<Employee>(transformedData, reuseRowObject: true);
CreateEnumerable также имеет аргумент SchemaDefinition, поэтому мое первое предположение состояло в том, чтобы извлечь схему из transformData и передать ее вCreateEnumerable. Однако он ожидает Microsoft.ML.DataViewSchema, а схема, созданная преобразованием, является Microsoft.ML.Da.ta.SchemaDefinition.Так что это тоже не сработало.
Я надеюсь, что кто-то может посоветовать мне это.Должен ли я сделать что-то другое?
Действие полного контроллера:
public ActionResult Turnover()
{
MLContext mlContext = new MLContext();
var _appPath = AppDomain.CurrentDomain.BaseDirectory;
var _dataPath = Path.Combine(_appPath, "Datasets", "WA_Fn-UseC_-HR-Employee-Attrition.csv");
// Load data from file
IDataView dataView = mlContext.Data.LoadFromTextFile<Employee>(_dataPath, hasHeader: true);
// 0. Get the column name of input features.
string[] featureColumnNames =
dataView.Schema
.Select(column => column.Name)
.Where(columnName => columnName != "Label")
.ToArray();
// Define categorical transform estimator
var categoricalEstimator = mlContext.Transforms.Categorical.OneHotEncoding("Attrition")
.Append(mlContext.Transforms.Categorical.OneHotEncoding("BusinessTravel"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("EducationField"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Gender"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("JobRole"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("MaritalStatus"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("Over18"))
.Append(mlContext.Transforms.Categorical.OneHotEncoding("OverTime"));
ITransformer categoricalTransformer = categoricalEstimator.Fit(dataView);
IDataView transformedData = categoricalTransformer.Transform(dataView);
// Inspect (fails because Employee (35 cols) cannot be mapped to new schema (52 cols)
IEnumerable<Employee> employeeDataEnumerable =
mlContext.Data.CreateEnumerable<Employee>(transformedData, reuseRowObject: true, schemaDefinition : transformedData.Schema);
// split the transformed dataset into training and a testing datasets
DataOperationsCatalog.TrainTestData dataSplit = mlContext.Data.TrainTestSplit(transformedData, testFraction: 0.2);
IDataView trainData = dataSplit.TrainSet;
IDataView testData = dataSplit.TestSet;
return View();
}