【Python】数据分析优秀案例&项目经历-用数据分析能力构建高分学生人群画像

【Python】数据分析优秀案例&项目经历-用数据分析能力构建高分学生人群画像又到了每周末知识分享环节。这次给大家分享的是kaggle上的一个非常有意思的项目,我们希望从中发现学生的测验表现与标签之间的关系。总之,本次项目干货满满,除了通过绘图等常规手段之外,也用到了t检验等假设检验的方法来力求让结论更具说服力。……

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

(有需要完整代码和数据的可以评论留下你的邮箱,我会尽快发送给你!)

大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师。欢迎大家跟我一起走进数据分析的世界,一起学习!

感兴趣的朋友可以关注我或者我的数据分析专栏,里面有许多优质的文章跟大家分享哦。


提问:大家觉得成绩的高低都和哪些因素有关呢?男女生之间在科目上是否有明显的差异呢?

前言

又到了每周末知识分享环节。这次给大家分享的是kaggle上的一个非常有意思的项目,我们希望从中发现学生的测验表现与标签之间的关系。

总之,本次项目干货满满,除了通过绘图等常规手段之外,也用到了t检验等假设检验的方法来力求让结论更具说服力。

下面开始项目的正式介绍。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots 
import scipy.stats as stats
import scipy
from scipy.stats import ttest_ind
from scipy.stats import chisquare
from scipy.stats import chi2_contingency
import numpy as np

1.项目介绍

1.1 项目介绍

本文数据集来自竞赛平台Kaggle,共拥有1000条数据,并已经过脱敏处理。数据集共包含9个标签,我们希望从中发现学生的测验表现与标签之间的关系。

1.2 数据介绍

以下标签解释:

  • Unnamed:学生编号
  • race/ethnicity:种族
  • parental level of education:父母受教育程度
    • bachelor’s degree: 学士学位
    • some college:大学肄业
    • master’s degree:硕士学位
    • associate’s degree:副学士
    • high school:高中
    • some high school:高中肄业
  • lunch:午餐花费
    • Standard: 标准
    • free/reduced: 学校免费提供或低于标准
  • test preparation course: 是否完成与考试相关课程
    • none: 未完成
    • completed: 完成
  • math percentage:数学成绩
  • reading score percentage: 阅读成绩
  • writing score percentage: 写作成绩
  • sex: 性别

2. 数据整理

data = pd.read_csv('Student Performance new.csv')
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 9 columns):
 #   Column                       Non-Null Count  Dtype  
---  ------                       --------------  -----  
 0   Unnamed: 0                   1000 non-null   int64  
 1   race/ethnicity               1000 non-null   object 
 2   parental level of education  1000 non-null   object 
 3   lunch                        1000 non-null   object 
 4   test preparation course      1000 non-null   object 
 5   math percentage              1000 non-null   float64
 6   reading score percentage     1000 non-null   float64
 7   writing score percentage     1000 non-null   float64
 8   sex                          1000 non-null   object 
dtypes: float64(3), int64(1), object(5)
memory usage: 70.4+ KB

本数据集共包含1000条数据,无数据缺失,数据类型包括整数,浮点数与对象类型

data.sample(n=5) # 随机抽取数据查看
Unnamed: 0 race/ethnicity parental level of education lunch test preparation course math percentage reading score percentage writing score percentage sex
113 113 group D some college standard none 0.51 0.58 0.54 F
342 342 group B high school standard completed 0.69 0.76 0.74 F
475 475 group D bachelor’s degree standard completed 0.71 0.76 0.83 F
181 181 group C some college free/reduced none 0.46 0.64 0.66 F
41 41 group C associate’s degree standard none 0.58 0.73 0.68 F
# 数据Unnamed列为学生编号,我们将其舍弃
data = data.drop(columns=['Unnamed: 0'], axis=1)

对于部分标签,存在多个变量, 我们需要对其进一步观察

labels = ['race/ethnicity', 'parental level of education', 'lunch', 'test preparation course']
for label in labels:
    print(f'标签{ 
     label}情况:')
    print(f'共有{ 
     data[label].nunique()}个变量,分别为')
    print(data[label].unique())
    print('*'*20)
标签race/ethnicity情况:
共有5个变量,分别为
['group B' 'group C' 'group A' 'group D' 'group E']
********************
标签parental level of education情况:
共有6个变量,分别为
["bachelor's degree" 'some college' "master's degree" "associate's degree"
 'high school' 'some high school']
********************
标签lunch情况:
共有2个变量,分别为
['standard' 'free/reduced']
********************
标签test preparation course情况:
共有2个变量,分别为
['none' 'completed']
********************

对于分数标签,我们增加一列平均分(average score)

average_score = data[['math percentage', 'reading score percentage', 'writing score percentage']].mean(axis=1)
data.insert(7, 'average score', np.round(average_score, 2))

在此基础上,我们对average_score进行分箱,以0-59,60-69,70-79,80-89,90-100为分隔,将分数分为对应的F, D, C, B, A。

performance_level = pd.cut(data['average score'], bins=[0, 0.59, 0.69, 0.79, 0.89, 100], 
                                   labels=['F', 'D', 'C', 'B', 'A'] )
data.insert(8, 'performance level', performance_level)
data.groupby('sex')['sex'].count()
sex
F    518
M    482
Name: sex, dtype: int64

本数据集男女比例为:48.2%比51.8%。我们认为其基本符合男女比例在美国的分布,为了进一步进行验证,我们可以引入卡方拟合度检验:

  • H0:在选取数据集时,男性与女性被选中的概率皆为50%
  • H0:上述概率不成立
expected_number = [500, 500] # 理论上1000个样本中男女人数
observed_number = [482, 518] # 实际观察到的男女人数
result = stats.chisquare(f_obs=observed_number, f_exp=expected_number)
print(f'卡方拟合度检验的P值为:{ 
     result[1]}')
卡方拟合度检验的P值为:0.25494516431731784

据此,我们可以认为,如果从男女比例出发,这份数据为随机抽取。

至此,数据整理结束,我们再次查看此时的数据情况。

data.sample(n=5)
race/ethnicity parental level of education lunch test preparation course math percentage reading score percentage writing score percentage average score performance level sex
801 group C some high school standard completed 0.76 0.80 0.73 0.76 C M
200 group C associate’s degree standard completed 0.67 0.84 0.86 0.79 C F
417 group C associate’s degree standard none 0.74 0.73 0.67 0.71 C M
629 group C some high school standard completed 0.44 0.51 0.55 0.50 F F
944 group B high school standard none 0.58 0.68 0.61 0.62 D F

3. 学生成绩分析

3.1 学生整体成绩分布

fig = plt.figure(figsize=(5,10))
sns.set_style('darkgrid')
subjects = ['math percentage', 'reading score percentage', 'writing score percentage', 'average score']
color = ['green', 'blue', 'orange', 'purple']
column = 1
for subject in subjects:
    plt.subplot(len(subjects), 1, column)
    sns.kdeplot(data=data, x=subject, color=color[column - 1])
    column = column + 1
plt.tight_layout()
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zWSG3rHk-1639906825714)(output_26_0.png)]

整体来看,各学科成绩与平均成绩都符合正态分布,我们以样本均值加减两个标准差,可以得到约95%的学生成绩分区间:

lower_bound = data['average score'].mean() - data['average score'].std()*2
upper_bound = data['average score'].mean() + data['average score'].std()*2
print(f'95%的学生成绩分布下限:{ 
     lower_bound}')
print(f'95%的学生成绩分布上限:{ 
     upper_bound}')
95%的学生成绩分布下限:0.3924529214957264
95%的学生成绩分布上限:0.9627870785042743

即约有95%的学生成绩分布在0.39分至0.96分之间。

3.2 不同学科成绩间的关联度以及不同学生人群擅长科目

我们数据集中共拥有三门学科,分别为读写与数学。我们可以分别将其看做**“文科”“理科”**,并分别查看不同学科成绩之间的关联度。

data[subjects].corr()
math percentage reading score percentage writing score percentage average score
math percentage 1.000000 0.817580 0.802642 0.918442
reading score percentage 0.817580 1.000000 0.954598 0.970143
writing score percentage 0.802642 0.954598 1.000000 0.965643
average score 0.918442 0.970143 0.965643 1.000000
fig = plt.figure()
plt.subplot()
sns.heatmap(data[subjects].corr(), annot=True)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWpxCHDy-1639906825715)(output_33_0.png)]

从上面的表与图中,我们可以看出,“文科”学科成绩之间的相关程度,要高于“文科”与“理科”学科成绩之间的相关程度。而且考虑到本数据集中“文科”的科目要多于“理科”的科目,“文科”成绩与平均成绩的相关程度更高。

一般意义而言,社会认为上男生更擅长理科,而女生更擅长文科。我们将使用统计学验证这一看法是否适用于本数据集。

我们引入卡方独立性检验,判断性别与学科掌握程度方面是否是独立不相关的。

  • H0:数学成绩与性别无关系。
  • H1: 数学成绩与性别有关系。
# 将数学成绩进行分箱,分箱方式与前述对平均成绩的分箱方式相关
math_grading = pd.cut(data['math percentage'], bins=[0, 0.59, 0.69, 0.79, 0.89, 100], 
                                   labels=['F', 'D', 'C', 'B', 'A'] )
crosstab = pd.crosstab(math_grading, data['sex'])
# 引入卡方独立性检验
result = stats.chi2_contingency(crosstab)
print(f'p值为:{ 
     result[1]}')
p值为:3.052111718576621e-05

**原假设不成立,即学生的数学成绩与性别并不独立。**在此基础上,我们进一步查看不同性别下,学生在数学科目的表现。

data.groupby('sex')[['math percentage']].agg([np.mean, np.median])
math percentage
mean median
sex
F 0.636332 0.65
M 0.687282 0.69
fig, ax  = plt.subplots(1,2, figsize=(10, 5))
sns.boxplot(data=data, y='math percentage', x='sex', palette='summer', ax=ax[0])
sns.histplot(data=data, x='math percentage', hue='sex', fill=True, ax=ax[1], stat='probability')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qV7fOTYc-1639906825716)(output_41_0.png)]

在数学科目的平均分以及中位数两大统计指标上,我们可以看出,男性在该科目的确占有一定优势。两者的数学成绩分布大致都符合正态分布,但男性在样本方差明显更小,且在高分部分,男性出现的概率更大——男性在数学上的整体表现,要优于女性。

下面我们继续观察男女性在文科科目上的表现,在这里,我们选取writing score percentage标签,做为研究对象。

data.groupby('sex')[['writing score percentage']].agg([np.mean, np.median])
writing score percentage
mean median
sex
F 0.724672 0.74
M 0.633112 0.64
fig = px.histogram(
    data, x='writing score percentage', 
    marginal='box', opacity=0.6,
    color='sex',
    histnorm='probability',
    title='男生与女生在文科上的表现',
    template='plotly_white'
)

fig.update_layout(barmode='overlay', width=800)
fig.show()

从所估计的概率密度图上看,女生在writing score percentage的高分领域,女性出现的概率要远高于男生,而在低分领域则正好相反。综合来看男生,男生的确更擅长理科,而女生则相反。

3.3 高分学生人群画像

3.3.1 父母学历

下面我们分析高分(均分高于90分)考生的画像,首先我们探究高分与父母受教育程度间的关系。

honor_students = data.loc[data['average score']>=0.9] # 选取均分高于0.9的学生,组成子数据集honor_students
honor_count = honor_students['parental level of education'].value_counts().sort_index()
total_count = data['parental level of education'].value_counts().sort_index()

fig = make_subplots(rows=1, cols=2, specs=[[dict(type='domain'),{ 
   'type':'domain'}]])

fig.add_pie(
    values=total_count.values, hole=0.4, labels=total_count.index, 
            row=1, col=1, name='整体学生父母受教育程度'
)
fig.add_pie(
    values=honor_count.values, hole=0.4, labels=honor_count.index, 
            row=1, col=2, name='高分学生父母受教育程度'
)

fig.update_layout(
    title_text="学生父母受教育程度",
    annotations=[dict(text='整体父母', x=0.15, y=0.5, font_size=20, showarrow=False),
                 dict(text='高分父母', x=0.85, y=0.5, font_size=20, showarrow=False)],
    width=900
)
fig.show()

