Esta entrada tiene como objetivo documentar la solución del proyecto final del Bootcamp de Data Science y Python. Este proyecto está basado en una competición de Kaggle organizada por Microsoft en 2019 en la que se repartieron hasta 20000$ en premios. El objetivo de esta competición es predecir si una máquina va a sufrir malware o no a partir de 2 datasets, uno de entrenamiento, con label, de 892148 registros y otro de test, sin label, de 321173 registros.
En este proyecto se valora incluso más que los resultados la forma de llegar a ellos, es decir, el código debe ejecutar todas las transformaciones de forma automatizada y debe estar preparado para solventar futuribles problemas como, por ejemplo, cambios en los nombres de los campos, nuevas columnas añadidas, nuevos tipos de datos…
El objetivo de esta competición es predecir la probabilidad de que una máquina Windows se infecte por varias familias de malware, basándose en diferentes propiedades de esa máquina. Los datos telemétricos que contienen estas propiedades y las infecciones de las máquinas se generaron combinando informes de latidos e informes de amenazas recopilados por el programa de seguridad antivirus Windows Defender.
Cada fila de este conjunto de datos corresponde a una máquina, identificada por un MachineIdentifier. HasDetections es el label que indica si se ha detectado malware en la máquina. Utilizando la información y las etiquetas de train.csv, debe predecir el valor de HasDetections para cada máquina de test.csv.
La metodología de muestreo utilizada para crear este conjunto de datos fue diseñada para cumplir con ciertas restricciones de negocio, tanto en lo que respecta a la privacidad del usuario, así como el período de tiempo durante el cual la máquina estaba funcionando. La detección de malware es inherentemente un problema de series temporales, pero se complica con la introducción de nuevas máquinas, máquinas que se conectan y desconectan, máquinas que reciben parches, máquinas que reciben nuevos sistemas operativos, etc. Aunque el conjunto de datos proporcionado aquí se ha dividido aproximadamente en el tiempo, las complicaciones y los requisitos de muestreo mencionados anteriormente pueden significar que se observe una concordancia imperfecta entre las puntuaciones de validación cruzada, públicas y privadas.
Unavailable or self-documenting column names are marked with an «NA».
MachineIdentifier: Individual machine ID
ProductName: Defender state information e.g. win8defender
EngineVersion: Defender state information e.g. 1.1.12603.0
AppVersion: Defender state information e.g. 4.9.10586.0
AvSigVersion: Defender state information e.g. 1.217.1014.0
IsBeta: Defender state information e.g. false
RtpStateBitfield: NA
IsSxsPassiveMode: NA
DefaultBrowsersIdentifier: ID for the machine’s default browser
AVProductStatesIdentifier: ID for the specific configuration of a user’s antivirus software
AVProductsInstalled: NA
AVProductsEnabled: NA
HasTpm: True if machine has TPM
CountryIdentifier: ID for the country the machine is located in
CityIdentifier: ID for the city the machine is located in
OrganizationIdentifier: ID for the organization the machine belongs in, organization ID is mapped to both specific companies and broad industries
GeoNameIdentifier: ID for the geographic region a machine is located in
LocaleEnglishNameIdentifier: English name of Locale ID of the current user
Platform: Calculates platform name (of OS related properties and processor property)
Processor: This is the process architecture of the installed operating system
OsVer: Version of the current operating system
OsBuild: Build of the current operating system
OsSuite: Product suite mask for the current operating system.
OsPlatformSubRelease: Returns the OS Platform sub-release (Windows Vista, Windows 7, Windows 8, TH1, TH2)
OsBuildLab: Build lab that generated the current OS. Example: 9600.17630.amd64fre.winblue_r7.150109-2022
SkuEdition: The goal of this feature is to use the Product Type defined in the MSDN to map to a ‘SKU-Edition’ name that is useful in population reporting. The valid Product Type are defined in %sdxroot%\data\windowseditions.xml. This API has been used since Vista and Server 2008, so there are many Product Types that do not apply to Windows 10. The ‘SKU-Edition’ is a string value that is in one of three classes of results. The design must hand each class.
IsProtected: This is a calculated field derived from the Spynet Report’s AV Products field. Returns: a. TRUE if there is at least one active and up-to-date antivirus product running on this machine. b. FALSE if there is no active AV product on this machine, or if the AV is active, but is not receiving the latest updates. c. null if there are no Anti Virus Products in the report. Returns: Whether a machine is protected.
AutoSampleOptIn: This is the SubmitSamplesConsent value passed in from the service, available on CAMP 9+
PuaMode: Pua Enabled mode from the service
SMode: This field is set to true when the device is known to be in ‘S Mode’, as in, Windows 10 S mode, where only Microsoft Store apps can be installed
IeVerIdentifier: NA
SmartScreen: This is the SmartScreen enabled string value from the registry. This is obtained by checking in order, HKLM\SOFTWARE\Policies\Microsoft\Windows\System\SmartScreenEnabled and HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SmartScreenEnabled. If the value exists but is blank, the value «ExistsNotSet» is sent in telemetry.
Firewall: This attribute is true (1) for Windows 8.1 and above if the Windows firewall is enabled, as reported by the service.
UacLuaenable: This attribute reports whether or not the «administrator in Admin Approval Mode» user type is disabled or enabled in UAC. The value reported is obtained by reading the regkey HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA.
Census_MDC2FormFactor: A grouping based on a combination of Device Census level hardware characteristics. The logic used to define Form Factor is rooted in business and industry standards and aligns with how people think about their devices. (Examples: Smartphone, Small Tablet, All in One, Convertible…)
Census_DeviceFamily: AKA DeviceClass. Indicates the type of device that an edition of the OS is intended for. Example values: Windows.Desktop, Windows.Mobile, and iOS.Phone
Census_OEMNameIdentifier: NA
Census_OEMModelIdentifier: NA
Census_ProcessorCoreCount: Number of logical cores in the processor
Census_ProcessorManufacturerIdentifier: NA
Census_ProcessorModelIdentifier: NA
Census_ProcessorClass: A classification of processors into high/medium/low. Initially used for Pricing Level SKU. No longer maintained and updated
Census_PrimaryDiskTotalCapacity: Amount of disk space on the primary disk of the machine in MB
Census_PrimaryDiskTypeName: Friendly name of Primary Disk Type – HDD or SSD
Census_SystemVolumeTotalCapacity: The size of the partition that the System volume is installed on in MB
Census_HasOpticalDiskDrive: True indicates that the machine has an optical disk drive (CD/DVD)
Census_TotalPhysicalRAM: Retrieves the physical RAM in MB
Census_ChassisTypeName: Retrieves a numeric representation of what type of chassis the machine has. A value of 0 means xx
Census_InternalPrimaryDiagonalDisplaySizeInInches: Retrieves the physical diagonal length in inches of the primary display
Census_InternalPrimaryDisplayResolutionHorizontal: Retrieves the number of pixels in the horizontal direction of the internal display.
Census_InternalPrimaryDisplayResolutionVertical: Retrieves the number of pixels in the vertical direction of the internal display
Census_PowerPlatformRoleName: Indicates the OEM preferred power management profile. This value helps identify the basic form factor of the device
Census_InternalBatteryType: NA
Census_InternalBatteryNumberOfCharges: NA -Census_OSVersion – Numeric OS version Example- 10.0.10130.0
Census_OSArchitecture: Architecture on which the OS is based. Derived from OSVersionFull. Example – amd64
Census_OSBranch: Branch of the OS extracted from the OsVersionFull. Example- OsBranch = fbl_partner_eeap where OsVersion = 6.4.9813.0.amd64fre.fbl_partner_eeap.140810-0005
Census_OSBuildNumber: OS Build number extracted from the OsVersionFull. Example – OsBuildNumber = 10512 or 10240
Census_OSBuildRevision: OS Build revision extracted from the OsVersionFull. Example- OsBuildRevision = 1000 or 16458
Census_OSEdition: Edition of the current OS. Sourced from HKLM\Software\Microsoft\Windows NT\CurrentVersion@EditionID in the registry. Example: Enterprise
Census_OSSkuName: OS edition friendly name (currently Windows only)
Census_OSInstallTypeName: Friendly description of what install was used on the machine i.e. clean
Census_OSInstallLanguageIdentifier: NA
Census_OSUILocaleIdentifier: NA
Census_OSWUAutoUpdateOptionsName: Friendly name of the WindowsUpdate auto-update settings on the machine.
Census_IsPortableOperatingSystem: Indicates whether the OS is booted up and running via Windows-To-Go on a USB stick.
Census_GenuineStateName: Friendly name of OSGenuineStateID. 0 = Genuine
Census_ActivationChannel: Retail license key or Volume license key for a machine.
Census_IsFlightingInternal: NA
Census_IsFlightsDisabled: Indicates if the machine is participating in flighting.
Census_FlightRing: The ring that the device user would like to receive flights for. This might be different from the ring of the OS, which is currently installed if the user changes the ring after getting a flight from a different ring.
Census_ThresholdOptIn: NA
Census_FirmwareManufacturerIdentifier: NA
Census_FirmwareVersionIdentifier: NA
Census_IsSecureBootEnabled: Indicates if Secure Boot mode is enabled.
Census_IsWIMBootEnabled: NA
Census_IsVirtualDevice: Identifies a Virtual Machine (machine learning model)
Census_IsTouchEnabled: Is this a touch device?
Census_IsPenCapable: Is the device capable of pen input?
Census_IsAlwaysOnAlwaysConnectedCapable: Retrieves information about whether the battery enables the device to be AlwaysOnAlwaysConnected.
Wdft_IsGamer: Indicates whether the device is a gamer device or not based on its hardware combination.
Wdft_RegionIdentifier: NA
Teniendo claro ya cuál es el problema que debemos resolver y cómo son los datos con los que vamos a trabajar, podemos empezar a profundizar en la solución.
Este proyecto está dividido en 3 cuadernos .ipynb:
Notebook de pruebas: Es el cuaderno de desarrollo, en él se prueban las nuevas transformaciones que queremos aplicar al modelo, se comprueban las métricas y se realiza el ajuste de hiperparámetros y la selección del modelo.
Notebook de entrenamiento: Es uno de los 2 cuadernos de puesta en producción, en este cuaderno no se comprueban los resultados, su única función es entrenar el modelo con los nuevos datos que vayan llegando y guardar todas las transformaciones aplicadas para implementarlas en el cuaderno de inferencia.
Notebook de inferencia: Es el otro cuaderno de puesta en producción, su función es predecir resultados. Lee los datos de entrada en un Dataframe de pandas, le aplica las transformaciones pertinentes y devuelve las predicciones.
A continuación adjuntaré cada uno de los 3 notebooks con todas las celdas de código documentadas en el propio notebook y con algunos de los outputs relevantes.
Selección de variables
Variables máscara
Elimino variables que no aportan valor
Variables booleanas
De numéricas a categóricas
Variables 'object' como categóricas
Train/Test split
Elimino variables con demasiados nulos (+80%)
Correlación entre variables
Creo una lista con las variables categóricas y otra con las numéricas
Pinto la matriz de correlación inicial
Independientemente de que haya más de 1 variable demasiado correlacionada, sólamente elimino 1 y vuelvo a calcular la correlación.
Imputación de nulos
Imputación de outliers
Codificación de variables
Variables numéricas
Variables categóricas
Target Encoding:
One Hot Encoding:
LightGBM
Búsqueda de hiperparámetros
Definición y entrenamiento del modelo
Importancia de variables
XGBoost
Definición y entrenamiento del modelo
Importancia de variables
Comparación de modelos
Métricas
Matriz de confusión
Curva ROC
Selección de variables
Variables máscara
Elimino variables que no aportan valor
Variables booleanas
Falsas columnas numéricas
Variables 'object' como categóricas
Separo la variable objetivo (label) del resto de variables
Elimino variables con demasiados nulos (+80%)
Correlación entre variables
Creo una lista con las variables categóricas y otra con las numéricas
Independientemente de que haya más de 1 variable demasiado correlacionada, sólamente elimino 1 y vuelvo a calcular la correlación.
Imputación de nulos
Imputación de outliers
Codificación de variables
Variables numéricas
Variables categóricas
Target Encoding:
One Hot Encoding:
Guardo los objetos usados en el entrenamiento para aplicarlos en inferencia
Selección de variables
Imputación de nulos
Imputación de outliers
Codificación de variables
results.csv es el archivo que se sube a Kaggle para la validación de los resultados
Independientemente de los resultados de Kaggle, que incluso mejoraban aplicando muchas menos transformaciones que, en teoría, deberían mejorar el modelo, y que, como se mencionó al inicio, no eran el enfoque principal del proyecto, estoy muy satisfecho con la solución propuesta que incluye los 3 cuadernos con transformaciones automatizadas y realizadas en base a una serie de parámetros ajustados manualmente.
Este proyecto me ha permitido poner en práctica gran parte de los conocimientos adquiridos en el Bootcamp de Data Science y Python, especialmente en el ámbito de los algoritmos tradicionales de Machine Learning.
Además, me ha brindado la oportunidad de reforzar mis habilidades en pandas y de llevar a cabo mi primer análisis exploratorio de datos desconocidos desde cero.