Microsoft Malware Prediction 2018/2019 Конкурсное решение с использованием TensorFlow, плохая точность - PullRequest
0 голосов
/ 02 апреля 2020

Как проект университета в области наук о данных, мне пришлось найти набор данных и провести некоторое машинное обучение.
Я обнаружил, что Microsoft Malware Prediction для Kaggle на 2018/2019 годы ( ссылка ), по-видимому, более Я хотел попытаться решить это с помощью TensorFlow. Цель состоит в том, чтобы попытаться определить, будет ли машина заражена вредоносным ПО или нет, с помощью данных телеметрии.

Я в основном пытаюсь решить эту проблему, используя решение участника 2-го места, но использую TF вместо Scikit-learn, как это сделал участник. Ссылка на решение предоставила участника, которого я использую: ссылка

Проблема, с которой я сталкиваюсь, заключается в том, что моя точность остается на уровне около 0,5 и что TF не улучшается после 1-я итерация Более того, потери остаются на уровне 0,6931 и после этого не улучшаются.

Описание набора данных: 8 921 483 строки, 83 столбца (последний столбец указывает, был ли заражен компьютер (= 1) или не (= 0), и я использую 1-й столбец в качестве индекса, поскольку он содержит уникальные хэши машин).

Вот мой код:

import pandas as pd
import tensorflow as tf

def categorical_conversion(df_input):
    """
    Convert to categorical instead of object
    Non categorical (non numeric, i.e. dtype = object) data need to be converted for TF 2.0 to works.
    Example : if a column has 3 possible values like Windows10, Windows7, WindowsXP, convert to 0, 1, 2
    """

    for c in df_input.columns:
        if df_input[c].dtype == "object":
            df_input[c] = pd.Categorical(df_input[c])
            df_input[c] = df_input[c].cat.codes
    return df_input


def get_compiled_model():
    model = tf.keras.Sequential([
        # l1/l2 Regularization: techniques intended to discourage complexity of a model by penalizing the loss function.
        tf.keras.layers.Dense(64, activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(0.001)),
        tf.keras.layers.Dropout(0.1),
        tf.keras.layers.Dense(32, activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(0.001)),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(16, activation='sigmoid'),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(8, activation='sigmoid'),
        tf.keras.layers.Dropout(0.5),
        tf.keras.layers.Dense(1, activation='sigmoid')
    ])

    # model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),  # change learning rate
    model.compile(optimizer='adam',
                  loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                  metrics=['accuracy'])
    return model


def neural_net():
    # creation of Neural Network
    target = df.pop('HasDetections')
    tf.keras.backend.set_floatx('float64')  # use float64 instead of 32
    dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values))  # read values from a pandas dataframe
    train_dataset = dataset.shuffle(len(df)).batch(64)  # shuffle and batch dataset
    # train the model
    model = get_compiled_model()
    model.fit(train_dataset, epochs=15, use_multiprocessing=True)


if __name__ == '__main__':
    df = pd.read_pickle("../data/pickled/train.pkl")  # same as original file, just used for faster loading
    df.set_index("MachineIdentifier", inplace=True)  # defines the unique hashes MachineIdentifier as index

    # 8921483 = size train -> 8921472 nearest integer that can be divided by 64
    df = df.iloc[:8921472, :]

    # drop cols with too much NaN
    df.drop(columns=[
        "AutoSampleOptIn", "Census_InternalBatteryNumberOfCharges", "Census_InternalBatteryType",
        "Census_IsFlightingInternal", "Census_IsFlightsDisabled", "Census_IsWIMBootEnabled", "Census_ProcessorClass",
        "Census_ThresholdOptIn", "DefaultBrowsersIdentifier", "IsBeta", "ProductName", "PuaMode", "UacLuaenable"],
        inplace=True)

    # columns with numerical values:
    numerical_features = [
        "Census_InternalPrimaryDiagonalDisplaySizeInInches", "Census_PrimaryDiskTotalCapacity",
        "Census_ProcessorCoreCount", "Census_SystemVolumeTotalCapacity", "Census_TotalPhysicalRAM"
    ]

    # columns with binary (0 or 1) values:
    binary_features = [
        "Census_HasOpticalDiskDrive", "Census_IsAlwaysOnAlwaysConnectedCapable", "Census_IsPenCapable",
        "Census_IsPortableOperatingSystem", "Census_IsSecureBootEnabled", "Census_IsTouchEnabled",
        "Census_IsVirtualDevice", "Firewall", "HasTpm", "IsProtected", "IsSxsPassiveMode", "SMode", "Wdft_IsGamer"
    ]

    # replace NaNs, very similar to the 2nd place solution
    for i in df.columns:
        s = df.loc[:, i]
        if i in numerical_features:  # set NaNs in numerical features to -1
            s.fillna(-1, inplace=True)
        elif i in binary_features:  # set NaNs in binary feature to the most frequent one
            s.fillna(s.mode().iloc[0], inplace=True)
        else:  # set to -1 if numerical, else to "unknown"
            if s.dtype == "object":
                s = s.astype(str)
                s = s.str.lower()
                s.fillna("unknown", inplace=True)
                s.replace(to_replace="nan", value="unknown", inplace=True)
                s[s.value_counts(normalize=True)[s].values < 0.05] = "unknown"  # replace low frequency values by "unknown" if string
            else:
                s.fillna(-1, inplace=True)

        df[i] = s.values
        if df[i].dtype == "int64" or df[i].dtype == "float64":  # replace rare values by -1 if numerical
            df.loc[df[i].value_counts(normalize=True)[df[i]].values < 0.05, i] = -1

    df = categorical_conversion(df)  # convert data to categorical if the column dtype is "object"

    # creation and train of NN
    neural_net()

Не могли бы вы точно указать и / или дайте мне совет, что я могу сделать, чтобы повысить точность моей модели? Я очень новый в TF.

Большое спасибо за ваше внимание и вашу помощь.

...