机器学习之数据分离与混淆矩阵

前言

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容之数据分离与混淆矩阵。


数据分离

前面我们讲过的实例基本流程都是这样的:
数据载入→数据可视化与预处理→模型创建→全数据用于模型训练→模型评估

按照这个流程的前提是我们要有新数据来作为测试数据供我们使用,那么如果我们没有新数据用于模型评估表现怎么办呢?这时就需要用到数据分离了。

简单来说数据分离就是对全数据进行数据分离,部分数据用来训练,部分数据用于新数据的结果预测。一般就是二八分還是三七分吧

通常来说分为3步:
在这里插入图片描述
小例
在这里插入图片描述
在这里插入图片描述

这里就是将3个数据作为训练数据,两个数据作为测试数据。

混淆矩阵

在我们前面的分类任务中,都是计算测试数据集预测准确率(accuracy)以评估模型表现,但如果只用accuracy会有很大的局限性。
在这里插入图片描述
举个例子:
在这里插入图片描述

如果建立模型如模型1所示,预测准确率就为90%;但如果模型如模型2所示,预测所有的样本结果都是1,也就是说按这个模型无论测试数据是什么,结果都为1,这样就会导致无论数据怎样,我的准确率都是90%,这时得到的准确率就是空准确率。

在这里插入图片描述
这就是只用accuracy的局限性,即我们不知道各类型数据的预测情况,就拿上例来说,我们不知道0中预测准确率是多少,也不知道1中预测准确率是多少,我们只知道整体准确率是90%。同时,我们也无法看出模型错误预测的类型,我们并不知道是0预测不对还是1预测不对,这样会给我们优化模型带来很多不便。

所以,为了更好地评估模型,我们可以用混淆矩阵。

混淆矩阵:又称为误差矩阵,用于衡量分类算法的准确程度
具体的混淆矩阵如下图所示:
在这里插入图片描述
在这里插入图片描述

另外,通过混淆矩阵可以计算更丰富的模型评估指标:

在这里插入图片描述
举个例子:

在这里插入图片描述

在这里插入图片描述
这时我们可以发现负样本中预测正确的比例为0,我们就可以清楚地知道这个指标的预测是有问题的,进而可以修改优化我们的模型。

在这里插入图片描述

在这些指标中没有说谁更重要、谁不重要,其重要度取决于应用场景

以上課件來自慕課

實戰

好壞質檢分類實戰task:

  1. 基於data_class_raw.csv數據,根據高斯分佈概率密度函數,尋找異常點並剔除
  2. 基於data_class_processed.csv數據,進行PCA處理,確定重要數據維度及成分
  3. 完成數據分離,數據分離參數:random_state=4,test_size=0.4
  4. 建立KNN模型完成分類,n_beighbors取10,計算分類準確率,可視化分類邊界
  5. 計算測試數據集對應的混淆矩陣,計算準確率、召回率、特異度、精確率、F1分數
  6. 嘗試不同的n_neighbors(1-20),計算其在訓練數據集、測試數據集上的準確率並作圖
#load the data
import pandas as pd
import numpy as np
data = pd.read_csv('data_class_raw.csv')
data.head()

在这里插入图片描述

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

