第一阶段工作总结-模型算法尝试

这篇博客总结了作者在第一阶段的工作,主要聚焦于利用LIBFM矩阵分解算法进行学生成绩预测。作者详细介绍了算法的背景、MCMC采样方法,并分享了在Ubuntu环境下训练模型的步骤。此外,还提到了小程序、HTML、CSS框架的学习过程。
摘要由CSDN通过智能技术生成

工作:

这段时间根据群里讨论的算法,打算尝试基于LIBFM矩阵分解进行学生成绩预测,如果要使用libfm,要使用线性回归,同时要清楚是根据学科还是专业来分别建立模型。
同时学习小程序教程。
第一周主要工作是先确定我负责算法方面的工作。观察数据后发现可以将学生的学习行为提取为特征。通过LIBFM矩阵分解算法预测学生成绩。

经过我们团队的商讨,将项目划分为算法设计和界面设计展示两部分,经过分工讨论,我的任务是辅助组长张同学,组员曲同学,参与算法设计,同时与组员成sir一同设计并实现配套的微信小程序项目。

1. 基于LIBFM矩阵分解算法的学生成绩预测

1.1 算法准备前言

这学期刚好创新设计跟随实验室进行了基于LIBFM矩阵分解算法的学生成绩预测,于是产生了将LIBFM矩阵分解算法运用到该项目中的想法。

1.2 LIBFM算法加上MCMC采样算法

在 LIBFM 中,提供了两大类的模型训练方法,一类是基于梯度的训练方法,另一类是基于 MCMC 的模型训练方法。其中 MCMC 学习方法非常简单好用,因为要调整的超参数非常少。下面将简要介绍 MCMC 算法的由来和发展。
MCMC 由两个 MC 组成,即蒙特卡罗方法(Monte Carlo Simulation,简称 MC)和马尔科夫链(Markov Chain ,也简称 MC)。MCMC 方法是用来在概率空间,通过随机采样估算兴趣参数的后验分布。

1.3 基于 LIBFM 的学生成绩预测

这里针对 LIBFM 框架下的 MCMC 算法下的学生成绩预测进行实现。利用 LIBFM 框架, 通过所有学生的历史学期成绩,预测学生当前学期成绩。主要算法核心使用的是 MCMC 马尔可夫链蒙特卡罗算法。
LIBFM 全称为 Factorization Machine Library,是由 Steffen Rendle 于 2010 年提出的。Steffen Rendle 在矩阵分解 (MF)、SVD++ 、PITF 、FPMC 等基础之上,归纳出针对高维稀疏数据的因子机 (Factorization Machine, FM) 模型。因子机模型可以将上述模型全部纳入一个统一的框架进行分析。并且,Steffen Rendle 实现了一个单机多线程版本的 libFM。
LIBFM 不仅仅适用于推荐系统,而是和 SVM 一样可以用于数据挖掘中的很多问题,以分类问题为主。他接受的数据格式和 libSVM 是一样的,每行一个数值(分类结果 or 打分结果等),对应一组特征,每个非零特征都需要给出数值,零特征忽略。他的思想应该是从推荐系统中经典的 SVD 模型(因子分解模型)得到的,经典的 SVD 模型当中相当于只有两种类型的feature,一类 feature 是 user,一类 feature 是 item,而 LIBFM 是把这个模型推广到了多类feature 的情况。

LIBFM 训练和测试数据的格式要求

libFM 模型使用的数据格式为 libvsm 格式,改格式的要求为一行一个样本,第一列是标签,其余列是 feature 特征。如下图所示,是带有三个特征的样本数据。
 libvsm 格式数据

LIBFM 环境要求

win10 dell xps15
VMWare 虚拟机,ubuntu18.04
libfm-master1.4.4

数据准备

下载的慕课数据

数据预处理

