机器学习——模型评价与优化

一、模型的过拟合与欠拟合

1.1现实问题思考

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2欠拟合与过拟合的定义
  • 由于模型不合适,致使其无法对新的测试数据进行准确的预测

在这里插入图片描述

1.3欠拟合
  • 观察训练数据的预测结果发现
  • 选用其他模型、增加模型复杂度、增加数据样本、采集新的维度数据
1.4过拟合
  • 原因
  • 使用了过于复杂的模型结构(比如高阶决策边界)
  • 训练数据不足,有限的训练数据(训练数据只有总体样本中的小部分、不具备代表性)
  • 样本里的噪音数据干扰过大,模型学习到了噪音信息(使用过多与结果不相关属性数据)
  • 解决方法
  • 简化模型结构(降低模型复杂度,能达到好的效果的情况下尽可能选择简单的模型)
  • 数据增强(按照一定的规则扩充样本数据)
  • 数据预处理,保留主成分信息(数据PCA处理)
  • 增加正则化项(regularization)

二、模型过拟合解决

2.1数据增强
  • 图片平移、翻转、旋转、镜像
    在这里插入图片描述
2.2数据PCA处理

在这里插入图片描述
在这里插入图片描述

2.3增加正则项
  • 机器学习过程中,模型求解的核心目标就是最小化损失函数,增加正则项是指在损失函数中添加一个额外项,实现对求解参数的数值约束,防止模型过拟合
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

三、数据分离

  • 一个好的模型,能对新数据样本做出准确预测
    在这里插入图片描述
    在这里插入图片描述
3.1数据分离定义
  • 把全部数据分成两组:训练集、测试集(验证数据集)
  • 用训练集里的数据输入模型进行训练
  • 用测试集里的数据输入模型进行预测,能有效评估此模型预测新的输入数据的表现

在这里插入图片描述

#数据分离
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=1,test_size=0.4)
print(X_train.shape,X_test.shape,X.shape)

四、混淆矩阵(Confusion Matrix)

4.1只用准确率作为模型评估指标的局限性
  • 不能全面或真实表达模型对各类别结果的预测准确度
  • 以准确率作为分类问题的评价指标是有明显缺陷的,假如不同样本的比列非常不均衡,占大比例的类别会成为影响准确率的主要原因
    在这里插入图片描述
    在这里插入图片描述
4.2混淆矩阵的定义
  • 混淆矩阵也称误差矩阵,用于统计各类别样本预测正确与错误的数量,能帮助用户更全面地评估模型表现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
4.3优点
  • 分类任务中,相比单一的准确率指标,混淆矩阵提供了更全面的模型评估信息(TP\TN\FP\FN)
  • 基于混淆矩阵,我们可以计算出多样的模型表现衡量指标,从而实现模型的综合评估
4.4场景
  • 广告精确投放(正样本为“目标用户”):希望目标用户尽可能都被找出来,即实际正样本正确,需要关注召回率;同时,希望预测的正样本中实际都尽可能为正样本,需要关注精确率
  • 异常消费检查(正样本为“异常检测”):希望判断为正常的消费(负样本)中尽可能不存在异常消费,还需要关注特异度
4.5实现
# In[]
#混淆矩阵
from sklearn.metrics import confusion_matrix
cm=confusion_matrix(y_test,y_test_predict)
print(cm)

P=cm[0,1]
FN=cm[1,0]
print(TP,TN,FP,FN)

# In[]
#准确率
accuracy=(TP+TN)/(TP+TN+FP+FN)
print('准确率:',accuracy)



# In[]
#灵敏度(召回率)
sensitivity=recall=TP/(TP+FN)
print('灵敏度:',sensitivity)


# In[]
#特异度
specificity=TN/(TP+FP)
print('特异度:',specificity)

# In[]
#精确率
precision=TP/(TP+FP)
print('精确度:',precision)

# In[]
#F1分数
f1=2*precision*recall/(precision+recall)
print('f1:',f1)

五、模型选择与优化

5.1三大核心问题
  • 选用什么算法?
  • 核心结构、参数如何设置
  • 模型表现不好,怎么办?
5.2算法选择
  • 逻辑回归:边界函数线性;二阶、高阶多项式
  • KNN;核心参数K值取多少合适
  • 决策树:树分支逻辑、最小分支样本数
  • 朴素贝叶斯:高斯、伯努利、CategoricaINB
  • 神经网络:几层、每层神经元数、激活函数
  • 其他算法
5.3模型表现
  • 训练样本预测准确率太低
  • 测试样本准确率下降明显
  • 召回率/特异度/精确率低
  • 模型表现属于结果,如表现不好,需要从前往后找问题
  • 数据是否有问题、算法选的是否合适、核心结构与参数是否合理