#visualize the data
from matplotlib import pyplot as plt
fig1 = plt.figure(figsize=(5,5))
bad = plt.scatter(X.loc[:,'x1'][y==0],X.loc[:,'x2'][y==0])
good = plt.scatter(X.loc[:,'x1'][y==1],X.loc[:,'x2'][y==1])
plt.legend((good,bad),('good','bad'))
plt.title('raw data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()

在这里插入图片描述

#anomy detection
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為異常點

在这里插入图片描述

fig2 = plt.figure(figsize=(5,5))
bad = plt.scatter(X.loc[:,'x1'][y==0],X.loc[:,'x2'][y==0])
good = plt.scatter(X.loc[:,'x1'][y==1],X.loc[:,'x2'][y==1])
plt.scatter(X.loc[:,'x1'][y==0][y_predict_bad==-1],X.loc[:,'x2'][y==0][y_predict_bad==-1],marker='x',s=150)
plt.legend((good,bad),('good','bad'))
plt.title('raw data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()

在这里插入图片描述

任務二

data = pd.read_csv('data_class_processed.csv')
data.head()
#define X and y
X = data.drop(['y'],axis=1)
y = data.loc[:,'y']
#pca
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)
fig3 = plt.figure(figsize=(5,5))
plt.bar([1,2],var_ratio)
plt.show()

可以看出這兩個占比都很大也就沒必要降維了
在这里插入图片描述

# train and test split: random_state=4,test_size=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=4,test_size=0.4)
print(X_train.shape,X_test.shape,X.shape) #看一下訓練數據、測試數據占原始數據的多少

數據分離

在这里插入图片描述

#knn model
from sklearn.neighbors import KNeighborsClassifier
knn_10 = KNeighborsClassifier(n_neighbors=10)
knn_10.fit(X_train,y_train)
y_train_predict = knn_10.predict(X_train)
y_test_predict = knn_10.predict(X_test)

#calculate the accuracy
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("training accuracy:",accuracy_train)
print("testing accuracy:",accuracy_test)

可以看出訓練數據準確率還可以,測試數據的不太行
在这里插入图片描述

#visualize the knn result and boundary
xx, yy = np.meshgrid(np.arange(0,10,0.05),np.arange(0,10,0.05)) #生成0-10間隔0.05的數據
print(xx)
print(xx.shape)

生成佈滿整個圖的點,主要是爲了畫出分類邊界
在这里插入图片描述

x_range = np.c_[xx.ravel(),yy.ravel()]
print(x_range.shape)
y_range_predict = knn_10.predict(x_range)

在这里插入图片描述

fig4 = plt.figure()
knn_bad = plt.scatter(x_range[:,0][y_range_predict==0],x_range[:,1][y_range_predict==0])
knn_good = plt.scatter(x_range[:,0][y_range_predict==1],x_range[:,1][y_range_predict==1])

bad = plt.scatter(X.loc[:,'x1'][y==0],X.loc[:,'x2'][y==0])
good = plt.scatter(X.loc[:,'x1'][y==1],X.loc[:,'x2'][y==1])
plt.legend((good,bad,knn_good,knn_bad),('good','bad','knn_good','knn_bad'))
plt.title('predoction data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()

在这里插入图片描述

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

直接用sklearn裏面包生成混淆矩陣

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

算一下各種指標

accuaracy = (TP + TN)/(TP + TN + FP + FN)
print(accuaracy)

可以看出這個跟上面算的是一樣的
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

#try different k and calcualte the accuracy for each
n = [i for i in range(1,21)]
accuaracy_train = []
accuaracy_test = []
for i in n:
    knn = KNeighborsClassifier(n_neighbors=i)
    knn.fit(X_train,y_train)
    y_train_predict = knn.predict(X_train)
    y_test_predict = knn.predict(X_test)
    accuaracy_train_i = accuracy_score(y_train,y_train_predict)
    accuaracy_test_i = accuracy_score(y_test,y_test_predict)
    accuaracy_train.append(accuaracy_train_i)
    accuaracy_test.append(accuaracy_test_i)
print(accuaracy_train,accuaracy_test)

嘗試不同的n_neighbors(1-20),計算其在訓練數據集、測試數據集上的準確率並作圖

在这里插入图片描述

fig5 = plt.figure(figsize=(15,5))
plt.subplot(121)
plt.plot(n,accuaracy_train,marker='o')
plt.title('training accuracy vs n_neighbors')
plt.xlabel('n_neighbors')
plt.ylabel('accuaracy')
plt.subplot(122)
plt.plot(n,accuaracy_test,marker='o')
plt.title('testing accuracy vs n_neighbors')
plt.xlabel('n_neighbors')
plt.ylabel('accuaracy')

plt.show()

可視化看一下

在这里插入图片描述

可以看出n_neighbors值在20時效果最差,n_neighbors小時訓練數據效果好測試數據效果差,總體來説n_neighbors值和準確率並沒有很有規律,還是得多嘗試才知道n_neighbors取什麽好

總結

好壞質檢分類實戰summary:

  1. 通過進行異常監測,幫助找到了潛在的異常數據點
  2. 通過PCA分析,發現需要保留2維數據集
  3. 實現了訓練數據與測試數據的分離,並計算模型對於測試數據的預測準確率
  4. 計算得到混淆矩陣,實現模型更全面的評估
  5. 通過新的方法,可視化分類的決策邊界
  6. 通過調整核心參數n_neighbors值(K值),在計算對應的準確率,可以幫助我們更好的確定使用哪個模型
  7. 核心算法参考链接:

這就是本次學習数据分离与混淆矩阵的筆記
附上本次實戰的數據集和源碼:
鏈接:https://github.com/fbozhang/python/tree/master/jupyter

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值