Machine Learning 已经成为澳洲、英国、美国、加拿大顶尖大学 CS 和数据科学专业最热门的课程方向之一。MIT 6.036、UNSW COMP9417、UofT CSC311、Imperial 70015 等 ML 课程每学期都有大量留学生需要辅导支持。
ML Assignment 的挑战不只是"写代码",而是理解算法原理 + 正确实现 + 准确解读结果 + 写好 Report。本文系统覆盖这四个层次。
ML Assignment 的典型结构
大多数 ML Assignment 包含以下部分:
- 数据预处理(Data Preprocessing)
- 算法实现或调用(Implementation / sklearn)
- 模型评估(Evaluation Metrics)
- 超参数调优(Hyperparameter Tuning)
- 结果分析 Report(Analysis & Discussion)
每一部分都有评分,其中 Report 占比通常 30–50%——很多学生代码写对了,但 Report 写得不到位,还是丢了很多分。
第一部分:数据预处理
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
# 读取数据
df = pd.read_csv('data.csv')
# 1. 查看数据基本信息
print(df.info())
print(df.describe())
print(df.isnull().sum()) # 检查缺失值
# 2. 处理缺失值
df['col'].fillna(df['col'].mean(), inplace=True) # 均值填充(数值型)
df['col'].fillna(df['col'].mode()[0], inplace=True) # 众数填充(类别型)
df.dropna(inplace=True) # 或直接删除含缺失值的行
# 3. 特征编码(类别变量→数值)
le = LabelEncoder()
df['category'] = le.fit_transform(df['category'])
# 或用 One-Hot Encoding(避免序数关系)
df = pd.get_dummies(df, columns=['category'], drop_first=True)
# 4. 特征标准化(对距离敏感的算法必须做)
X = df.drop('target', axis=1).values
y = df['target'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) # 在训练集上 fit
X_test = scaler.transform(X_test) # 在测试集上只 transform!
最常见错误:用整个数据集 fit scaler(Data Leakage),应该只在训练集上 fit。
第二部分:核心算法实现
2.1 线性回归(Linear Regression)
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# 评估
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"RMSE: {rmse:.4f}")
print(f"R² Score: {r2:.4f}")
print(f"Coefficients: {model.coef_}")
print(f"Intercept: {model.intercept_:.4f}")
Report 里要解释:
- R² 代表什么(模型解释了多少方差)
- 哪些特征系数最大(最重要的预测变量)
- RMSE 在业务意义上是多少(如果预测房价,RMSE=5000澳元意味着什么)
2.2 逻辑回归(Logistic Regression)
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
model = LogisticRegression(max_iter=1000, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1] # 正类概率
print(classification_report(y_test, y_pred))
print("ROC-AUC:", roc_auc_score(y_test, y_prob))
混淆矩阵(Confusion Matrix)解读:
| 预测正 | 预测负 | |
|---|---|---|
| 实际正 | TP(真正例) | FN(假负例) |
| 实际负 | FP(假正例) | TN(真负例) |
$$Accuracy = \frac{TP + TN}{TP + FP + TN + FN}$$ $$Precision = \frac{TP}{TP + FP}$$ $$Recall = \frac{TP}{TP + FN}$$ $$F1 = \frac{2 \times Precision \times Recall}{Precision + Recall}$$
Report 里必须回答:在你的任务中,Precision 和 Recall 哪个更重要?(医疗诊断→Recall 更重要;垃圾邮件过滤→Precision 更重要)
2.3 决策树(Decision Tree)
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.metrics import accuracy_score
# 不带限制(容易过拟合)
dt = DecisionTreeClassifier(random_state=42)
dt.fit(X_train, y_train)
# 带限制(防止过拟合)
dt_pruned = DecisionTreeClassifier(max_depth=5, min_samples_leaf=10, random_state=42)
dt_pruned.fit(X_train, y_train)
# 特征重要性
importances = pd.Series(dt_pruned.feature_importances_, index=feature_names)
importances.sort_values(ascending=False).plot(kind='bar')
2.4 随机森林(Random Forest)
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42, n_jobs=-1)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
2.5 神经网络(Neural Network with PyTorch)
import torch
import torch.nn as nn
class MLP(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.layers = nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Dropout(0.3), # 防止过拟合
nn.Linear(hidden_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, output_size)
)
def forward(self, x):
return self.layers(x)
# 训练循环
model = MLP(input_size=20, hidden_size=64, output_size=2)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
for epoch in range(100):
model.train()
optimizer.zero_grad()
outputs = model(X_train_tensor)
loss = criterion(outputs, y_train_tensor)
loss.backward()
optimizer.step()
第三部分:过拟合处理
过拟合的症状:训练集准确率高,测试集准确率低。
| 方法 | 适用场景 | 实现方式 |
|---|---|---|
| 减少模型复杂度 | 决策树/神经网络 | max_depth、减少神经元 |
| 正则化(L1/L2) | 线性模型 | sklearn的 C 参数 |
| Dropout | 神经网络 | nn.Dropout(0.3) |
| Early Stopping | 神经网络 | 验证集 loss 不再下降时停止 |
| 交叉验证 | 所有模型 | cross_val_score |
| 增加数据量 | 所有模型 | 数据增强、更多数据 |
from sklearn.model_selection import cross_val_score
# 5-fold 交叉验证
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"CV Accuracy: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")
第四部分:超参数调优
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, None],
'min_samples_leaf': [1, 5, 10]
}
grid_search = GridSearchCV(RandomForestClassifier(random_state=42),
param_grid, cv=5, scoring='f1', n_jobs=-1)
grid_search.fit(X_train, y_train)
print("Best params:", grid_search.best_params_)
print("Best CV F1:", grid_search.best_score_)
第五部分:ML Assignment Report 写作
Report 是很多同学最失分的地方,因为教授不只要看"你做了什么",更要看"你理解了什么"。
Report 标准结构
1. Introduction(问题描述,数据集介绍)
2. Data Preprocessing(处理了什么,为什么)
3. Model Selection & Justification(为什么选这个算法)
4. Results(表格+图,清晰呈现各指标)
5. Analysis & Discussion(解读结果,对比不同模型)
6. Conclusion(局限性 + 改进方向)
高分 Discussion 要包含的内容
- 模型对比:为什么随机森林比决策树好?(减少方差,不易过拟合)
- 特征重要性分析:哪些特征对预测最重要?有没有 business sense?
- 错误分析:模型在哪类样本上预测最差?为什么?
- 局限性:数据集大小、类别不平衡、特征工程不足等
需要辅导?
ML Assignment 的调试(模型不收敛、维度不匹配、过拟合)和 Report 写作(如何把结果写成有说服力的分析)是最常见的辅导需求。我们的导师熟悉 PyTorch、sklearn、Keras 等主流框架。
相关资源:
