学生成绩排名预测(DC)

去年大数据分析课程的选题项目,最近考研不顺整理之前的杂碎半成品等丰富一下简历,准备找工作二战了,真是一个悲伤的现实,唉。

原题目链接:DC竞赛:学生成绩排名预测 【已挂】

相关数据:https://github.com/typeisgod/CSDN

题目背景和意义:

    我们希望通过借助大数据相关的挖掘技术和基础算法,从学生的校园行为数据中,根据学生出入图书馆的次数,以及借书和消费情况等,挖掘用户作息规律、兴趣爱好等,精准地预测学生之间的相对排名。通过对这些日常行为的建模来预测学生的学业成绩,发现学生成绩和日常校园行为之间的潜在关系,可以实现提前预警学生的异常情况,并进行适当的干预,因而对学生的培养、管理工作将会起到极其重要的作用。

题目描述:

    本次竞赛中,我们将从某高校的某个学院随机抽取一定比例学生,提供这些学生在三个学期的图书馆进出记录、一卡通消费记录、图书馆借阅记录、以及综合成绩的相对排名。这一部分数据将作为训练数据。我们从另外的某学院随机抽取一定比例的学生,然后提供他们在三个学期的图书馆进出记录、一卡通消费记录、图书借阅记录、以及前两个学期的成绩排名。第三学期的成绩排名作为预测目标。

提供文件:

    训练\成绩.txt。训练集的成绩文件,包含学期、学号、以及相对排名

    训练\借书.txt。训练集的图书借阅信息,包含学期、学号、书号、日期

    训练\图书门禁.txt。 训练集的图书门禁进入,包含学期、学号、日期、时间

    训练\消费.txt。训练集的消费数据,包含学期、学号、地点、日期、时间、金额

    测试\成绩.txt。 测试集的成绩文件。字段同上 测试\借书.txt。 测试集的图书借阅信息。字段同上

    测试\图书门禁.txt。 测试集的图书门禁进入。字段同上

    测试\消费.txt。 测试集的消费数据。字段同上

评估标准:

    算法通过衡量预测排名和实际排名的Spearman相关性,为[0,1]之间的值,值越大,表示越相关,排名的预测就越准确。若要考虑n个学生的排名,学生i的预测排名为pi,而实际的排名为ri,di = pi - ri,那么

                                                     

本数据统计模型(最后评分并不是很高,仅供参考):

后来觉得次数不一定决定成绩,应该还有稳定性。后来对门禁和借书计算了每个学期的月均值、月方差、日均值、日方差(第一、三学期五个月 第二学期六个月 每个月三十一天计算),扩展到了317维。之后归一化到了[0,1]之间。

我做的工作:提取成绩、图书馆门禁、借书;分析预测

汪东启的工作:提取图书类别(供借书使用)、消费;多维合并

一.书籍信息读取、检查与存储(汪东启)

  0. 图书类别.txt 文件预览与格式:

  1.文件的预读取与检查(test_check_book.py)

# -*- coding: utf-8 -*-
"""
Created on Mon May  7 14:53:24 2018

@author: wangdongqi

读取书籍信息,检查数据中可能出现的问题
"""

Book = dict()
ClassNum = []
err = []

with open('图书类别.txt', encoding = 'utf-8') as f:
    f.readline();
    for line in f:
        (BookNumber, BookClass) = line.split('\t');
        if BookNumber not in Book.keys():
            Book[BookNumber] = [BookClass]
        else:
            Book[BookNumber].append(BookClass)
            print(BookNumber)
            err.append(BookNumber)
        if BookClass not in ClassNum:
            ClassNum.append(BookClass);

# 测试重复的那些数据是否有变化
err_list = []
for i in err:
    tmp_list = Book[i]
    tmp = tmp_list[0]
    for j in tmp_list[1:]:
        if j != tmp:
            err_list.append(i)
            break
# 结论:所有重复的数据的信息相同,对结果无影响



2.数据提取(test_read_book)

首先导入文件,将文件按行切分(split,代码使用replace直接替换)为BookNumber和bookclass,检查BookNumber是否为数字(防止图书编号中出现错切分的其他符号),如果是则放入字典BookInfo中;同时BookClass为list类型,用于存放一共出现的bookclass的种类数(文件中只有42种,但在其他文件中出现未在字典中的书籍,收集作为第43类)。最后通过pickle.load函数将BookInfo和BookClass数组存放下pkl中。

# -*- coding: utf-8 -*-
"""
Created on Mon May  7 15:49:55 2018

@author: wangdongqi

读取书籍信息
"""
BookInfo = dict()
errInfo = dict()
BookClass = []

with open('图书类别.txt', encoding = 'utf-8') as f:
    f.readline();
    for line in f:
        line = line.replace('\n', '')
        (BookNumber, bookclass) = line.split('\t');
        if not BookNumber.isdigit():
            errInfo[BookNumber] = bookclass
            continue
        
        BookInfo[BookNumber] = bookclass
        if bookclass not in BookClass:
            BookClass.append(bookclass)
        

# 排序
BookClass.sort()

# 打印42类书的类名
for i in BookClass:
    print(i, end = ' ')
    


# 保存信息
import pickle

# 保存
pickle.dump(BookInfo, open('BookInfo.pkl', 'wb'))
pickle.dump(BookClass, open('BookClass.pkl', 'wb'))

# 读取
BookInfo = pickle.load(open('BookInfo.pkl', 'rb'))
BookClass = pickle.load(open('BookClass.pkl', 'rb'))






二.成绩、图书馆门禁、借书提取(Type) (pre.py)

0.文件预览与格式

1.

依次读入成绩、图书馆门禁、借书三个txt文件,分别存入file_rank、file_ibrary、file_borrow变量中。

(1)file_rank:

每次读取一行(readline()),对每行未使用split等切割,而是手动实现的“字符切割”:(代码25-39行)

   pre为某个字符段(数字段)的开始,初始化0,end为某个字符段(数字段)的结束,当没有扫描到行末尾时循环查找,当下标为pre的字符不为空(/t)时,end一直循环到下一个空(/t)或末尾的上一个字符(数字段结尾),然后取[pre:end](end不取),依次取数组段直到pre到行末,得到的多个数字段放入temp中,并合并到总data里(二维数组),读取下一行。全部读完后以学号为主key,学期为副key对data排序:data=sorted(data,key=lambda x:(x[1],x[0]))

此时data格式为:

学期 学号 排名

(2)file_library:

新增 月平均 月方差 月最大 月最小 
        日平均  日方差 日最大 日最小
        06-22 小时点次数

(PS:月平均:平均每个月去图书馆的门禁次数,月最大:最多一个月去的门禁次数,其他同理

小时点次数:这个学期每个小时门禁次数汇总情况,并非每天每小时的次数)
新增共 25 维(最开始的模型只有下标3 新增4-28)

下标(从0开始) 0 1 2 3 4-7 8-11 12-28
维/属性 学期 学号 排名 本学期图书馆门禁次数 月平均 月方差 月最大 月最小 日平均  日方差 日最大 日最小 06-22 小时点次数

从file_library提取的数据共26维(data下标对应3-28),建立一个和data等长(len(data)的)三维数组data3,用于存放每个学期每个学生每个月每天的图书馆门禁次数。

data3=np.zeros(shape=(len(data),6,31)).tolist();

用split('\t')分割每行为四个数字段,分别对应学期、学号、日期、时间。(代码中ent为回车符),通过学期和学号即可计算出对应data中的下标:index=(sid-1)*3+seme-1; (sid=学号,seme=学期)。

从时间提取出前二位数为小时hour([0:2]),同理从日期中提取出月份month和天day。并根据学期将每个学期的月份最低数规划到0,分别将每个月每天的次数存入data3中,将每小时(06时-22时)的门禁次数写入data中。(此上代码75-90行)

统计完毕后计算月均值mmean、月最大mmax、月最大mmax、月最小mmin、月方差mvar、日均值mmean、日最大mmax、日最大mmax、日最小mmin、日方差mvar并放入data的[4:12]中。

(3) file_borrow:(使用 一 中已经写好的pkl作为字典索引类别)

下标(从0开始) 0 1 2 3-28 29-71 72-75 76-79
维/属性 学期 学号 排名 file_library提取的属性列 每类书的借阅总次数(本数) 月平均  月方差 月最大 月最小 日平均  日方差 日最大 日最小

读入pkl和file_library类似地统计每个人每个学期每类书(43类,用ABCD等表示)的总次数,和所有类型书的借阅月总次数、最大、最小、方差、日同理。

代码pre.py:

# -*- coding: utf-8 -*-
"""
Created on Mon May  7 13:28:12 2018

@author: Type真是太帅了
"""
import numpy as np
import pickle
file_rank=open('成绩.txt','r')
file_library=open('图书馆门禁.txt','r')
file_borrow=open('借书.txt','r')
file_consume=open('消费.txt','r')
#file_type=open('图书类别.txt','r')

'''
 学期 学号 图书馆门禁次数 食堂总消费 交通总消费 宿舍总消费 超市总消费 书类别  排名
'''  
data=[]
'''
读入成绩
'''
line = file_rank.readline()
line = file_rank.readline()#直接读取第二行数据 
while line:  
    temp=[]
    pre=0
    while pre<len(line)-2: #对于每行line的每个字符 将其转化为数字形式并存储于数组中 最后\n两个字符不读
        if line[pre]!='\t':
            end=pre+1
            while end<len(line)-1:
                if line[end]=='\t':
                    temp=temp+[int(line[pre:end])]
                    pre=end+1
                    break
                else:
                    end=end+1
        else:
            pre=pre+1
            end=pre+1
    data=data+[temp]
    line = file_rank.readline()  
'''
以学号为主key 学期为负key进行排序
'''
data=sorted(data,key=lambda x:(x[1],x[0]))

'''
读入图书馆门禁次数(学期计)
'''

'''
新增 月平均 月方差 月最大 月最小 
     日平均  日方差 日最大 日最小
    06-22 小时点次数
    共 25 维
0    1    2    3    4567 891011      12-28 29-71
学期 学号 排名  总数 月   日          06-22  1-43
'''
line = file_library.readline()
line = file_library.readline()#直接读取第二行数据 
zero26=np.zeros(26,int).tolist();#新建26维列表
i=0
while i<len(data):
    data[i]=data[i]+zero26;
    i=i+1

data3=np.zeros(shape=(len(data),6,31)).tolist();#统计每天的次数 每个月取31天 
'''1/3学期 data3[index][0-4]表示 9-1月 9~0 10~1 11~2 12~3 1~4
     2学期 data3[index][0-5]表示 2-7月
'''
n_1=5;#1 3 学期 5个月
n_2=6;# 2 学期 6个月
while line:
    read
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值