从上图所示,我们发现,高分考生父母的教育程度,要高于整体考生父母的教育程度,其中高分考生父母拥有副学士、学士、硕士的比例,相较于整体考生,分别从22.9%, 11.8%, 5.9%上升至31.5%, 24.1%, 11.1%。

整体来看,高分学生的父母,约有90%都曾接受过大学教育。

不仅仅是高分学生父母的所受教育程序较高,实际上,在本数据集中,所有学生的平均分,皆与父母的教育程度正相关。下表给出了不同教育程度的父母,以及对应考生群体平均分。其中,其中学历为硕士与高中的父母,子女的平均分分别为73分及63分。

data.groupby('parental level of education')['average score'].mean().sort_values()
parental level of education
high school           0.631224
some high school      0.650726
some college          0.684469
associate's degree    0.695586
bachelor's degree     0.719492
master's degree       0.735763
Name: average score, dtype: float64
parents = data['parental level of education'].unique()
sample_data = []
for parent in parents:
    member = data[data['parental level of education'] == parent].sample(n=30, random_state=1)
    sample_data.append(member)
parent_data = pd.concat(sample_data, axis=0)

fig = px.scatter(
    parent_data, x='math percentage', y='writing score percentage',
    color='parental level of education',
    size='average score',
    title='父母教育程度对学生成绩影响',
    template='plotly_dark'
)
fig.show()

上述气泡图抽取各个教育水平的父母各30名,并观察其子女成绩表现。不难看出,学生的成绩表现与父母受教育程度成正相关关系,即父母受教育程度越高,子女的学业表现越好。

为了进一步在统计学上证明这一点,我们引入卡方独立性检验:

  • H0: 学生成绩表现与父母受教育程序无关
  • H1: 学生成绩表现与父母受程序程度相关
crosstab = pd.crosstab(data['parental level of education'], data['performance level'])
result = stats.chi2_contingency(crosstab)
if result[1] < 0.05:
    print(f'p值为{ 
     result[1]}, 原假设不成立!')
else:
    print(f'p值为{ 
     result[1]}, 原假设成立!')
p值为0.00014895457933147155, 原假设不成立!

结论:对于高分段的学生,其父母所受的教育程度要更高。

3.3.2 学生性别

honor_students.groupby('sex')['sex'].count()
sex
F    40
M    14
Name: sex, dtype: int64

从上图表格中,我们发现高分学生当中,女性的数量要明显多于男性数量。但考虑到在三门科目当中,写作与阅读都偏向于女生所擅长的文科类科目,这对于擅长数学的男生而言,显然是不利的,我们考虑选取一门文科与一门理科,取其均值,查看在这一情况下,高分学生在男女中的分布。

condition = ((data['math percentage']+data['writing score percentage'])/2 >= 0.9)
data[condition].groupby('sex')['sex'].count()
sex
F    35
M    18
Name: sex, dtype: int64

此时,女生仍然相较于男生,仍然拥有更大的优势!

honor_index = honor_students.groupby('sex')['sex'].count().index
honor_value = honor_students.groupby('sex')['sex'].count().values
math_writing_index = data[condition].groupby('sex')['sex'].count().index
math_writing_value = data[condition].groupby('sex')['sex'].count().values
fig = go.Figure(data=[
    go.Bar(x=honor_index, y=honor_value, name='三科均分高于90分', text=honor_value,),
    go.Bar(x=math_writing_index, y=math_writing_value, name='数学写作均分高于90分', text=math_writing_value)
])
fig.update_layout(width=500, height=400)
fig.show()

从我们得到的结果来看,无论是哪种情况,女生高分情况都要远胜于男生,基于此,我们做出一个假设:尽管女生在数学方面整体不如男性,但在高分段,男女生在数学的表现基本一致。

data[data['math percentage']>0.9].groupby('sex')['math percentage'].mean()
sex
F    0.952857
M    0.948621
Name: math percentage, dtype: float64

上表所示为男生与女生在高分段的数学平均成绩。

data[data['math percentage']>0.9].groupby('sex')['math percentage'].std()
sex
F    0.031803
M    0.032373
Name: math percentage, dtype: float64

上表所示为男生与女生在高分段的数学样本方差。