5.4建模前五检查
  • 样本代表性:采集数据的方法是否合理,采集到的数据是否具有代表性
  • 标签统一性:对于样本结果,要确保每个样本都遵循一样的标签规则
  • 数据合理化:样本中的异常数据点是否合理、如何处理
  • 数据重要性:数据属性的意义,是否为无关数据
  • 数据差异性:不同属性数据的数量级差异性如何
5.5建模前五方法及好处
  • 根据实际场景扩充或减少样本:数据质量提升,有助于提高模型表现
  • 对不合理标签数据进行预处理:帮助模型学习到正确信息(合理的“监督”)
  • 删除不重要的属性数据、数据降维:降低噪音影响,减少过拟合、节约运算时间
  • 对数据进行归一化或标准化:平衡数据影响,加快训练收敛
  • 过滤掉异常数据:降低噪音影响、提高鲁棒性
5.6现实问题思考

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.7提高模型表现的四要素

在这里插入图片描述

六、任务

6.1炮弹发射轨迹预测,基于数据,建立回归模型,预测炮弹高度
  • 基于train数据,建立线性回归模型,计算其在数据test数据上的r2分数,可视化模型预测结果
  • 分别引入2次、6次多项式数据,建立回归模型
  • 对比三个模型对训练数据、测试数据集做预测的r2分数,判断哪个模型预测更准确
    在这里插入图片描述
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family']='SimHei'
data_train=pd.read_csv('Pt_train_data.csv')
data_test=pd.read_csv('Pt_test_data.csv')

# In[]
x_train=np.reshape(np.array(data_train.iloc[:,0]),(-1,1))
y_train=np.reshape(np.array(data_train.iloc[:,1]),(-1,1))

x_test=np.reshape(np.array(data_test.iloc[:,0]),(-1,1))
y_test=np.reshape(np.array(data_test.iloc[:,1]),(-1,1))
fig1=plt.figure()
plt.scatter(x_train,y_train,label='train')
plt.scatter(x_test,y_test,label='test')
plt.legend()
plt.xlabel('x_d')
plt.ylabel('y_d')

在这里插入图片描述

from sklearn.linear_model import LinearRegression
lr1=LinearRegression()
lr1.fit(x_train,y_train)

# In[]
y_train_predict=lr1.predict(x_train)
y_test_predict=lr1.predict(x_test)

from sklearn.metrics import r2_score
r2_train=r2_score(y_train,y_train_predict)
r2_test=r2_score(y_test,y_test_predict)

print(r2_train,r2_test)

在这里插入图片描述

X_range=np.linspace(40,400,300).reshape(-1,1)
y_range_predict=lr1.predict(X_range)



fig2=plt.figure()
plt.plot(X_range,y_range_predict,label='train_predict',c='r')
plt.scatter(x_train,y_train,label='训练数据')
plt.scatter(x_test,y_test,label='测试数据')
plt.title('炮弹发射距离数据')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.legend()
plt.show()

在这里插入图片描述

#生成二次多项式
from sklearn.preprocessing import PolynomialFeatures
poly2=PolynomialFeatures(degree=2)
x_2_train=poly2.fit_transform(x_train)
x_2_test=poly2.transform(x_test)

#fit_transform()的作用就是先拟合数据,然后转化它将其转化为标准形式
#tranform()的作用是通过找中心和缩放等实现标准化
#训练集上调用fit_transform(),其实找到了均值μ和方差σ^2,即已经找到了转换规则(即方差和均值)
#所以可以直接将其运用到测试集上(甚至交叉验证集)
print(x_train.shape,x_2_train.shape)
print(x_train[0:5],'\n','x_2_train[0:5,:]')

#θ0,x,x的平方

在这里插入图片描述

lr2=LinearRegression()
lr2.fit(x_2_train,y_train)
y_2_train_predict=lr2.predict(x_2_train)
y_2_test_predict=lr2.predict(x_2_test)

r2_2_train=r2_score(y_train,y_2_train_predict)
r2_2_test=r2_score(y_test,y_2_test_predict)

print(r2_2_train,r2_2_test)

在这里插入图片描述

X_range=np.linspace(40,400,300).reshape(-1,1)
X_2_range=poly2.transform(X_range)
y_2_range_predict=lr2.predict(X_2_range)

fig3=plt.figure()
plt.plot(X_range,y_2_range_predict,label='train_predict')
plt.scatter(x_train,y_train,label='训练数据')
plt.scatter(x_test,y_test,label='测试数据')
plt.title('炮弹发射距离数据(poly2)')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.legend()
plt.show()

