欠拟合与过拟合
欠拟合:模型不合适,导致其无法对数据实现有效预测
过拟合:模型对训练数据的契合度极高,但对预测数据的准确率低
过拟合形成的原因:
- 模型结构过于复杂(维度过高)
- 使用了过多属性,模型训练时包含了干扰项信息
过拟合的解决办法: - 简化模型结构(使用低阶模型,比如线性模型)
- 数据预处理,保留主成分信息(数据PCA处理)
- 在模型训练时,增加正则化项(regularization)
建立模型的意义,不在于对训练数据做出准确预测,更在于对新数据的准确预测
分离数据与测试数据
把数据分成两部分:训练集、测试集,使用训练集进行模型训练,使用测试集进行预测,更有效地评估模型对于新数据的预测表现
混淆矩阵
使用准确率进行分类任务中的模型评估的局限性:
- 无法真实反映模型针对各个分类的预测准确度
- 准确度可以方便的用于衡量模型的整体预测效果,但无法反映细节信息,具体表现为:
- 没有体现数据预测的实际分布情况
- 没有体现模型错误预测的类型
混淆矩阵,又称为误差矩阵,用于衡量分类算法的准确程度
- True Positives(TP):预测准确,实际为正样本的数量(实际为1,预测为1)
- True Negatives(TN):预测准确,实际为负样本的数量(实际为0,预测为0)
- False Positives(FP):预测错误,实际为负样本的数量(实际为0,预测为1)
- False Negatives(FN):预测错误,实际为正样本的数量(实际为1,预测为0)
混淆矩阵指标特点:
- 分类任务中,相比单一的预测准确率,混淆矩阵提供了更全面的模型评估信息(TP/TN/FP/FN)
- 通过混淆矩阵,我们可以计算出多样的模型表现衡量指标,从而更好地选择模型
指标选择主要取决于应用场景:
- 垃圾邮件检测(正样本为“垃圾邮件”):希望普通邮件(负样本)不要被判断为垃圾邮件(正样本),即:判断为垃圾邮件的样本是判断正确的,需要关注精确率;还希望所有的垃圾邮件尽可能被判断出来,需要关注召回率
- 异常交易检测(正样本为“异常交易”):希望判断为正常的交易(负样本)中尽可能不存在异常交易,还需要关注特异度
数据的重要性
数据质量决定模型表现的上限
关注点:
- 数据属性的意义,是否为无关数据
- 不同属性数据的数量级差异性如何
- 是否有异常数据
- 采集数据的方法是否合理,采集到的数据是否有代表性
- 对于标签结果,要确保标签判定规则的一致性(统一标准)
Always try | Benefits |
---|---|
删除不必要的属性 | 减少过拟合,节约运算时间 |
数据预处理:归一化、标准化 | 平衡数据影响,加快训练收敛 |
确定是否保留或过滤异常数据 | 提高鲁棒性 |
尝试不同的模型,对比模型表现 | 帮助确定更合适的模型 |
模型的优化
目标: 在确定模型类别后,如何让模型表现更好
三方面:数据、模型核心参数、正则化
尝试一下方法:
- 遍历核心参数组合,评估对应模型表现(比如:逻辑回归边界函数考虑多项式、KNN尝试不同的n_neighbors值)
- 扩大数据样本
- 增加或减少数据属性
- 对数据进行降维处理
- 对模型进行正则化处理,调整正则项 λ 的数值
酶活性预测代码部分
#生成新数据并用于预测:
X_range = np.linspace(40,90,300).reshape(-1,1)
y_range_predict = lr1.predict(X_range) ///lr1为训练的模型
#生成多项式(二次)数据:
from sklearn.preprocessing import PolynomialFeatures
poly2 = PolynomialFeatures(degrees=2) ///degrees=n等价于将数据训练为x的n次方
X_2_train = poly2.fit_transform(X_train)
X_2_test = poly2.transform(X_test)
质量好坏预测:
#数据分类:
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=4,test_size=0.4)
'''
test_size表示分离的数据的百分比,0.4表示测试数据占40%
'''
#生成决策区域数据
xx,yy = np.meshgrid(np.arange(0,10,0.05),np.arange(0,10,0.05))
x_range = np.c_[xx.ravel(),yy.ravel()]
y_range_predict = knn.predict(x_range)
#可视化决策区域:
bad_knn = plt.scatter(x_range[:,0][y_range_predict==0],x_range[:,1][y_range_predict==0])
good_knn = plt.scatter(x_range[:,0][y_range_predict==1],x_range[:,1][y_range_predict==1])
#计算混淆矩阵
from sklearn.metrics import confusion_matrix
cm = confusion_mairix(y_test,y_test_predict)
TP = cm[1,1]
TN = cm[0,0]
FP = cm[0,1]
FN = cm[1,0]
#计算召回率,特异率,精确率,F1分数:
recall = TP/(TP+FN)
specificity = TN/(TN+FP)
precision = TP/(TP+FP)
f1 = 2*precision*recall/(precision+recall)