从数学高分段的均值及方差来看,两者都十分接近。为了进一步验证我们的观点,我们引入t 检验,判断两者的均值是否相同。

  • H0: 在高分段,男生与女生在数学方面的均值一致
  • H1: 在高分段,男生与女生在数学方面的均值不一致
honored_male_math = data.loc[(data['math percentage'] >= 0.9) & (data['sex'] == 'M'),'math percentage']
honored_female_math = data.loc[(data['math percentage'] >= 0.9) & (data['sex'] == 'F'),'math percentage']
result = ttest_ind(honored_male_math.values, honored_female_math.values, equal_var=True)
if result[1]>0.95:
    print(f'两者的均值一致,P值为{ 
     result[1]}')
else:
    print(f'两者的均值不一致,P值为{ 
     result[1]}')
两者的均值一致,P值为1.0

从P值所反馈结果来看,女生尽管整体在数学方面不如男生,但在高分段,女生与男生的表,并无明显区别。

结论:高分段,女生比男生要更占优势,而男生的优势科目在高分段,优势并不明显。

结束语

看完这篇,还有更多知识点分享给你哦,自己慢慢找哈,就在下面链接。

推荐关注的专栏

?‍?‍?‍? 机器学习:分享机器学习实战项目和常用模型讲解
?‍?‍?‍? 数据分析:分享数据分析实战项目和常用技能整理

往期内容回顾

? 学习Python全套代码【超详细】Python入门、核心语法、数据结构、Python进阶【致那个想学好Python的你】
❤️ 学习pandas全套代码【超详细】数据查看、输入输出、选取、集成、清洗、转换、重塑、数学和统计方法、排序
? 学习pandas全套代码【超详细】分箱操作、分组聚合、时间序列、数据可视化
? 学习NumPy全套代码【超详细】基本操作、数据类型、数组运算、复制和试图、索引、切片和迭代、形状操作、通用函数、线性代数


关注我,了解更多相关知识!

CSDN@报告,今天也有好好学习

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/179181.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • test.py是什么文件_exe文件反编译源码工具

    test.py是什么文件_exe文件反编译源码工具"java"]//P6DataSourcep6DSource=newP6DataSource(cpDSource)publicclassP6DataSourceextendsP6BaseimplementsDataSource,Referenceable,Serializable{//source是通过构造传入的数据源c3p0或DruidpublicP6DataSource(DataSourcesource)

  • 电脑word文档图标变了怎么办_word图标变成白纸

    电脑word文档图标变了怎么办_word图标变成白纸当我们在使用word文档的时候,可能会遇到word文档图标显示异常的情况,那么这个时候我们该怎么办?下面是学习啦小编整理的word文档图标显示异常的解决方法,供您参考。word文档图标显示异常的解决方法一点击“开始”菜单,输入“运行”并搜索。点击“运行”。输入regedit,然后点击确定。双击打开HKEY_CLASSES_ROOT。找到.docx,鼠标右击,选择删除。用同样的方法依次打开HKEY…

  • 360奇安信天擎卸载不干净_强力卸载奇安信

    360奇安信天擎卸载不干净_强力卸载奇安信人狠话不多,直接上教程!找到软件安装目录下的EntBase.dat文件,比如我的位置是D:\QAX\360Safe\EntClient\conf\EntBase.dat。打开如下:[base]persistent_connetion=closeshow_tip=1net_env=4communication_interval=300[api_frequency]checkupdate=60get_client_tasks=60getconf=60svr_init_info=180u

  • flex 词法分析_c语言词法分析器的简单实现

    flex 词法分析_c语言词法分析器的简单实现为什么80%的码农都做不了架构师?>>>…

    2022年10月28日
  • Vue.js高效前端开发 • 【初识Vue.js】

    1.1Vue概述1.1.1Web前端框架介绍近几年,互联网前端行业发展得依旧迅猛,涌现出了很多优秀的JavaScript框架,同时这些JavaScript框架也正在逐渐改变统的前端开发方式。在这些新出现的JavaScript框架中,最具代表性的框架有Angular.js、React.js和Vue.js。1.1.2MVC和MVVMMVC是著名的设计模式,基本思想是将软件结构分解为Model(模型)、View(视图)和Controller(控制器)三部分组成。Model:主要负责数据处理和

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号