在这里插入图片描述

#生成六阶属性数据
from sklearn.preprocessing import PolynomialFeatures
poly6=PolynomialFeatures(degree=6)
x_6_train=poly6.fit_transform(x_train)
x_6_test=poly6.transform(x_test)

print(x_train.shape,x_6_train.shape)

lr6=LinearRegression()
lr6.fit(x_6_train,y_train)

y_6_train_predict=lr6.predict(x_6_train)
y_6_test_predict=lr6.predict(x_6_test)

r2_6_train=r2_score(y_train,y_6_train_predict)
r2_6_test=r2_score(y_test,y_6_test_predict)

print(r2_6_train,r2_6_test)

在这里插入图片描述

X_range=np.linspace(40,400,300).reshape(-1,1)
X_6_range=poly6.transform(X_range)
y_6_range_predict=lr6.predict(X_6_range)



fig4=plt.figure()
plt.plot(X_range,y_6_range_predict,label='train_predict')
plt.scatter(x_train,y_train,label='训练数据')
plt.scatter(x_test,y_test,label='测试数据')
plt.title('炮弹发射距离数据(poly6)')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.legend()
plt.show()

在这里插入图片描述

6.2基于数据,综合异常数据检测、PCA降维、数据分离、KNN等技术完成芯片品质预测
  • 基于高斯分布概率密度,对两个维度数据进行分析、计算概率密度函数,寻找异常点进行剔除
  • 统计分析各维度数据分布
  • 对数据进行主成分分析,计算各维度方差比例
  • 数据分离,数据分离参数:random_state=1,test_size=0.4
  • 建立KNN模型(K=3)完成分类,可视化分类边界
  • 计算测试数据集对应的混淆矩阵,准确率、召回率、特异度、精确度、F1分数
  • 尝试不同的K值(1-20),计算其在训练数据集、测试数据集上的准确率并作图
  • 尝试其他模型完成预测:决策树、逻辑回归、朴素贝叶斯
    在这里插入图片描述
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family']='SimHei'

data=pd.read_csv('chip_quality_data.csv')

# In[]
#X,y赋值
X=data.drop(['y'],axis=1)
y=data.loc[:,'y']

# In[]
#数据可视化
fig1=plt.figure()
plt.scatter(X.loc[:,'x1'][y==1], X.loc[:,'x2'][y==1],marker='o',facecolor='none',edgecolor='red',s=150,label='良品' )
plt.scatter(X.loc[:,'x1'][y==0], X.loc[:,'x2'][y==0],marker='x',label='次品' ,s=150)
plt.legend(loc='upper left')
plt.title('芯片数据')
plt.xlabel('尺寸1')
plt.ylabel('尺寸2')
plt.show()

在这里插入图片描述

import math
x1=data.loc[:,'x1'][y==1]
x2=data.loc[:,'x2'][y==1]

#计算均值与标准差
u1=x1.mean()
sigma1=x1.std()
u2=x2.mean()
sigma2=x2.std()
print(u1,sigma1,u2,sigma2)

#计算高斯密度函数
p1=1/sigma1/math.sqrt(2*math.pi)*np.exp(-np.power((x1-u1),2)/2/math.pow(sigma1,2))
p2=1/sigma2/math.sqrt(2*math.pi)*np.exp(-np.power((x2-u2),2)/2/math.pow(sigma2,2))
p = np.multiply(p1,p2)
print(p)
print('max.p',max(p))
print('min.p',min(p))
print('max/min',max(p)/min(p))

在这里插入图片描述

from sklearn.covariance import EllipticEnvelope
ad_model=EllipticEnvelope(contamination=0.02)
ad_model.fit(X[y==0])
y_predict_bad=ad_model.predict(X[y==0])
print(y_predict_bad)

在这里插入图片描述

fig2=plt.figure()
plt.scatter(X.loc[:,'x1'][y==1], X.loc[:,'x2'][y==1],marker='o',facecolor='none',edgecolor='red',s=150,label='良品' )
plt.scatter(X.loc[:,'x1'][y==0], X.loc[:,'x2'][y==0],marker='x',label='次品' ,s=150)
plt.scatter(X.loc[:,'x1'][y==0][y_predict_bad==-1],X.loc[:,'x2'][y==0][y_predict_bad==-1],marker='o',s=150)
plt.legend(loc='upper left')
plt.title('芯片数据')
plt.xlabel('尺寸1')
plt.ylabel('尺寸2')
plt.show()


在这里插入图片描述


#剔除异常数据点
print(data.shape)
data=data.drop(index=35)
print(data.shape)

X=data.drop(['y'],axis=1)
y=data.loc[:,'y']

在这里插入图片描述

