目錄
一、前期準備
二、實戰(zhàn)演練
2.1分類指標評價計算示例
?2.2數(shù)據(jù)探索性分析(EDA)
2.2.1 導入函數(shù)工具箱
2.2.2 查看數(shù)據(jù)信息等相關數(shù)據(jù)
判斷數(shù)據(jù)缺失和異常
數(shù)字特征相互之間的關系可視化
?類別特征分析(箱圖,小提琴圖,柱形圖)
?2.2.3特征與標簽構建
2.3模型訓練與預測
2.3.1 利用xgb進行五折交叉驗證查看模型的參數(shù)效果
2.3.2 定義xgb和lgb模型函數(shù)
2.3.3 切分數(shù)據(jù)集(Train,Val)進行模型訓練,評價和預測
?編輯
2.3.4 進行兩模型的結果加權融合
承接上一章:數(shù)據(jù)挖掘:汽車車交易價格預測(測評指標;EDA)_牛大了2023的博客-CSDN博客來一次實戰(zhàn)演練。
一、前期準備
數(shù)據(jù)集是我以前發(fā)在資源里的心臟病數(shù)據(jù)集,大家可以手動劃分一下訓練集和測試集。
https://download.csdn.net/download/m0_62237233/87694444?spm=1001.2014.3001.5503
二、實戰(zhàn)演練
2.1分類指標評價計算示例
import pandas as pd
import numpy as np
import os, PIL, random, pathlib
data_dir = './data/'
data_dir = pathlib.Path(data_dir)
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
import torch.nn.functional as F
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("\\")[1] for path in data_paths]
print(classeNames)
Train_data = pd.read_csv('data/trainC.csv', sep=',')
Test_data = pd.read_csv('data/testC.csv', sep=',')
print('Train data shape:',Train_data.shape) #包含了標簽所以多一列
print('TestA data shape:',Test_data.shape)
?打印相關指標
from sklearn.metrics import accuracy_score
y_pred = [0, 1, 0, 1]
y_true = [0, 1, 1, 1]
print('ACC:',accuracy_score(y_true, y_pred))
## Precision,Recall,F1-score
from sklearn import metrics
y_pred = [0, 1, 0, 0]
y_true = [0, 1, 0, 1]
print('Precision',metrics.precision_score(y_true, y_pred))
print('Recall',metrics.recall_score(y_true, y_pred))
print('F1-score:',metrics.f1_score(y_true, y_pred))
import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print('AUC socre:',roc_auc_score(y_true, y_scores))
回歸指標評價計算也搞里頭
# coding=utf-8
import numpy as np
from sklearn import metrics
# MAPE需要自己實現(xiàn)
def mape(y_true, y_pred):
return np.mean(np.abs((y_pred - y_true) / y_true))
y_true = np.array([1.0, 5.0, 4.0, 3.0, 2.0, 5.0, -3.0])
y_pred = np.array([1.0, 4.5, 3.8, 3.2, 3.0, 4.8, -2.2])
# MSE
print('MSE:',metrics.mean_squared_error(y_true, y_pred))
# RMSE
print('RMSE:',np.sqrt(metrics.mean_squared_error(y_true, y_pred)))
# MAE
print('MAE:',metrics.mean_absolute_error(y_true, y_pred))
# MAPE
print('MAPE:',mape(y_true, y_pred))
?2.2數(shù)據(jù)探索性分析(EDA)
2.2.1 導入函數(shù)工具箱
## 基礎工具
import numpy as np
import pandas as pd
import warnings
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.special import jn
from IPython.display import display, clear_output
import time
warnings.filterwarnings('ignore')
## 模型預測的
from sklearn import linear_model
from sklearn import preprocessing
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
## 數(shù)據(jù)降維處理的
from sklearn.decomposition import PCA, FastICA, FactorAnalysis, SparsePCA
import lightgbm as lgb
import xgboost as xgb
## 參數(shù)搜索和評價的
from sklearn.model_selection import GridSearchCV, cross_val_score, StratifiedKFold, train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error
# coding:utf-8
# 導入warnings包,利用過濾器來實現(xiàn)忽略警告語句。
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
2.2.2 查看數(shù)據(jù)信息等相關數(shù)據(jù)
## 2) 簡略觀察數(shù)據(jù)(head()+shape)
print(Train_data.head().append(Train_data.tail()))
?通過describe()來熟悉數(shù)據(jù)的相關統(tǒng)計量
describe種有每列的統(tǒng)計量,個數(shù)count、平均值mean、方差std、最小值min、中位數(shù)25% 50% 75% 、以及最大值?看這個信息主要是瞬間掌握數(shù)據(jù)的大概的范圍以及每個值的異常值的判斷
?這個數(shù)據(jù)集沒啥問題,但還是要做這些前置工作,要養(yǎng)成這個習慣。
判斷數(shù)據(jù)缺失和異常
print(Train_data.isnull().sum())
?沒缺少的
了解預測值分布情況
對預測值分析+對預測值進行統(tǒng)計+對分布情況進行驗證,以time變量為例
## 1) 總體分布概況(無界約翰遜分布等)
import scipy.stats as st
y = Train_data['time']
plt.figure(1);
plt.title('Johnson SU')
sns.distplot(y, kde=False, fit=st.johnsonsu)
plt.figure(2);
plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)
plt.figure(3);
plt.title('Log Normal')
sns.distplot(y, kde=False, fit=st.lognorm)
plt.show()
?
?還挺符合正態(tài)分布的。在進行回歸之前,可以進行轉(zhuǎn)換。雖然對數(shù)變換做得很好,但最佳擬合是無界約翰遜分布。
?查看頻數(shù)
plt.hist(Train_data['time'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
# log變換 z之后的分布較均勻,可以進行l(wèi)og變換進行預測,這也是預測問題常用的trick
plt.hist(np.log(Train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
?將time進行l(wèi)og變換后趨近于正態(tài)分布,可以用來預測。
特征分為類別特征和數(shù)字特征,并對類別特征查看unique分布
# 分離label即預測值
Y_train = Train_data['time']
# 這個區(qū)別方式適用于沒有直接label coding的數(shù)據(jù)
# 這里不適用,需要人為根據(jù)實際含義來區(qū)分
# 數(shù)字特征
# numeric_features = Train_data.select_dtypes(include=[np.number])
# numeric_features.columns
# # 類型特征
# categorical_features = Train_data.select_dtypes(include=[np.object])
# categorical_features.columns
#數(shù)字特征
numeric_features = ['age', 'creatinine_phosphokinase', 'ejection_fraction', 'platelets', 'serum_creatinine', 'serum_sodium', 'time']
#類型特征
categorical_features = ['anaemia', 'diabetes', 'high_blood_pressure', 'sex', 'smoking', 'DEATH_EVENT']
# 特征nunique分布
for cat_fea in categorical_features:
print(cat_fea + "的特征分布如下:")
print("{}特征有個{}不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
print(Train_data[cat_fea].value_counts())
相關性分析:
## 1) 相關性分析
numeric_features.append('DEATH_EVENT')
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr()
print(correlation['DEATH_EVENT'].sort_values(ascending = False),'\n')
?
數(shù)字特征相互之間的關系可視化
## 4) 數(shù)字特征相互之間的關系可視化
sns.set()
columns = ['age', 'creatinine_phosphokinase', 'ejection_fraction', 'platelets', 'serum_creatinine', 'serum_sodium', 'time']
sns.pairplot(Train_data[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()
弄time和其他的看看
## 5) 多變量互相回歸關系可視化
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8), (ax9, ax10)) = plt.subplots(nrows=5, ncols=2, figsize=(24, 20))
# ['age', 'creatinine_phosphokinase' , 'ejection_fraction', 'platelets', 'serum_creatinine', 'time']
age_scatter_plot = pd.concat([Y_train, Train_data['age']], axis=1)
sns.regplot(x='age', y='time', data=age_scatter_plot, scatter=True, fit_reg=True, ax=ax1)
creatinine_phosphokinase_scatter_plot = pd.concat([Y_train, Train_data['creatinine_phosphokinase']], axis=1)
sns.regplot(x='creatinine_phosphokinase', y='time', data=creatinine_phosphokinase_scatter_plot, scatter=True,
fit_reg=True, ax=ax2)
ejection_fraction_scatter_plot = pd.concat([Y_train, Train_data['ejection_fraction']], axis=1)
sns.regplot(x='ejection_fraction', y='time', data=ejection_fraction_scatter_plot, scatter=True, fit_reg=True, ax=ax3)
platelets_scatter_plot = pd.concat([Y_train, Train_data['platelets']], axis=1)
sns.regplot(x='platelets', y='time', data=platelets_scatter_plot, scatter=True, fit_reg=True, ax=ax4)
serum_creatinine_scatter_plot = pd.concat([Y_train, Train_data['serum_creatinine']], axis=1)
sns.regplot(x='serum_creatinine', y='time', data=serum_creatinine_scatter_plot, scatter=True, fit_reg=True, ax=ax5)
# time_scatter_plot = pd.concat([Y_train, Train_data['time']], axis=1)
# sns.regplot(x='time', y='time', data=time_scatter_plot, scatter=True, fit_reg=True, ax=ax6)
plt.show()
?類別特征分析(箱圖,小提琴圖,柱形圖)
# 因為 name和 regionCode的類別太稀疏了,這里我們把不稀疏的幾類畫一下
categorical_features = ['anaemia',
'diabetes',
'high_blood_pressure',
'sex',
'smoking']
for c in categorical_features:
Train_data[c] = Train_data[c].astype('category')
if Train_data[c].isnull().any():
Train_data[c] = Train_data[c].cat.add_categories(['MISSING'])
Train_data[c] = Train_data[c].fillna('MISSING')
def boxplot(x, y, **kwargs):
sns.boxplot(x=x, y=y)
x = plt.xticks(rotation=90)
f = pd.melt(Train_data, id_vars=['DEATH_EVENT'], value_vars=categorical_features) # 預測值
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, height=5)
g = g.map(boxplot, "value", "DEATH_EVENT")
plt.show()
因為都是0-1數(shù)據(jù),所以好像沒法直觀看…不再演示其他類型圖了
?類別特征的每個類別頻數(shù)可視化(count_plot)
## 5) 類別特征的每個類別頻數(shù)可視化(count_plot)
def count_plot(x, **kwargs):
sns.countplot(x=x)
x=plt.xticks(rotation=90)
f = pd.melt(Train_data, value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, height=5)
g = g.map(count_plot, "value")
plt.show()
?2.2.3特征與標簽構建
- 提取數(shù)值類型特征列名
numerical_cols = Train_data.select_dtypes(exclude='object').columns
print(numerical_cols)
categorical_cols = Train_data.select_dtypes(include='object').columns
print(categorical_cols)
- 構建訓練和測試樣本
## 提前特征列,標簽列構造訓練樣本和測試樣本
X_data = Train_data[feature_cols]
Y_data = Train_data['time']
X_test = Test_data[feature_cols]
print('X train shape:', X_data.shape)
print('X test shape:', X_test.shape)
X train shape: (209, 13)
X test shape: (90, 13)
- 統(tǒng)計標簽的基本分布信息
## 定義了一個統(tǒng)計函數(shù),方便后續(xù)信息統(tǒng)計
def Sta_inf(data):
print('_min', np.min(data))
print('_max:', np.max(data))
print('_mean', np.mean(data))
print('_ptp', np.ptp(data))
print('_std', np.std(data))
print('_var', np.var(data))
print('Sta of label:')
Sta_inf(Y_data)
## 繪制標簽的統(tǒng)計圖,查看標簽分布
plt.hist(Y_data)
plt.show()
2.3模型訓練與預測
2.3.1 利用xgb進行五折交叉驗證查看模型的參數(shù)效果
## xgb-Model
xgr = xgb.XGBRegressor(n_estimators=120, learning_rate=0.1, gamma=0, subsample=0.8,\
colsample_bytree=0.9, max_depth=7) #,objective ='reg:squarederror'
#簇120,學習率0.1 ,深度為7
scores_train = []
scores = []
## 5折交叉驗證方式,防止過擬合
sk=StratifiedKFold(n_splits=5,shuffle=True,random_state=0)
for train_ind,val_ind in sk.split(X_data,Y_data):
train_x=X_data.iloc[train_ind].values
train_y=Y_data.iloc[train_ind]
val_x=X_data.iloc[val_ind].values
val_y=Y_data.iloc[val_ind]
xgr.fit(train_x,train_y)
pred_train_xgb=xgr.predict(train_x)
pred_xgb=xgr.predict(val_x)
score_train = mean_absolute_error(train_y,pred_train_xgb)
scores_train.append(score_train)
score = mean_absolute_error(val_y,pred_xgb)
scores.append(score)
print('Train mae:',np.mean(score_train))
print('Val mae',np.mean(scores))
Train mae: 0.04781590756915864
Val mae 1.206481080991189
2.3.2 定義xgb和lgb模型函數(shù)
def build_model_xgb(x_train,y_train):
model = xgb.XGBRegressor(n_estimators=150, learning_rate=0.1, gamma=0, subsample=0.8,\
colsample_bytree=0.9, max_depth=7) #, objective ='reg:squarederror'
model.fit(x_train, y_train)
return model
def build_model_lgb(x_train,y_train):
estimator = lgb.LGBMRegressor(num_leaves=127,n_estimators = 150)
param_grid = {
'learning_rate': [0.01, 0.05, 0.1, 0.2],
}
gbm = GridSearchCV(estimator, param_grid) #網(wǎng)格搜索
gbm.fit(x_train, y_train)
return gbm
網(wǎng)格搜索自動調(diào)參方式,對param_grid中參數(shù)進行改正,可以添加學習率等等參數(shù)
param_grid = {
'learning_rate': [0.01, 0.05, 0.1, 0.2],
'n_estimators': [100, 140, 120, 130],
}
2.3.3 切分數(shù)據(jù)集(Train,Val)進行模型訓練,評價和預測
## Split data with val
x_train,x_val,y_train,y_val = train_test_split(X_data,Y_data,test_size=0.3)
?按比例切分,也可以4:1 即test_size=0.2
print('Train lgb...')
model_lgb = build_model_lgb(x_train,y_train)
val_lgb = model_lgb.predict(x_val)
MAE_lgb = mean_absolute_error(y_val,val_lgb)
print('MAE of val with lgb:',MAE_lgb)
print('Predict lgb...')
model_lgb_pre = build_model_lgb(X_data,Y_data)
subA_lgb = model_lgb_pre.predict(X_test)
print('Sta of Predict lgb:')
Sta_inf(subA_lgb)
文章來源:http://www.zghlxwxcb.cn/news/detail-770017.html
print('Train xgb...')
model_xgb = build_model_xgb(x_train,y_train)
val_xgb = model_xgb.predict(x_val)
MAE_xgb = mean_absolute_error(y_val,val_xgb)
print('MAE of val with xgb:',MAE_xgb)
print('Predict xgb...')
model_xgb_pre = build_model_xgb(X_data,Y_data)
subA_xgb = model_xgb_pre.predict(X_test)
print('Sta of Predict xgb:')
Sta_inf(subA_xgb)
2.3.4 進行兩模型的結果加權融合
## 這里我們采取了簡單的加權融合的方式
val_Weighted = (1-MAE_lgb/(MAE_xgb+MAE_lgb))*val_lgb+(1-MAE_xgb/(MAE_xgb+MAE_lgb))*val_xgb
val_Weighted[val_Weighted<0]=10 # 由于我們發(fā)現(xiàn)預測的最小值有負數(shù),而真實情況下,price為負是不存在的,由此我們進行對應的后修正
print('MAE of val with Weighted ensemble:',mean_absolute_error(y_val,val_Weighted))
MAE of val with Weighted ensemble: 3.1147994422143657文章來源地址http://www.zghlxwxcb.cn/news/detail-770017.html
到了這里,關于數(shù)據(jù)挖掘:心臟病預測(測評指標;EDA)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!