一、选题的背景
睡眠健康在当代社会中具有重要的意义。随着现代生活方式的改变和工作压力的增加,许多人面临着睡眠问题和健康隐患。因此,对于睡眠健康进行数据分析可以提供有价值的洞察和解决方案,改善人们的生活质量和健康状况。
数据分析目标: 该数据分析的目标是深入了解睡眠健康状况、发现潜在的睡眠问题,并提供个性化的建议和干预措施。通过分析睡眠数据,我们可以探索并深入了解不同个体之间睡眠质量的差异和关联。性别、年龄和职业可能与睡眠质量存在相关性,例如年龄增长可能影响睡眠质量。睡眠时间、睡眠质量和身体活动水平之间可能存在相互影响的关系。压力水平和睡眠质量之间可能存在正反馈关系。BMI类别、血压和心率可能与睡眠质量有关联。每日步数和睡眠质量可能存在相关性,而是否有睡眠障碍可能对睡眠质量产生显著影响。等因素与个体健康状况的关联性,为个人提供科学有效的睡眠管理方案。
综上所述,睡眠健康分析的目的是通过数据分析方法深入了解睡眠问题,提供个性化的睡眠管理建议,并促进人们的健康和生活质量的提高。
二、大数据分析设计方案
数据集来源:kaggle,网址:https://www.kaggle.com/
数据集涵盖了与睡眠和日常习惯有关的诸多变量。如性别、年龄、职业、睡眠时间、睡眠质量、身体活动水平、压力水平、BMI类别、血压、心率、每日步数、以及是否有睡眠障碍等细节。
经过检查,数据却没有缺失值,也没有重复值。但数据中存在一部分的分类型变量,需要对其进行编码,方便考察变量之间相关性以及后续的预测。除此之外,血压字段中存在高压和低压混合 的情况,需要对其进行拆解。
使用第三方库:运用pandas、matplotlib、numpy、seaborn等库对数据进行可视化。
实现思路:对数据集进行分析→进行数据清洗→根据所需内容对数据进行可视化→得到图像并分析结果
本文的分析主要在以下四个方面进行:
基本字段分析:分析各个字段的分布情况,基本掌握数据集的分布情况,方便后续的分析。
全面的睡眠指标:探索睡眠时间、质量和影响睡眠模式的因素。
生活方式因素:分析身体活动水平、压力水平和BMI类别。
心血管健康:检查血压和心率测量。
睡眠障碍分析:识别睡眠障碍的发生,如失眠和睡眠呼吸暂停。
三、数据分析步骤
数据集来源:kaggle,网址:https://www.kaggle.com/
一、安装数据库
!pip install xgboost二、导入数据库
# 导入相关库 import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.preprocessing import LabelEncoder import warnings import xgboost from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier from sklearn.metrics import confusion_matrix, classification_report, accuracy_score warnings.filterwarnings('ignore') plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据集 df = pd.read_csv('/home/mw/input/data1581/Sleep_health_and_lifestyle_dataset.csv',encoding='gbk') df.head()
代码过程繁多,直接附上重要分析结果,并对各个结果做出解释:
分类型变量分析
针对于分类型变量考察各个类别的分布,针对数值型变量考察其概率分布情况。首先是关于年龄和职业的分析:
从性别来看,男女总人数接近于1:1,但从事的职业有较大的的差异:男性更多的从事于医生、软件工程师(数据集中没有女性从事该职业)、销售代表(数据集中没有女性从事该职业)、律师、营业员(该数据集中没有女性从事该工作);女性更多的从事于老师、护士(数据集中没有男性从事该职业)、会计师、科学家(数据集中没有男性从事该职业)、主管(数据集中没有男性从事该职业);工程师的从业男女比例接近于1:1。
这份数据集的采集对象一定程度的打破了男性更适合精密、严谨工作的刻板印象,女性在其中从事的工作跨度非常大,除了传统认为女性适宜从事的职业外,像类似于科学家、主管等职业反倒是女性人数占优。
下一个要考虑的分类型变量为睡眠障碍字段:
男性没有睡眠障碍的人数多于女性;女性出现睡眠障碍的人群中更多人会出现睡眠呼吸暂停的情况;男女失眠的人群中,男性的人数比女性略高。
女性的BMI指数更容易出现超重的情况;男性正常的人数高于女性,同时肥胖的人数也显著高于女性。
数值型变量分析
首先考虑的是年龄的分布情况:
从直方图来看,数据集中被调研者的年龄集中在27-59岁之间,基本呈现对称分布的态势,42岁左右的人数最多。
然后是睡眠时长的分布情况:
从直方图来看,睡眠时间六小时左右的人数最多,其次是7.2小时的人数;睡眠时间呈现出双峰分布的态势,且更多的人群偏向于睡更久的时间。
下面是睡眠质量的分布:
睡眠质量在6分到8分的人数最多,没有9分以上的人群,但存在4-5分的低分人群。
心率的分布:
心率分布整体呈现右偏分布的态势,这与数据集选取的调研人群的年龄有一定的关系:一般来说,年龄越大,心率会越慢,但是数据集选取的调研人群大多集中在青壮年的范围内,心率偏快属于比较正常的现象。
血压的分布:
低压集中在80左右的人数最多,高压集中在130的人数最多。高压的正常范围一般在90-140mmHg,低压的正常范围是60-90mmHg,数据集中低压有部分人群高于90,高压有部分人群高于140,但高出的幅度都不大。
下面是身体活动水平:
身体活动水平呈现出多峰分布,集中在30-90之间,整体身体活动水平集中在五个维度,其余维度的被调研者数量很少。
压力水平分布:
压力水平在7左右的人群最多,且分布比较集中,压力在5或者5以下的人群占比较多。
步数分布水平:
每日步数的分布集中在3000-8000之间,整个数据集的被调研人群每天的步数量还是非常可观的。
睡眠指标
这里使用的描述睡眠指标模型的指标主要是在睡眠时间和睡眠质量以及睡眠障碍三个字段。而影响睡眠模式的因素非常多,先对整个数据集的所有字段两两绘制散点图和直方图,考察它们之间的相关性:
从上述图表可知:睡眠时长和身体活动水平,睡眠质量和压力水平有一定的相关关系,高压低压和每日步数、心率有一定的相关关系。
绘制热力图更加辅助了上面的认知,睡眠时长和年龄有一定的相关性,睡眠质量和身体活动水平和年龄有一定的相关性,是否出现睡眠障碍和每日步数、身体活动水平有一定的相关性,高压低压和BMI、年龄、职业有较强的相关关系。
为了更好的找出与睡眠模式等有关的特征,这里分别将这三个字段作为自变量,剩下的字段(除这三个字段以外)作为特征,按照因变量的类型分别使用分类和回归模型进行预测,根据输出的重要性指标判断与上述三个字段有关的特征有哪些。
从热力图可知,对于睡眠时长来说,压力水平的重要性最高,其次是年龄和身体活动水平;对于睡眠质量而言,压力水平的重要性最高,其次是年龄;对于是否存在睡眠障碍而言,BMI、职业、血压的重要性较高。
综上所述,睡眠时长的影响因素主要是压力水平、年龄和身体活动水平;睡眠质量的影响因素主要是压力水平和年龄;是否存在睡眠障碍的主要影响因素是BMI、职业和血压。
生活方式因素
分析身体活动水平、压力水平和BMI类别这部分已经在基本分析中完成,此处不再赘述。这里的分析主要集中在不同性别身体活动水平、压力水平的差异性分析上:
根据箱型图可以看出,身体活动水平男女之间几乎没有差别。
下面是压力水平的差异性分析:
不同性别压力水平差异较大,女性的压力水平总体较男性低,且波动程度大,个体差异性更加明显,下四分位数同时也是最小值整体呈现右偏分布;男性的压力水平则基本呈现对称分布,波动程度小,个体差异性较小。
心血管健康
检查血压和心率测量的部分也已经在基本分析中完成。此处同样重点考察不同性别带来的血压和心率测量的差异性:
从箱型图来看,男性心率存在非常多的异常值,且都是偏大的异常值,正常而言女性的心率要高于男性的心率,而此处被调研者则呈现出了完全相反的规律;女性的心率差异性明显,这点在箱型图上有所体现。
下面分别来看高压和低压的箱型图分布情况:
女性血压的高压和低压都高于男性,且波动性更大。
睡眠障碍分析
将数据集三七分,七份作为训练集,三份作为测试集,利用XGBoost预测睡眠障碍的类型,此处XGBoost的代码参考自:XGBoost保姆级教程
从混淆矩阵来看,模型的预测准确率还是比较不错的。
最后附上总代码
!pip install xgboost # 导入相关库 import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.preprocessing import LabelEncoder import warnings import xgboost from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier from sklearn.metrics import confusion_matrix, classification_report, accuracy_score warnings.filterwarnings('ignore') plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 导入数据集 df = pd.read_csv('/home/mw/input/data1581/Sleep_health_and_lifestyle_dataset.csv',encoding='gbk') df.head()
# 检查数据集缺失情况 df.info()
# 检查数据集重复情况 df.duplicated().sum()
df_new = df.copy()
cat_cols = []
for each in df_new.columns.tolist(): if df_new[each].dtype == 'object' and each != '血压': cat_cols.append(each) print(df_new[each].value_counts().to_frame())
# 分类型变量编码
for col in cat_cols: le = LabelEncoder() le.fit(df_new[col]) df_new[col] = le.transform(df_new[col])
df_new.head()
xueya = df_new['血压'].str.split('/',expand=True) xueya.columns = ['高压','低压'] xueya = xueya.astype(int)
df_new = pd.concat([df_new,xueya],axis=1)
df_new.info()
plt.figure(figsize=(12,8)) sns.countplot(x='性别',hue='职业',data=df,palette='Set3') plt.title('男女及从事职业情况',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) sns.countplot(x='性别',hue='睡眠障碍',data=df,palette='Set3') plt.title('男女睡眠障碍情况',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) sns.countplot(x='性别',hue='BMI',data=df,palette='Set3') plt.title('男女BMI情况',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) plt.hist(df['年龄'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['年龄'].plot(kind = 'kde') plt.title('年龄分布',fontsize=20) plt.show()
df['年龄'].min(),df['年龄'].max()
plt.figure(figsize=(12,8)) plt.hist(df['睡眠时长'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['睡眠时长'].plot(kind = 'kde') plt.title('睡眠时间分布',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) plt.hist(df['睡眠质量'],density=True,bins=6,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['睡眠质量'].plot(kind = 'kde') plt.title('睡眠质量分布',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) plt.hist(df['心率'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['心率'].plot(kind = 'kde') plt.title('心率分布',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) plt.hist(df_new['高压'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7),label='高压') df_new['高压'].plot(kind = 'kde',label='高压') plt.hist(df_new['低压'],density=True,bins=15,color=plt.cm.RdBu(0.3),edgecolor=plt.cm.RdBu(0.2),label='低压') df_new['低压'].plot(kind = 'kde',label='低压') plt.title('血压分布',fontsize=20) plt.legend() plt.show()
df_new['高压'].max(),df_new['高压'].min(),df_new['低压'].min(),df_new['低压'].max()
plt.figure(figsize=(12,8)) plt.hist(df['身体活动水平'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['身体活动水平'].plot(kind = 'kde') plt.title('身体活动水平分布',fontsize=20) plt.show()
df['身体活动水平'].min(),df['身体活动水平'].max()
plt.figure(figsize=(12,8)) plt.hist(df['压力水平'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['压力水平'].plot(kind = 'kde') plt.title('压力水平分布',fontsize=20) plt.show()
plt.figure(figsize=(12,8)) plt.hist(df['每日步数'],density=True,bins=15,color=plt.cm.RdBu(0.6),edgecolor=plt.cm.RdBu(0.7)) df['每日步数'].plot(kind = 'kde') plt.title('每日步数分布',fontsize=20) plt.show()
sns.pairplot(df_new[df_new.columns.tolist()[1:]])
plt.figure(figsize=(12,12)) plt.imshow(df_new.iloc[:,1:].corr(),cmap='Blues') plt.xticks(range(len(df_new.iloc[:,1:].corr().columns.tolist())),df_new.iloc[:,1:].corr().columns.tolist(),rotation=45) plt.yticks(range(len(df_new.iloc[:,1:].corr().columns.tolist())),df_new.iloc[:,1:].corr().columns.tolist(),rotation=45) plt.colorbar() plt.show()
target = ['睡眠时长','睡眠质量','睡眠障碍'] df_new.drop(columns=['ID'],inplace=True)
df_new.drop(columns=['血压'],inplace=True)
for i in range(len(target[:2])): y = df_new[target[i]] X = df_new.iloc[:,~df_new.columns.isin(target)] model = RandomForestRegressor() model.fit(X,y) print('在'+ target[i] + '作为因变量时,各因素重要性为:') plt.figure(figsize=(8,8)) plt.subplot(2,1,i+1) plt.imshow(model.feature_importances_.reshape(-1,1)) plt.yticks(range(len(X.columns.tolist())),X.columns.tolist()) plt.xticks(range(1)) plt.xlabel(target[i]) plt.colorbar() plt.show()
y = df_new[target[2]] X = df_new.iloc[:,~df_new.columns.isin(target)] model1 = RandomForestClassifier() model1.fit(X,y) plt.imshow(model1.feature_importances_.reshape(-1,1)) plt.yticks(range(len(X.columns.tolist())),X.columns.tolist()) plt.xticks(range(1)) plt.xlabel(target[2]) plt.colorbar() plt.show()
plt.figure(figsize=(4,8)) sns.boxplot(x='性别',y='身体活动水平',palette='Set3',data=df_new) plt.title('不同性别身体活动水平的箱型图分析',fontsize=15) plt.show()
plt.figure(figsize=(4,8)) sns.boxplot(x='性别',y='压力水平',palette='Set3',data=df_new) plt.title('不同性别压力水平的箱型图分析',fontsize=15) plt.show()
lt.figure(figsize=(4,8)) sns.boxplot(x='性别',y='心率',palette='Set3',data=df_new) plt.title('不同性别心率的箱型图分析',fontsize=15) plt.show()
plt.figure(figsize=(12,8)) sns.boxplot(x='性别',y='高压',palette='Set3',data=df_new) sns.boxplot(x='性别',y='低压',palette='Set3',data=df_new) plt.title('不同性别血压的箱型图分析',fontsize=15) plt.show()
X = df_new.drop(columns=['睡眠障碍']) y = df_new[['睡眠障碍']] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, train_size=0.7, random_state=42)
model2 = xgboost.XGBClassifier() model2.fit(X_train, y_train)
y_pred = model2.predict(X_test)
df_new['睡眠障碍'].unique()
cm = confusion_matrix(y_test, y_pred)
label_mapping = {0:'失眠',1:'无',2:'睡眠呼吸暂停'}
# 输出混淆矩阵 for i, true_label in enumerate(label_mapping): row = '' for j, pred_label in enumerate(label_mapping.values()): row += f'{cm[i, j]} ({pred_label})\t' print(f'{row} | {true_label}') print(classification_report(y_test, y_pred,target_names=['失眠','无', '睡眠呼吸暂停'])) # 输出混淆矩阵
print("Accuracy:")
print(accuracy_score(y_test, y_pred))
label_names = ['失眠','无', '睡眠呼吸暂停']
cm = confusion_matrix(y_test, y_pred)
# 绘制混淆矩阵图 fig, ax = plt.subplots() im = ax.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues) ax.figure.colorbar(im, ax=ax) ax.set(xticks=np.arange(cm.shape[1]), yticks=np.arange(cm.shape[0]), xticklabels=label_names, yticklabels=label_names, title='Confusion matrix', ylabel='True label', xlabel='Predicted label') # 在矩阵图中显示数字标签 thresh = cm.max() / 2. for i in range(cm.shape[0]): for j in range(cm.shape[1]): ax.text(j, i, format(cm[i, j], 'd'), ha="center", va="center", color="white" if cm[i, j] > thresh else "black") fig.tight_layout() plt.show()
四、课程设计总结:
- 通过对包含性别、年龄、职业、睡眠时间、睡眠质量、身体活动水平、压力水平、BMI类别、血压、心率、每日步数以及是否有睡眠障碍等细节的数据集进行分析和挖掘,我们得到了以下有益的结论:
- 不同性别、年龄和职业群体在睡眠时间和睡眠质量方面存在差异,需要针对不同群体制定个性化的睡眠管理措施。
- 身体活动水平与睡眠质量密切相关,适度的身体活动可以促进良好的睡眠。
- 压力水平对睡眠质量有重要影响,学会有效应对压力和情绪管理可以改善睡眠。
- BMI类别、血压和心率与睡眠质量存在关联,注意身体健康和生活习惯对于睡眠的重要性。
- 每日步数与睡眠质量呈正相关,保持适度的身体活动有助于改善睡眠。
这些结论有助于我们深入了解睡眠质量的多个维度和影响因素,为个体提供更准确、全面的睡眠管理建议,帮助人们改善睡眠质量和促进整体健康。
- 在完成睡眠质量分析的课程设计过程中,我获得了以下收获:
- 掌握了针对多个睡眠相关因素进行数据分析和挖掘的方法和技巧,增强了数据分析的能力。
- 对不同要素之间的关联性和影响因素有了更深入的理解,为个性化的睡眠管理提供了更全面的视角。
- 加强了对睡眠障碍的认识,对睡眠问题的预防和干预有了更清晰的认识。
改进的建议:
- 在数据分析过程中,可以尝试更多的统计方法、机器学习算法和数据可视化技巧,以获取更全面、准确的睡眠质量分析结果。
- 需要更多关于睡眠质量的数据来源,特别是实时睡眠监测数据,以提高分析的准确性和实用性。
- 加强与医疗机构、专业人士的合作,如医生或睡眠专家,以获取更专业的睡眠质量评估和建议,提供更全面和个性化的睡眠管理服务。
总的来说,通过对该数据集进行分析,我们得出了多个有益的结论。这些结论帮助我们深入了解睡眠质量的多个维度和影响因素,并为个体提供更准确、全面的睡眠管理建议。在完成课程设计过程中,我获得了数据分析和睡眠健康方面的实践经验,加深了对睡眠问题的认识。为进一步完善分析方法和数据源,建议探索更多的统计方法、机器学习算法和数据可视化技巧,同时加强与专业人士的合作,以提供更专业和个性化的睡眠管理服务。这样可以更好地改善人们的睡眠质量,促进整体健康和生活质量的提升。