Feature engineering modifies or combines existing attributes to create inputs that make unusual records easier to detect. A derived feature might expose a relationship hidden across columns, describe a pattern across several records, or turn a date or string into values an outlier detector can use. The aim is not simply to create more columns, but to represent distinctions that matter for the problem. section 4.8 section 17.2.7
In an outlier-detection workflow, feature engineering sits alongside cleaning, feature selection, encoding, and scaling. It can come before or after feature selection: without a target column, there is no prediction target to decide which derived features to keep, so domain judgment and subsequent evaluation matter. section 4.1 section 4.8
Choose features by asking what would make a value or relationship suspicious:
- For dates, extract day of week or month, mark the beginning of a month, or calculate days between an expense and its submission. A long or negative gap may merit inspection. Dates can also be converted to elapsed time; rank order loses substantial information. section 9.2.5 section 4.8
- For phone numbers, count characters and digits, test a common format, or extract an area code. These properties are more useful than treating the whole number as a magnitude or as a categorical value with many unique entries. section 9.2.1
- For related numeric columns, derive a ratio when one quantity provides context for another. Home runs divided by at bats can reveal players who stand apart even when the two original counts are related. section 4.8
- For activity records, count events within a preceding hour or minute for each person. A single expense may look ordinary while its frequency does not. section 4.8
- For time series, describe whole windows using their day-to-week ratios, standard deviation, fraction of increases, or fraction of local peaks. This can expose an unusual weekly shape even when individual readings are normal. section 17.2.7
Listing 9.3 Extracting features from phone numbers
def num_digits(x):
return len([c for c in x if c.isdigit()])
df = pd.DataFrame({'Phone': ['123-456-9890', '555-555-5555', '555-555']})
df['Num Characters'] = df['Phone'].str.len()
df['Num Digits'] = df['Phone'].apply(num_digits)
print(df)
The phone-number listing creates separate character and digit counts. The distinction makes a short entry visible without assigning numeric meaning to the phone number itself. section 9.2.1
Relationships between simultaneous series can be features too. When air-quality measurements usually move together, scale them to comparable values, then calculate pairwise differences. Each timestamp retains the original measurements and gains columns that a tabular outlier detector can use to find divergence. Where series move together only imperfectly, a difference still needs interpretation rather than automatic acceptance as an anomaly. section 17.2.9
Listing 17.14 Calculating pairwise differences between features
from sklearn.preprocessing import RobustScaler
df = air_quality_df[air_quality_df['year']==2017]
df = df[['PM2.5', 'PM10', 'SO2']]
scaler = RobustScaler()
df = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)
for col_idx_i in range(len(df.columns)):
col_name_i = df.columns[col_idx_i]
for col_idx_j in range(col_idx_i+1, len(df.columns)):
col_name_j = df.columns[col_idx_j]
df[f"Diff {col_name_i} vs {col_name_j}"] = \
df[col_name_i] - df[col_name_j]
The listing uses RobustScaler before subtracting each pair of air-quality measurements, making their differences usable as additional tabular columns. section 17.2.9
A further option is to use outlier scores from several detectors as features for a classifier trained on a smaller labeled set. Unlike a date component or ratio, each score describes an entire record. Its usefulness depends on whether the detectors find the kinds of outliers sought; learned combinations may still miss novel cases, so high individual scores can warrant separate checks. section 15.4















