Python入门到实战(十三)过拟合欠拟合、混淆矩阵、评价指标、模型建立与优化、炮弹轨迹预测、芯片品质预测

本文深入探讨了模型过拟合和欠拟合的概念,以及如何通过增加数据量、调整模型复杂度等方式解决。介绍了混淆矩阵及其相关评价指标,如准确率、查准率、查全率和F1分数,并通过实例展示了模型建立与优化过程,包括线性回归、多项式回归和KNN模型的应用。此外,还涉及异常检测和主成分分析在数据预处理中的作用,以及KNN模型在芯片品质预测中的应用和效果评估。
摘要由CSDN通过智能技术生成

模型过拟合与欠拟合

训练数据预测数据
欠拟合不准确不准确
合适模型准确准确
过拟合准确不准确

欠拟合

产生原因:训练集不充分、模型过于简单不够适应场景需求
解决办法:增加模型复杂度 增加样本维数 增加数据样本

过拟合

产生原因:模型过于复杂、数据中噪音过多、训练数据分配不足
解决办法:适当简化模型、按照一定规则扩充样本数据、数据预处理、保留主成分信息、增加正则项

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

混淆矩阵Confusion Matrix

混淆矩阵也称误差矩阵,用于统计各类别样本预测正确与错误的数量,能帮助用户更全面地评估模型表现。

positivenegative
TrueTP(真正例)FN(假反例)
FalseFP(假正例)TN(真反例)

TP预测准确,实际为正样本
TN预测准确,实际为负样本
FP预测错误,预测为正样本、实际为负样本
FN预测错误,预测为负样本、实际为正样本

基于混淆矩阵的评价指标:

准确率accuracy

预测正确的比例:
accuracy=(TP+TN)/(TP+TN+FP+FN)

错误率misclassification rate

预测错误的比例:
misclassification rate=(FN+FP)/(TP+TN+FP+FN)

查准率Precision

预测结果为正的样本中预测正确的比例
Precision=(TP)/(TP+FP)

查全率Recall

正样本中,预测正确的比例
Recall=(TP)/(TP+FN)

特异度Specificity

负样本中,预测正确的比例
Specificity=TN/(TN+FP)

F1分数

综合了precision和recall的指标
F1=(2PrecisionRecall)/(Precision+Recall)

应用优势:

如广告投放问题,需要关注查全率,即更多的用户被查找出来、同时需要关注查准率,即当中都是目标用户
异常消费检测中希望判断正常的消费(负样本)中尽可能不存在异常的消费,需要关注特异度

模型建立与优化

算法选择:

核心结构、参数设置
逻辑回归–>边界函数线性;二阶高阶多项式
KNN–>核心参数k取多少合适
决策树–>树分支逻辑、最小分支样本数
朴素贝叶斯–>高斯、伯努利、CategoricalNB
神经网络–>几层、每层神经元数、激活函数
其他算法–>

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

实战

炮弹轨迹预测

数据载入和可视化

import pandas as pd
import numpy as np
data_train=pd.read_csv('Final_task1_train_data.csv')
data_test=pd.read_csv('Final_task1_test_data.csv')
#数据赋值
x_train=data_train.loc[:,'x_d']
y_train=data_train.loc[:,'y_d']
x_test=data_test.loc[:,'x_d']
y_test=data_test.loc[:,'y_d']
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
data_train=plt.scatter(x_train,y_train,label='training data')
data_test=plt.scatter(x_test,y_test,label='test data')
plt.title('traing-test data')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.show()

在这里插入图片描述

数据预处理、训练模型和预测

#数据预处理]
x_train=np.array(x_train)
x_train=x_train.reshape(-1,1)
x_test=np.array(x_test).reshape(-1,1)
#线性回归模型建立与训练
from sklearn.linear_model import LinearRegression
model1=LinearRegression()
model1.fit(x_train,y_train)
#模型预测
y_train_predict=model1.predict(x_train)
y_test_predict=model1.predict(x_test)
print(y_test_predict)

[193.2015545 207.52252667 224.53579682 245.97018916 280.65629028
358.35826068 383.81445438 392.54847322]

模型评估与可视化、r2分数

#模型评估
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('training r2:',r2_train)
print('test r2:',r2_test)
#可视化模型预测结果 生成新的数据点
x_range=np.linspace(40,400,300).reshape(-1,1)
y_range_predict=model1.predict(x_range)
#结果可视化
fig2=plt.figure()
data_train=plt.scatter(x_train,y_train,label='training data')
data_test=plt.scatter(x_test,y_test,label='test data')
curve_p=plt.plot(x_range,y_range_predict,'r',label='predicted curve')
plt.title('traing-test data')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.show()

training r2: 0.5756251457400434
test r2: -1.6553718247964802
在这里插入图片描述

二次多项式属性数据

