Applied Python Analytics
Python Skills Showcase
Eight modules: metrics and charts first, notebooks on demand.
Holdout-validated demos across ML pipelines, viz, data science, big data, responsible AI, social mining, deep learning, and NLP.
Portfolio demonstrations use synthetic or public-style data.
Selected results
Outcome charts
Two representative patterns from the catalog. Synthetic data for portfolio storytelling.
Pipeline CV F1 by fold
Five-fold F1 for a mixed-type logistic pipeline; mean ≈ 0.81
Synthetic sentiment mix
Polarity buckets from lexicon triage on demo social posts.
Skill catalog
Eight skills at a glance
Skill · one-line result · metric. Essays stay collapsed; code sits behind Show snippet.
| Skill | Result | Metric | Expand |
|---|---|---|---|
| ML pipelines | Reusable sklearn Pipeline; no leakage in CV | CV F1 ~0.81 ±0.03 | |
|
Production-minded Python for ML: arrays, wrangling, numerical/categorical prep, evaluation, and model selection.
NumPypandasPipeline
ColumnTransformercross_val_score
Decision takeaway
Bundle scaling and encoding inside a Pipeline so leakage stays out of validation. Model choice is secondary to a clean, repeatable transform path. Show snippet# Skill demo — reusable sklearn pipeline (synthetic) from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score prep = ColumnTransformer([ ("num", StandardScaler(), ["temp", "humidity", "wind"]), ("cat", OneHotEncoder(handle_unknown="ignore"), ["zone"]), ]) clf = Pipeline([ ("prep", prep), ("model", LogisticRegression(max_iter=2000)), ]) scores = cross_val_score(clf, X, y, cv=5, scoring="f1") print(scores.mean().round(3), scores.std().round(3)) |
|||
| Visualization | Clear peak and outlier story for ops audiences | Static + interactive | |
|
Static and interactive viz stacks for exploration, review patterns, and stakeholder-ready charts.
matplotlibseabornplotly
multi-panelhover UX
Decision takeaway
Use seaborn for publication-clean static cuts; reserve Plotly when the audience needs hover, filter, and shared exploration. Not every chart needs interactivity. Show snippet# Skill demo — seaborn + plotly pattern (synthetic ops series) import seaborn as sns import plotly.express as px sns.set_theme(style="whitegrid") ax = sns.lineplot(data=df, x="hour", y="otif", hue="region") ax.set_title("OTIF by hour — GTA corridors") fig = px.scatter(df, x="freight_cost", y="fill_rate", color="exception", hover_data=["plant"], title="Cost vs fill — exception overlay") fig.show() |
|||
| Data science | A/B significance + holdout classifier above chance | p 0.031 · AUC ~0.74 | |
|
End-to-end data science workflow: EDA, sampling, experiments, prediction, and unsupervised reduction.
EDAsamplingt-test
glm / LRKNNPCA
Decision takeaway
Significance without effect size is incomplete; pair p-values with lift, and prefer AUC over raw accuracy when the positive class is rare. Show snippet# Skill demo — A/B conversion test + holdout classifier from scipy import stats from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score from sklearn.linear_model import LogisticRegression t_stat, p_val = stats.ttest_ind(a_conv, b_conv, equal_var=False) print("Welch p:", round(p_val, 4)) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, stratify=y, random_state=42) clf = LogisticRegression(max_iter=2000).fit(X_train, y_train) auc = roc_auc_score(y_test, clf.predict_proba(X_test)[:, 1]) print("Holdout AUC:", round(auc, 3)) |
|||
| Big data | Bronze → silver → gold KPI table at demo scale | Medallion grain | |
|
Big-data fundamentals, storage concepts, and layered analytics pipelines (bronze → silver → gold).
5 Vslakehousemedallion
Spark API shapeparquet
Decision takeaway
Scale is a design problem first: enforce keys, dedupe, and grain in silver so gold KPIs stay trustworthy when volumes grow into Spark/cluster territory. Show snippet# Skill demo — medallion layers at demo scale (pandas stand-in for Spark) import pandas as pd bronze = pd.read_csv("events_raw.csv") # append-only ingest silver = (bronze .dropna(subset=["plant_id", "event_ts"]) .assign(event_ts=lambda d: pd.to_datetime(d["event_ts"])) .drop_duplicates(["event_id"])) gold = (silver .groupby(["plant_id", silver["event_ts"].dt.floor("D")], as_index=False) .agg(shipments=("event_id", "count"), late_rate=("is_late", "mean"))) # Spark analog: spark.read.json → filter/withColumn → groupBy.agg → parquet gold.to_parquet("gold_plant_day.parquet") |
|||
| Responsible AI | Demographic parity gap flagged before go-live | Gap 0.12 vs ≤0.05 | |
|
Responsible AI practice: fairness concepts, bias audits, privacy threat modeling, and governance documentation.
demographic paritybias audit
model cardprivacygovernance
Decision takeaway
Metrics alone are not ethics. Pair gap reports with owners, thresholds, and a written mitigation path before go-live. Show snippet# Skill demo — demographic parity gap on synthetic scores import pandas as pd def selection_rate(df, group_col, group, yhat="y_hat"): g = df[df[group_col] == group] return g[yhat].mean() rates = {g: selection_rate(scored, "region", g) for g in scored["region"].unique()} gap = max(rates.values()) - min(rates.values()) print("Selection rates:", {k: round(v, 3) for k, v in rates.items()}) print("Parity gap:", round(gap, 3)) # Document threshold, protected attributes, and mitigation owner in model card |
|||
| Social mining | Theme + polarity map from posts | 4 topics · triage | |
|
Social analytics stack: collection, network structure, text mining, audience segmentation, and ethics.
TF-IDFNMF topicssentiment
network graphsengagement
Decision takeaway
Lexicon polarity is a fast triage layer; topic models explain why sentiment moved. Always validate with sampling before executive briefings. Show snippet# Skill demo — synthetic posts → TF-IDF topics + lexicon polarity from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import NMF pos = {"fast", "great", "love"}; neg = {"late", "broken", "angry"} def polarity(text): toks = set(text.lower().split()) return (len(toks & pos) - len(toks & neg)) / max(len(toks), 1) posts["score"] = posts["text"].map(polarity) vec = TfidfVectorizer(max_features=500, stop_words="english") X = vec.fit_transform(posts["text"]) nmf = NMF(n_components=4, random_state=0).fit(X) terms = vec.get_feature_names_out() for i, comp in enumerate(nmf.components_): top = terms[comp.argsort()[-5:][::-1]] print(f"Topic {i}:", ", ".join(top)) |
|||
| Deep learning | Non-linear boundary learned with tiny MLP | Holdout loss ↓ | |
|
Deep learning foundations in PyTorch: tensors, activations, training loops, embeddings, autoencoders, and RAG-oriented activities.
torchReLUbackprop
embeddingsautoencoderRAG
Decision takeaway
Start with the smallest network that fits the interaction pattern; depth without regularization is a liability. Measure holdout loss, not just training loss. Show snippet# Skill demo — tiny PyTorch MLP (XOR-style non-linearity) import torch import torch.nn as nn class MLP(nn.Module): def __init__(self): super().__init__() self.net = nn.Sequential( nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 1), ) def forward(self, x): return self.net(x).squeeze(-1) model = MLP() opt = torch.optim.Adam(model.parameters(), lr=1e-2) loss_fn = nn.BCEWithLogitsLoss() for _ in range(400): opt.zero_grad() loss = loss_fn(model(X), y) loss.backward(); opt.step() print("final loss", float(loss)) |
|||
| NLP | Intent and entity cues on short enterprise text | Macro F1 ~0.88 | |
|
NLP systems path: foundations, classical ML for text, evaluation, representation, RNNs/BiLSTM NER, seq2seq, transformers and HF pipelines.
tokenizationTF-IDFBiLSTM NER
seq2seqtransformers
Decision takeaway
Strong classical baselines still win on short enterprise text; graduate to transformers when context windows, multilingual needs, or NER span quality demand it. Show snippet# Skill demo — text → vectors → intent classifier (synthetic tickets) from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.svm import LinearSVC from sklearn.pipeline import make_pipeline from sklearn.metrics import classification_report pipe = make_pipeline( TfidfVectorizer(ngram_range=(1, 2), min_df=2), LinearSVC(), ) pipe.fit(train_text, train_label) print(classification_report(test_label, pipe.predict(test_text))) # Transformer sketch (deployment path): # from transformers import pipeline # ner = pipeline("ner", aggregation_strategy="simple") # ner("Delay at Milton DC for PO-4412") |
|||
Demo: See Smart-Shield AI for multimodal Python in production-style demos: NLP hazards, vision cues, and risk fusion.