7.5 KiB
7.5 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 [ ]:
df = pd.read_csv(DATA_PATH, low_memory=False)
required_columns = {"source", "label"}
if not required_columns.issubset(df.columns):
raise ValueError(f"Missing required columns: {required_columns - set(df.columns)}")
feature_cols = [column for column in df.columns if column not in required_columns]
print("Dataset shape:", df.shape)
print("Number of candidate features:", len(feature_cols))
display(df.head())In [ ]:
class_counts = df["label"].value_counts().sort_index()
class_proportions = df["label"].value_counts(normalize=True).sort_index()
source_by_label = pd.crosstab(df["source"], df["label"], margins=True)
print("Class counts (0 = benign, 1 = malware):")
display(pd.DataFrame({"count": class_counts, "proportion": class_proportions}))
print("Source by label:")
display(source_by_label)In [ ]:
numeric_features = df[feature_cols].apply(pd.to_numeric, errors="coerce")
infinite_count = int(np.isinf(numeric_features.to_numpy(dtype=float)).sum())
missing_summary = numeric_features.isna().mean().sort_values(ascending=False).rename("missing_rate")
duplicate_count = int(df.duplicated().sum())
constant_features = numeric_features.nunique(dropna=True).loc[lambda values: values <= 1].index.tolist()
suspicious_tokens = ("label", "class", "target", "source", "filename", "hash", "md5", "sha")
suspicious_columns = [
column for column in feature_cols
if any(token in column.lower() for token in suspicious_tokens)
]
print("Exact duplicate rows:", duplicate_count)
print("Infinite numeric values:", infinite_count)
print("Constant candidate features:", len(constant_features))
print("Suspicious feature names:", suspicious_columns[:20])
display(missing_summary.head(10).to_frame())In [ ]:
assert {"source", "label"}.issubset(df.columns)
assert len(feature_cols) > 0
assert set(df["label"].dropna().unique()) == {0, 1}
assert set(feature_cols).isdisjoint({"source", "label"})
assert class_counts.loc[1] > class_counts.loc[0]
assert len(missing_summary) == len(feature_cols)
assert infinite_count == 0
print("✓ Lab 1 completed")In [ ]:
In [ ]: