2021中科大软件学院 绝对是最内卷的一年,400分以上据可靠统计已经有419人。好在中科大还有较高单科划线的传统,总分不但要过复试线,单科线也需要过线才能顺利进入复试,除此之外中科大软件学院一向重视数学和计算机专业考试,所以这就为部分总分处于尴尬370-390区间但数学和专业偏高的考生看到了生的希望。是的,博主我也是处于这尴尬的分数区间内。
那么与其焦虑的等待和被群里的各种搞心态,不如主动的去分析进复试的概率,好不太绝望或是有个心里准备。
下面开始进入正题****************************************************************************************************
既然数学和专业单科最终划线未知,那么就有了可分析的对象,这时很容易想到应该对单科划线的分数区间建立概率分布。
根据群里的消息和其他知乎等非官方渠道,数学单科划分极大可能出现在105--115分区间,由于数学普遍都高分,难以很好卡人,但专业课不同,卡人还是有那么一点狠的,不妨假设专业分数划线在105--120区间内,那么就可以开始对数学和专业分数划线区间建立概率分布了:
(ps:这是我预估的划线的概率分布,当然有我主观因素,可能不是很准确,之所以数学107分开始概率变高,这来源于群里消息)
注:为方便定义分布,每个分数段对应的比例都是在0-1范围取值(如专业课115分可以在0-1范围内取比例值,这里取了0.75),之后再归一化,使区间内比例和为1,即转换为概率
有了概率分布后,接下来可以开始建模并计算出分数390--370区间内各分数段过复试线的概率了!建模思路并不复杂:
数学划线区间是105--115分,共10个分数段,专业划线区间是105--120分,共15个分数段,那么数学划线和专业划线的排列组合就有10*15=150种,对每一种组合(如数学划线110,专业划线115),我们只需要从1560名考生(今年考生人数)中去掉两科中一科没达到划线成绩的考生,然后从剩余考生中找到排名第600名的考生成绩作为该组合的复试分数线(这里600名是因为有消息说扩张,不妨假设复试名额为前600名)。对所有组合都进行上述操作,我们就可以得到每一种组合的复试分数线了。
假设分数线划到某组合的数学的概率为X,专业的概率为Y,那么每一种组合的概率P为:
P = X * Y
经过上面的处理后,就得到了每一种组合的复试分数线和划线概率。
接下来就可以开始计算总分390--370区间内各分数段过复试线的概率了,假设待计算的总分为 S , S 过复试线的概率为PS,PS初始为0,将S与各组合复试线大小比较,如果S大于或等于该组合的复试线,就把该组合概率P加到PS中,即
PS += P (if S>=组合的复试线)
(注意上面概率统计是统计一般情况下的概率,即不针对某个人具体各科分数去统计进复试概率,也就是说总是认为存在某个总分S,当它大于或等于该组合的复试线时,其各科也不小于该组合的划线。若要具体针对某个人各科分数计算过复试概率,那么计算概率的方法应改为当这个人总分大于或等于该组合的复试线且数学和专业单科不小于该组合划线时才把该组合概率P加到PS中!)
完成这些操作后我们就得到该分数过复试线的一般概率了!下图计算了分数360--390区间内各分数段过复试线的一般概率:
很好,对于375的我来说过线的一般概率是51.9%,额一半的概率,不说了我去烧香了~
附代码(python):
"""
licene:玮涛
2021/3/3
"""
import xlrd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
xlsxPath='studentScore.xlsx'#全部考生成绩统计excel表文件路径
mathFilterScoreRank=(105,115)#左闭右闭,数学划线分数区间
mathFilterProportion=[0.2,0.2,0.50,0.52,0.55,0.68,0.6,0.5,0.4,0.35,0.3]#数学各分数段划线概率(比例),每个元素取值范围0-1
majorFilterScoreRank=(105,120)#左闭右闭,专业划线分数区间
majorFilterProportion=[0.2,0.2,0.25,0.3,0.35,0.4,0.45,0.46,0.47,0.5,0.75,0.65,0.6,0.5,0.45,0.3]#专业各分数段划线概率(比例),每个元素取值范围0-1
totalEnrollment=600#计划复试人数
#输出各分数进复试的概率
outPutScore=[390,385,380,375,370,365,360]
#将划线比例转换为概率
def changeProportionToProbability(listProportion):
sumProportion=sum(listProportion)
listProbability = [value/sumProportion for value in listProportion]
return listProbability
def read_excel(xlsxPath):
# 打开文件
workBook = xlrd.open_workbook(xlsxPath)
#按索引号获取sheet内容
sheet1_content1 = workBook.sheet_by_index(0)# sheet索引从0开始
content=[]
for rowIndex in range(sheet1_content1.nrows):
value=sheet1_content1.row_values(rowIndex)[2:4]#数学分数,专业分数
value.append(sheet1_content1.cell_value(rowIndex, 5))#append 总分数
content.append(value)
return content
def calScoreLineProbability(content,mathFilterProbability,majorFilterProbability):
minScores=[]
#仅保留过线的分数
for mathScore in range(mathFilterScoreRank[0],mathFilterScoreRank[-1]+1):
for majorScore in range(majorFilterScoreRank[0],majorFilterScoreRank[-1]+1):
# print(mathScore,majorScore)
filterTotalScore=[]#保留过线的人的总分
for rowValue in content:
if rowValue[0]>=mathScore and rowValue[1]>=majorScore:
filterTotalScore.append(rowValue[2])
if len(filterTotalScore)>=totalEnrollment:
minScores.append(filterTotalScore[totalEnrollment-1])
else:
minScores.append(filterTotalScore[-1])
outPutScoreProbability=[0 for _ in outPutScore]
#对outPutScore各个分数段计算入线概率
majorFilterLen = len(majorFilterProportion)
for outIndex,outScore in enumerate(outPutScore):
for minIndex,minScore in enumerate(minScores):
if outScore>=minScore:
outPutScoreProbability[outIndex]+=(mathFilterProbability[minIndex//majorFilterLen]*majorFilterProbability[minIndex%majorFilterLen])
return outPutScoreProbability
if __name__ == '__main__':
#将比例转换为概率
mathFilterProbability = changeProportionToProbability(mathFilterProportion)
majorFilterProbability = changeProportionToProbability(majorFilterProportion)
#计算过线概率
content=read_excel(xlsxPath)
outPutScoreProbability=calScoreLineProbability(content,mathFilterProbability,majorFilterProbability)
print("Probability:", outPutScoreProbability)
outPutScoreProbability=[float('%.4f' % x) for x in outPutScoreProbability]#修改精度
#绘图********************************************************************************************
#绘制概率分布图
fig1 = plt.figure(2)
plt.subplot(211)
x=[str(mathScore) for mathScore in range(mathFilterScoreRank[0],mathFilterScoreRank[-1]+1)]
#y=[float('%.3f' % p ) for p in mathFilterProbability]
y=mathFilterProportion
plt.plot(x,y,color='g',label="math", markerfacecolor='r', marker='o')
for a, b in zip(x, y):
plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
plt.legend()
plt.grid() # 添加网格
# subplot(211)把绘图区域等分为2行*1列共两个区域,然后在区域1(上区域)中创建一个轴对象
plt.subplot(212) # 在区域2(下区域)创建一个轴对象
x=[str(majorScore) for majorScore in range(majorFilterScoreRank[0],majorFilterScoreRank[-1]+1)]
#y = [float('%.3f' % p) for p in majorFilterProbability]
y=majorFilterProportion
plt.plot(x,y,color='b',label="major", markerfacecolor='r', marker='o')
for a, b in zip(x, y):
plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
plt.legend()
plt.grid() # 添加网格
# 绘制各分数过复试线概率
fig2 = plt.figure(1)
# 添加数据标签
def add_labels(rects):
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height, height, ha='center', va='bottom')
# 柱形图边缘用白色填充,纯粹为了美观
rect.set_edgecolor('white')
rect=plt.bar(outPutScore, outPutScoreProbability,width=3.5,color='rgb')
add_labels(rect)
plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(5))
plt.title(u'Probability of each score entering the retest')
plt.show()