首先需要将原始数据进行处理和数据集切分,用于适应 LIBFM 训练和十折交叉验证。数据集划分,构建 python 代码实现十折训练集,测试集划分,将训练集切分成十分,选取
其中一份当作测试集,但得到的测试结果的查全率较低。为使模型获得更好的学习效果,通过十折交叉验证划分后生成的测试集验证集。将特征和成绩处理成我们之前提到的libsvm格式。接下来的在ubuntu虚拟机linux上进行训练,使用开源的框架libfm-master1.4.4进行训练。
将txt文件进行十折划分并转换为libvsm格式文件的python相关代码。

import csv
from pandas import read_excel
from sklearn.model_selection import KFold
import numpy as np
import random
from sklearn.utils import shuffle
from sklearn.model_selection import KFold
import xlrd
import pandas as pd
import os






'''
#将dataframe转换为txt
df.to_csv('output.txt', sep='\t', index=0, header=0)

'''
#将txt格式的数据转换为libvsm格式文件。
def CSVtoLibsvm(datapath,savepath):
    # read data file
    readin = open(datapath, 'r')
    # write data file
    output = open(savepath, 'w')
    try:
        the_line = readin.readline()
        while the_line:
            # delete the \n
            the_line = the_line.strip('\n')
            index = 0;
            output_line = ''
            for sub_line in the_line.split('\t'):
                # the label col
                if index == 0:
                    output_line = sub_line
                # the features cols
                if sub_line != 'NULL' and index != 0:
                    the_text = ' ' + str(index) + ':' + sub_line
                    output_line = output_line + the_text
                index = index + 1
            output_line = output_line + '\n'
            output.write(output_line)
            the_line = readin.readline()
    finally:
        readin.close()

#十折交叉验证
#输入dataframe的格式,出来不同切分好的dataframe模式
#同时为了后续处理方便,同时切分后的训练集进行处理。将其中的正例+1复制三遍加入训练集样本中。

def k_fold_split(train, k, n):
    #k k折交叉验证
    #n是第几个文件
    os.system("mkdir data")
    kf = KFold(n_splits=10)
    #十折交叉验证,将数据分为十分,每次取一份作为test集


    k_fold = []
    k_tra = []
    for train_index, test_index in kf.split(data_frame):
        k_fold.append(test_index)
        k_tra.append(train_index)


    # # 将原始训练集划分为k个包含训练集和验证集的训练集,同时每个训练集中,训练集:验证集=k-1:1
    for i in range(k):
        print("第{}折........".format(i + 1))
        dev = k_fold[i]
        print("dev", dev)
        tra = k_tra[i]

        train_df = train.iloc[tra]#切分后的训练集
        test_df = train.iloc[dev]#切分后的测试集
        test_df.drop(19, axis=1, inplace=True)##########3333333333333333333333333333333333333333333333333333333333333
        #test_df = shuffle(test_df)不切分数据集。


        #对训练集进行平衡,复制正例并随机打乱
        extra_df =train_df[train_df[19] == 1]##########3333333333333333333333333333333333333333333333333333333333333
        for j in range(3):
           train_df =train_df.append(extra_df, ignore_index=False)

        train_df.drop(19, axis=1, inplace=True)#判断完正例后删除+1,-1标记##########3333333333333333333333333333333333333333333333333333333333333
        train_df = shuffle(train_df)#打乱顺序。
        print('finaltrain', train_df)

        #

        train_df.to_csv("data/lin{0}train_{1}.txt".format(n, i), sep="\t", index=False, header = None)
        test_df.to_csv("data/lin{0}val_{1}.txt".format(n, i), sep="\t", index=False, header = None)


        #将测试集训练集转化为libvsm格式
        CSVtoLibsvm("data/lin{}train_{}.txt".format(n, i), "finaldata/lin{}train_{}.txt".format(n, i))
        CSVtoLibsvm("data/lin{}val_{}.txt".format(n, i), "finaldata/lin{}val_{}.txt".format(n, i))

    print("done!")


