1. 导入并查看数据信息
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns
# 载入数据 data = pd.read_csv('./diabetes.csv') data.head()
数据说明:
Pregnancies:怀孕次数
Glucose:葡萄糖测试值
BloodPressure:血压
SkinThickness:皮肤厚度
Insulin:胰岛素
BMI:身体质量指数
DiabetesPedigreeFunction:糖尿病遗传函数
Age:年龄
Outcome:糖尿病标签
# 查看数据类型 data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 768 entries, 0 to 767 Data columns (total 7 columns): Pregnancies 768 non-null int64 Glucose 768 non-null float64 BloodPressure 768 non-null float64 BMI 768 non-null float64 DiabetesPedigreeFunction 768 non-null float64 Age 768 non-null int64 Outcome 768 non-null int64 dtypes: float64(4), int64(3) memory usage: 42.1 KB
# 查看数据基本信息 data.describe()
# 查看数据形状 data.shape • 1 • 2
(768, 9)
# 查看标签分布 print(data.Outcome.value_counts()) # 使用柱状图的方式画出标签个数统计 data.Outcome.value_counts().plot(kind="bar") plt.show()
0 500 1 268 Name: Outcome, dtype: int64
# 查看两个目标分类下,各个特征的数据分布 sns.pairplot(data, hue = 'Outcome') plt.show()
上图表明的是两种目标分类下,不用类型特征属性之间的关系,包含直方图和散点图。
其中同一特征对比时用的是直方图,不同特征对比的时候用的是散点图。
2. 特征工程
2.1 处理异常值
通过观察上图数据分布可以发现一些异常值,比如Glucose葡萄糖,BloodPressure血压,SkinThickness皮肤厚度,Insulin胰岛素,BMI身体质量指数存在0数值,但是这些数值应该是不可能出现0值的,因此我们需要将这些异常的0值进行处理。
# 将葡萄糖,血压,皮肤厚度,胰岛素,身体质量指数中的0替换为nan colume = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI'] data[colume] = data[colume].replace(0,np.nan)
# 查看数据类型 data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 768 entries, 0 to 767 Data columns (total 9 columns): Pregnancies 768 non-null int64 Glucose 763 non-null float64 BloodPressure 733 non-null float64 SkinThickness 541 non-null float64 Insulin 394 non-null float64 BMI 757 non-null float64 DiabetesPedigreeFunction 768 non-null float64 Age 768 non-null int64 Outcome 768 non-null int64 dtypes: float64(6), int64(3) memory usage: 54.1 KB
# 画出各特征非空的数值个数 data.notnull().sum().plot(kind="bar")
<matplotlib.axes._subplots.AxesSubplot at 0x192abc4ac50>
# 设定阀值,非空值需要超过总数量的80%以上 thresh_count = data.shape[0]*0.8 # 若某一列数据缺失的数量超过20%就会被删除 data = data.dropna(thresh=thresh_count, axis=1)
# 画出各特征非空的数值个数 data.notnull().sum().plot(kind="bar") • 1 • 2
<matplotlib.axes._subplots.AxesSubplot at 0x192a79c8b38>
2.2 填充缺失值
# 导入插补库 from sklearn.preprocessing import Imputer # 此处采用均值插补的方法来填充缺失值 imr = Imputer(missing_values='NaN', strategy='mean', axis=0) colume = ['Glucose', 'BloodPressure', 'BMI'] # 进行插补 data[colume] = imr.fit_transform(data[colume])
D:\anaconda3\lib\site-packages\ipykernel_launcher.py:7: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy import sys D:\anaconda3\lib\site-packages\pandas\core\indexing.py:543: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy self.obj[item] = s
# 画出各特征非空的数值个数 data.notnull().sum().plot(kind="bar") • 1 • 2
<matplotlib.axes._subplots.AxesSubplot at 0x192af6bde80>
plt.figure(figsize=(12,10)) # 画热力图,数值为两个变量之间的相关系数 p=sns.heatmap(data.corr(), annot=True) plt.show()
3. 切分数据集并构建模型
# 把数据切分为特征x和标签y x = data.drop("Outcome",axis = 1) y = data.Outcome
from sklearn.model_selection import train_test_split # 切分数据集,stratify=y表示切分后训练集和测试集中的数据类型的比例跟切分前y中的比例一致 # 比如切分前y中0和1的比例为1:2,切分后y_train和y_test中0和1的比例也都是1:2 x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3, stratify=y)
# 此处使用逻辑回归进行建模 from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report LR = LogisticRegression() LR.fit(x_train,y_train) pre_result= LR.predict(x_test) print(classification_report(y_test, pre_result))
precision recall f1-score support 0 0.78 0.91 0.84 150 1 0.76 0.52 0.62 81 avg / total 0.77 0.77 0.76 231
由上述结果,可以看出该模型的准确率约为76%,不是很高,模型还需进一步优化。