#生成二阶属性数据
from sklearn.preprocessing import PolynomialFeatures
poly2=PolynomialFeatures(degree=2)
x_2_train=poly2.fit_transform(x_train)
x_2_test=poly2.fit_transform(x_test)
#建立新的回归模型
model2=LinearRegression()
model2.fit(x_2_train,y_train)
#模型预测评估
y_2_train_predict=model2.predict(x_2_train)
y_2_test_predict=model2.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=model2.predict(x_2_range)
fig3=plt.figure()
data_train=plt.scatter(x_train,y_train,label='training data')
data_test=plt.scatter(x_test,y_test,label='test data')
curve_p=plt.plot(x_range,y_2_range_predict,'r',label='predicted cruve')
plt.title('traing-test data(poly2)')
plt.xlabel('x_d')
plt.ylabel('y_d')
plt.legend()
plt.show()

0.9954725354913146 0.9738532191575348
在这里插入图片描述

六次多项式属性数据

0.9996745021380762 -3.5695788694551593
在这里插入图片描述

总结

回归对应着欠拟合的模型
二阶模型对应着正确的模型
六阶对应着过拟合的模型

芯片品质预测

数据加载可视化

#加载数据
import pandas as pd
import numpy as np
data=pd.read_csv('Final_task2_data.csv')
#赋值
x=data.drop(['y'],axis=1)
y=data.loc[:,'y']
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
bad=plt.scatter(x.loc[:,'x1'][y==0],x.loc[:,'x2'][y==0],marker='x',s=150,label='bad')
good=plt.scatter(x.loc[:,'x1'][y==1],x.loc[:,'x2'][y==1],marker='o',facecolor='none',edgecolor='red',s=150,label='good')
plt.title('chip data')
plt.xlabel('size 1')
plt.ylabel('size 2')
plt.legend()
plt.show()

在这里插入图片描述

import math
x1=data.loc[:,'x1'][y==0]
x2=data.loc[:,'x2'][y==0]
#计算均值与标准差
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)


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)

寻找异常点并剔除

#异常数据点对点检测
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)

[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1]

fig2=plt.figure()
bad=plt.scatter(x.loc[:,'x1'][y==0],x.loc[:,'x2'][y==0],marker='x',s=150,label='bad')
good=plt.scatter(x.loc[:,'x1'][y==1],x.loc[:,'x2'][y==1],marker='o',facecolor='none',edgecolor='red',s=150,label='good')
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.title('chip data')
plt.xlabel('size 1')
plt.ylabel('size 2')
plt.legend()
plt.show()

在这里插入图片描述

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

统计各维度数据分布

#各维度数据分布
fig3 = plt.figure()
plt.subplot(121)
plt.hist(x1,bins=10)
plt.title('x1 data')
plt.xlabel('x1')
plt.ylabel('counts')
plt.subplot(122)
plt.hist(x2,bins=10)
plt.title('x2 data')
plt.xlabel('x2')
plt.ylabel('counts')
plt.show()

w

对数据进行主成分分析,计算各维度方差比例

#X y赋值
X = data.drop(['y'],axis=1)
y = data.loc[:,'y']
#主成分分析
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'])
plt.show()

在这里插入图片描述

数据分离 分离参数0.4

#数据分离
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)

建立KNN模型k=3完成分类

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

#模型预测
y_train_predict = knn_3.predict(X_train)
y_test_predict = knn_3.predict(X_test)

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)

0.8095238095238095 0.7857142857142857

可视化分类边界

#结果可视化
#生成用于结果可视化的数据集
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_3.predict(x_range)
fig4 = plt.figure()

bad_p = plt.scatter(x_range[:,0][y_range_predict==0],x_range[:,1][y_range_predict==0],label='bad_p')
good_p = plt.scatter(x_range[:,0][y_range_predict==1],x_range[:,1][y_range_predict==1],label='good_p')

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


plt.title('chip data')
plt.xlabel('size 1')
plt.ylabel('size 2')
plt.legend()
plt.show()

在这里插入图片描述

评价指标

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

[[4 1]
[2 7]]

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

0.7857142857142857

recall = TP/(TP + FN)
print(recall)

0.7777777777777778

specificity = TN/(TN + FP)
print(specificity)

0.8

precision = TP/(TP + FP)
print(precision)

0.875

f1 = 2*precision*recall/(precision+recall)
print(f1)

0.823529411764706

尝试不同K值1-20并计算准确率

#尝试不同的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)
print(accuracy_train,accuracy_test)

#k值变化对准确率影响的结果可视化
fig10 = plt.figure(figsize=(12,5))
plt.subplot(121)
plt.plot(n,accuracy_train,marker='o')
plt.title('training data accuracy ')
plt.xlabel('k')
plt.ylabel('accuracy')

plt.subplot(122)
plt.plot(n,accuracy_test,marker='o')
plt.title('test data accuracy ')
plt.xlabel('k')
plt.ylabel('accuracy')
plt.show()

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会写程序的程序员.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值