if __name__ == "__main__":
   alist = [1,2,3]
   for num in alist:
       writer_1 = pd.ExcelFile('D:\pycharmBayesian\lindata\lin{}.xlsx'.format(num))
       data_frame = writer_1.parse('Sheet1', header=None, index=0)
       k_fold_split(data_frame, 10, num)




将成绩数据进行十折交叉验证后切分成训练集,和测试集。

之前已经准备好了训练数据,和测试数据之后,开始进行模型训练。

LIBFM 框架使用简介

利用 LIBFM 对学生成绩进行回归预测的终端命令如下所示。./libFM -task r -method mcmc -train ijcnn1tr.txt -test ijcnn1ts.txt -iter 100 -dim ‘1,1,2’-out output.libfm
task -r 代表是回归任务
task - c 代表的是分类任务
-train 后面跟着是训练集
-test 后面跟着的是测试集
-method 是相应的训练方法,这里使用的就是 MCMC 学习方法。

-iter 代表模型训练的迭代次数这里是一百次,当程序运行时会在屏幕上打印出来。
-out 则代表将预测结果输出到哪一个文件之中。其中各个文件格式可以选择 txt ,也可以选择 libfm 都可以,不影响结果。

利用脚本编写提高效率

为达到批量训练模型,需要在 linux 上编写脚本提高效率

f o r num in 1  2 3 do
f o r char in 0  1  2  3  4  5  6  7  8  9 do
echo $num $ char
trainDT=" l i n " ${num}" train_ " ${ char } " . txt " testDT=" l i n " ${num}" val_ " ${ char } " . txt "
echo  $ ( sed − i	’ s /\ r // ’	$trainDT ) echo  $ ( sed − i	’ s /\ r // ’	$testDT ) echo $ ( f i l e $trainDT )
echo $ ( f i l e $testDT )
echo $ ( . / libFM −task r −method mcmc − t r a i n $trainDT − t e s t $testDT − i t e r 100
done
done

在开始一直无法正常读取,差点崩溃,后来发现是linux里的txt文件格式和windows系统里的文件格式不一样导致的。通过相关资料的查询,在终端对文件格式进行修改适应,解决问题。

训练效果

训练过程
在这里插入图片描述
迭代过程

libFM对测试集进行预测:

我们使用一个回归模型来作为例子
比如训练集如下
每一行代表一个样本。第一题是回归标签,后面是三个特征取值。
在这里插入图片描述
测试集也是相同格式:

0.434343434343434	 1:.636363636363636	 2:.47	 3:.843137254901961
0.474747474747475	 1:9.09090909090909E-02	 2:.64	 3:.705882352941177
0.676767676767677	 1:1	 2:.74	 3:.823529411764706
0.696969696969697	 1:.636363636363636	 2:.97	 3:.862745098039216
0.707070707070707	 1:.636363636363636	 2:1	 3:.980392156862745
0.525252525252525	 1:.727272727272727	 2:.04	 3:.274509803921569

可能会疑惑明明是预测,第一列的标签不应该啥都没有吗?但是为了输入的格式能被识别,标签不能为NAN,不能为空,可以随意设置一个数,比如0,1,问题不大,对结果并不影响。

训练效果与组里其他的算法相比,效果比较差,因为矩阵太稀疏,导致训练效果不好,难以找到有效的语义信息,有效的特征。所以经过比较,选择了其他组员实现的算法。
在这里插入图片
上图为迭代过程。
下图为预测结果,也就是预测得到的标签。
在这里插入图片描述

2. 小程序,html框架,css框架的学习

之前没有接触过web网页设计和小程序设计,但是由于项目需要,我和任同学负责小程序项目实现,最开始是利用零碎时间学习小程序开发技术和相关知识。通过任同学的推荐,跟着b站的黑马程序员视频教程快速学习html+css,跟着b站的清华大学- 学做小程序(基础+实战)速冲了一波。同时还学习了vue uni-app框架学习前端程序设计。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值