数据集链接:Heart Disease UCI | Kaggle
导入python库
## Plotting Libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import cufflinks as cf
%matplotlib inline
## Metrics for Classification technique
from sklearn.metrics import classification_report,confusion_matrix,accuracy_score
## Scaler
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import RandomizedSearchCV, train_test_split
## Model building
from xgboost import XGBClassifier
from catboost import CatBoostClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
数据加载
导入数据集
data = pd.read_csv("heart.csv")
data.head(6)
探索性数据分析
data.shape
## 特征数据类型
data.info()
简单分析:
1、在14个特征中,13个数据属性为int类型,仅有一个为float数据类型
2、数据集没有任何缺失值
data.describe()
特征变量相关性分析
plt.figure(figsize=(20, 12))
sns.set_context('notebook', font_scale=1.3)
sns.heatmap(data.corr(), annot=True, linewidth=2)
plt.tight_layout()
目标变量相关性分析
sns.set_context('notebook',font_scale = 2.3)
data.drop('target', axis=1).corrwith(data.target).plot(kind='bar', grid=True, figsize=(20, 10),
title="Correlation with the target feature")
plt.tight_layout()
分析:
1、四个特征(“cp”、“retecg”、“thalach”、“slope”)与目标特征正相关
2、其他特征与目标特征负相关
单变量分析——年龄
plt.figure(figsize=(25,12))
sns.set_context('notebook',font_scale = 1.5)
sns.barplot(x=data.age.value_counts()[:10].index,y=data.age.value_counts()[:10].values)
plt.tight_layout()
58 岁这一列出现的频率最高
年龄分析:
minAge = min(data.age)
maxAge = max(data.age)
meanAge = data.age.mean()
print('最小年龄:', minAge)
print('最大年龄:', maxAge)
print('平均年龄:', meanAge)
将年龄特征分为三个部分——“年轻(Young)”、“中年(Middle)”和“年长(Elder)”
Young = data[(data.age>=29)&(data.age<40)]
Middle = data[(data.age>=40)&(data.age<55)]
Elder = data[(data.age>55)]
plt.figure(figsize=(23,10))
sns.set_context('notebook',font_scale = 1.5)
sns.barplot(x=['young ages','middle ages','elderly ages'],y=[len(Young),len(Middle),len(Elder)])
plt.tight_layout()
推论: 老年人受心脏病的影响最大,而年轻人受心脏病的影响最小
使用饼图,进一步展示上述推论:
colors = ['blue', 'green', 'yellow']
explode = [0, 0, 0.1]
plt.figure(figsize=(10, 10))
sns.set_context('notebook', font_scale=1.2)
plt.pie([len(Young), len(Middle), len(Elder)], labels=['young ages', 'middle ages',
'elderly ages'], explode=explode, colors=colors, autopct='%1.1f%%')
plt.tight_layout()
单变量分析——性别
plt.figure(figsize=(18,9))
sns.set_context('notebook',font_scale = 1.5)
sns.countplot(data['sex'])
plt.tight_layout()
推论: 男性与女性的比例约为 2:1
绘制sex与slope的关系:
plt.figure(figsize=(18, 9))
sns.set_context('notebook', font_scale=1.5)
sns.countplot(data['sex'], hue=data["slope"])
plt.tight_layout()
推论: 男性的slope值更高(1)
单变量分析——胸痛类型(cp)
plt.figure(figsize=(18, 9))
sns.set_context('notebook', font_scale=1.5)
sns.countplot(data['cp'])
plt.tight_layout()
胸痛状况分为四种:尚可、低度、中度、严重
胸痛状况与target分析:
plt.figure(figsize=(18, 9))
sns.set_context('notebook', font_scale=1.5)
sns.countplot(data['cp'], hue=data["target"])
plt.tight_layout()
推论:
胸痛最少的人不太可能患有心脏病。
患有严重胸痛的人很可能患有心脏病。
老年人更容易出现胸痛。
单变量分析——Thal
plt.figure(figsize=(18, 9))
sns.set_context('notebook', font_scale=1.5)
sns.countplot(data['thal'])
plt.tight_layout()
Target分析
plt.figure(figsize=(18,9))
sns.set_context('notebook',font_scale = 1.5)
sns.countplot(data['target'])
plt.tight_layout()
推断: 1 和 0 之间的比率远小于 1.5,这表明目标特征不失衡。所以对于一个平衡的数据集,可以使用 accuracy_score 作为我们模型的评估指标。
特征工程
完整数据分析:
categorical_val = []
continous_val = []
for column in data.columns:
print("--------------------")
print(f"{column} : {data[column].unique()}")
if len(data[column].unique()) <= 10:
categorical_val.append(column)
else:
continous_val.append(column)
删除目标列,并对所有类别变量进行分类:
categorical_val.remove('target')
dfs = pd.get_dummies(data, columns=categorical_val)
dfs.head(6)
数据归一化:
sc = StandardScaler()
col_to_scale = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']
dfs[col_to_scale] = sc.fit_transform(dfs[col_to_scale])
dfs.head(6)
构造模型
拆分数据集
X = dfs.drop('target', axis=1)
y = dfs.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42)
KNN机器学习算法
knn = KNeighborsClassifier(n_neighbors=10)
knn.fit(X_train, y_train)
y_pred1 = knn.predict(X_test)
print(accuracy_score(y_test, y_pred1))
预测结论
1、对目标变量、年龄特征等进行了数据可视化和数据分析,以及它的单变量分析和双变量分析。
2、完成了一个完整的特征工程部分,其中包含了进一步步骤(即模型构建)所需的所有有效步骤。
3、从模型准确率来看,KNN准确率是 89%。
原文:Heart Disease Prediction using Machine Learning - Analytics Vidhya