#各维度数据分布
fig3=plt.figure()
fig3_1=plt.subplot(121)
plt.hist(x1,bins=10)
plt.xlabel('尺寸1')
plt.ylabel('次数')
plt.title('尺寸1数据')

fig3_2=plt.subplot(122)
plt.hist(x2,bins=10)
plt.xlabel('尺寸2')
plt.ylabel('次数')
plt.title('尺寸2数据')
plt.show()

在这里插入图片描述

#主成分分析
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
X_norm=StandardScaler().fit_transform(X)
pca=PCA(n_components=2)
X_reduced=pca.fit_transform(X_norm)
var_ratio=pca.explained_variance_ratio_
print(var_ratio)
fig4=plt.figure()
plt.bar([1,2],var_ratio)
plt.xticks([1,2],['PC1',['PC2']])


#数据分离
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=1,test_size=0.4)
print(X_train.shape,X_test.shape,X.shape)

在这里插入图片描述

#建立KNN模型k=3
from sklearn.neighbors import KNeighborsClassifier
knn_3=KNeighborsClassifier(n_neighbors=3)
knn_3.fit(X_train,y_train)


# In[]
y_train_predict=knn_3.predict(X_train)
y_test_predict=knn_3.predict(X_test)
print(y_train_predict)



# In[]
from sklearn.metrics import accuracy_score
accuracy_train=accuracy_score(y_train,y_train_predict)
accuracy_test=accuracy_score(y_test,y_test_predict)
print(accuracy_train,accuracy_test)

在这里插入图片描述

#结果可视化
#生成用于结果可视化的数据集
xx,yy=np.meshgrid(np.arange(0,10,0.05),np.arange(0,10,0.05))

#数据展开
X_range=np.c_[xx.ravel(),yy.ravel()]
print(X_range.shape)
print(X_range)


y_range_predict=knn_3.predict(X_range)


# In[]

fig4=plt.figure()
plt.scatter(X_range[:,0][y_range_predict==1], X_range[:,1][y_range_predict==1],label='良品(预测)')
plt.scatter(X_range[:,0][y_range_predict==0], X_range[:,1][y_range_predict==0],label='次品(预测)')

plt.scatter(X.loc[:,'x1'][y==1], X.loc[:,'x2'][y==1],marker='o',facecolor='none',edgecolor='red',s=150,label='良品' )
plt.scatter(X.loc[:,'x1'][y==0], X.loc[:,'x2'][y==0],marker='x',label='次品' ,s=150)


plt.legend(loc='upper left')

plt.title('芯片数据')
plt.xlabel('尺寸1')
plt.ylabel('尺寸2')
plt.show()


在这里插入图片描述
在这里插入图片描述

#混淆矩阵
from sklearn.metrics import confusion_matrix
cm=confusion_matrix(y_test,y_test_predict)
print(cm)

# In[]
#获取混淆矩阵元素
TP=cm[1,1]
TN=cm[0,0]
FP=cm[0,1]
FN=cm[1,0]
print(TP,TN,FP,FN)

# In[]
#准确率
accuracy=(TP+TN)/(TP+TN+FP+FN)
print('准确率:',accuracy)



# In[]
#灵敏度(召回率)
sensitivity=recall=TP/(TP+FN)
print('灵敏度:',sensitivity)


# In[]
#特异度
specificity=TN/(TP+FP)
print('特异度:',specificity)

# In[]
#精确率
precision=TP/(TP+FP)
print('精确度:',precision)

# In[]
#F1分数
f1=2*precision*recall/(precision+recall)
print('f1:',f1)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#尝试不同的K值并计算准确率
n=[i for i in range(1,21)]
accuracy_train=[]
accuracy_test=[]
for i in n:
    knn_i=KNeighborsClassifier(n_neighbors=i)
    knn_i.fit(X_train,y_train)
    y_train_predict=knn_i.predict(X_train)
    y_test_predict=knn_i.predict(X_test)
    accuracy_train_i=accuracy_score(y_train,y_train_predict)
    accuracy_test_i=accuracy_score(y_test,y_test_predict)
    accuracy_train.append(accuracy_train_i)
    accuracy_test.append(accuracy_test_i)
# In[]
#k值变化对准确率影响的结果可视化
fig10 = plt.figure(figsize=(12,5))
plt.subplot(121)
plt.plot(n,accuracy_train,marker='o')
plt.title('训练数据准确率')
plt.xlabel('k')
plt.ylabel('准确率')

plt.subplot(122)
plt.plot(n,accuracy_test,marker='o')
plt.title('测试数据准确率')
plt.xlabel('k')
plt.ylabel('准确率')
plt.show()


在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值