6.3 KiB
6.3 KiB
In [ ]:
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
DATA_PATH = Path("data/malware_features.csv")
if not DATA_PATH.exists():
raise FileNotFoundError(
"Missing data/malware_features.csv. Follow data/README.md, place the three "
"official UCI CSV files under data/raw/, and run: python data/prepare_dataset.py"
)In [ ]:
# TODO 1: load the prepared dataset and define X, y, and feature_cols.
df = None
feature_cols = None
X = None
y = None
print("Rows:", None, "Features:", None)In [ ]:
family_tokens = {
"pe_or_header": ("header", "section", "image", "size", "character", "linker", "dll", "entry"),
"api_or_import": ("api", "import", "call", "function"),
"byte_or_opcode": ("byte", "opcode", "asm", "hex"),
"dynamic_behavior": ("registry", "network", "process", "file", "mutex", "service"),
}
# TODO 2: collect up to ten feature-name examples for each family.
family_examples = None
family_examplesIn [ ]:
benign = X.loc[y == 0]
malware = X.loc[y == 1]
# TODO 3: calculate the IQR for every feature and replace zero IQR values with NaN.
iqr = None
# TODO 4: build feature_profile with missing rate, unique count, and class medians.
feature_profile = None
# TODO 5: calculate the absolute median gap divided by IQR, then select the top eight names.
top_features = None
display(feature_profile.loc[top_features])In [ ]:
# TODO 6: create a horizontal grouped bar chart of benign and malware medians.
median_plot = None
ax = None
plt.tight_layout()
plt.show()In [ ]:
assert set(X.columns) == set(feature_cols)
assert set(y.unique()) == {0, 1}
assert len(feature_profile) == len(feature_cols)
assert len(top_features) == 8
assert set(top_features).issubset(feature_cols)
assert {"benign_median", "malware_median", "standardized_median_gap"}.issubset(feature_profile.columns)
print("✓ Lab 2 completed")