文章自动打分算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文章自动打分算法相关的知识,希望对你有一定的参考价值。

参考技术A

文章自动打分简称 AES (Automated Essay Scoring),AES 系统利用 NLP 技术自动对文章进行打分,可以减轻阅卷人员的负担。目前有不少大型的考试都采用了 AES 算法进行作文打分,例如 GRE 考试,GRE 考试会有一位阅卷老师和 AES 系统一起打分,如果 AES 的分数和阅卷老师的分数相差过大,才有再增加一位阅卷老师进行打分。本文主要介绍两种比较经典的自动打分算法。

自动打分算法从优化目标或者损失函数来说大致可以分为三种:

传统的自动打分算法通常会人工设置很多特征,例如语法错误,N 元组,单词数量,句子长度等,然后训练机器学习模型进行打分。目前也有很多使用了神经网络的方法,通过神经网络学习出文章的特征。

下面介绍两种打分算法:

出自论文《Regression based Automated Essay Scoring》。给定很多需要打分的文章后,首先需要构造出文章的特征,用到了人工设置特征和向量空间特征。

拼写错误 Spelling Errors :使用 pyenchant 包统计出拼写错误单词数量占总单词数量的比例。

统计特征 Statistical Features :统计字符数量,单词数量,句子数量,段落数量,停止词数量,命名实体数量,标点符号数量 (反映文章的组织情况),文本长度 (反映写作流畅程度),不同词汇的数量与总单词数的占比 (反映词汇量水平)。

词性统计 POS count :统计各种词性出现的频率,例如名词,动词,形容词,副词等,词性通过 nltk 包获取。

语法流畅特征 Grammatical Fluency :使用 link grammar (链语法) 解析句子,然后统计 links 的个数;统计 n 元组出现的概率;统计词性 n 元组出现的概率。

可读性 Readability :可读性分数是衡量文本组织以及文本句法和语义复杂程度的一个指标。采用了 Kincaid 可读性分数作为一个特征,计算公式如下

本体特征 Ontological Features :为每个句子打上标签,例如研究、假设、主张、引用、支持和反对等。

可以将一篇文章投影到一个向量空间模型中 (VSM),此时文章可以用向量空间中的一个特征向量表示,例如可以用 one-hot 编码表示一篇文章,长度等于词汇表长度,如果一个单词出现在文章中,则对应的位置置为 1,如下:

另外也可以使用 TF-IDF 向量表示文本,但是采用这种表示方式单词之间不存在任何关联,为了解决这个问题,文章中使用了一个单词相关性矩阵 W 加上线性变换从而引入单词之间的相关性。

单词的相关性矩阵 W 通过 word2vec 生成的词向量计算,即 W (i,j) = 单词 i 和单词 j 词向量的余弦相似度。

最后,为了考虑文章中单词的顺序问题,将文章拆分成 k 个段落,然后分别计算向量空间特征,融合在一起。

得到上述特征之后,采用 SVR 算法进行回归学习。数据集是 kaggle ASAP 比赛数据集,数据集包含 8 个集合的文章,评价指标采用 KAPPA 和相关系数,以下是一些实验效果。

这是在 8 个集合上分别使用 linear kernel 和 rbf kernel 的效果。

这是和人类打分者的对比。

以下内容出自论文《Neural Networks for Automated Essay Grading》,可以采用回归或者分类的方法进行训练,模型如下图所示。

论文中主要使用了三种方法构造出文章的特征向量:

论文中主要用了三种神经网络结构,NN (前向神经网络),LSTM 和 BiLSTM。所有的网络都会输出一个向量 h(out),根据 h(out) 构造出损失函数,下面分别是回归和分类的损失函数。

回归损失

分类损失

第一种模型:NN (前向神经网络)

使用了两层前向神经网络,网络输入的文章特征向量是 Glove 词向量的平均值或者训练的词向量平均值。h(out) 的计算公式如下。

第二种模型:LSTM

LSTM 模型接受的输入是文章所有单词的词向量序列,然后将 LSTM 最后输出的向量作为文章的特征向量 h(out)。

第三种模型:BiLSTM

因为文章通常比较长,单向的 LSTM 容易丢失前面的信息,因此作者也使用了 BiLSTM 模型,将前向 LSTM 和后向 LSTM 模型的输出加在一起作为 h(out)。

添加 TF-IDF 向量

以上模型的输出 h(out) 都可以再加上 TF-IDF 向量提升性能,首先需要对 TF-IDF 向量降维,然后和模型的输出拼接在一起,如下图所示 (BiLSTM 为例子)。

《Regression based Automated Essay Scoring》
《Neural Networks for Automated Essay Grading》

SlopOne推荐算法(附Python源码)


关键字全网搜索最新排名

【机器学习算法】:排名第一

【机器学习】:排名第二

【Python】:排名第三

【算法】:排名第四




SlopOne是一个非常简单的协同过滤算法。他的基本思想非常简单,如果用户u已经对物品j打过分,现在对物品i进行打分,那么只需要计算出同时对物品i和物品j打分的用户中他们分数之差的平均,那么我们就可以根据这个分数之差来计算用户u对物品i的打分了,当然,这样的物品j也有很多歌,有的物品和j共同大份的用户比较少,有的比较多,那么显而易见的是共同打分多的那个物品在评分是所占的比重应该大一些。举个例子,如下图所示



现在要预测Lucy对Item1的评分。首先可以知道用户Lucy对Item2和Item3打过分,现在计算Item1和Item2的平均差值,即((5-3)+(3-4))/2 = 0.5,在计算Item1和Item3的平均差值,即5-2 = 3,那么根据Item1和Item2的平均差值来看Lucy对Item1的评分可能为2+0.5 = 2.5,同时根据Item1和Item3的平均差值Lucy对Item1的评分可能为5+3=8,最终用户Lucy对Item1的评分为(2.5*2+8*1)/(2+1)=13/3=4.33。


使用movielens数据

链接:https://grouplens.org/datasets/movielens/


Python代码如下

#coding:utf-8  

import re  

import math  


#读取数据,并生成矩阵  

def getMatrix():  

    mat = {}  

    f = open("u.data", "r")  

    for line in f:  

        list = map(int, line.strip("\n").split("\t"))  

        if list[0] in mat:  

            mat[ list[0] ][ list[1] ] = list[2]  

        else:  

            mat[ list[0] ] = { list[1] : list[2] }  

    f.close()  

    return mat  


#计算某个用户的平均分  

def getAvg(usr):  

    res = 0.0  

    for i in usr:  

        res += usr[i]  

    return res / len(usr)  


#预测分数, 返回矩阵mat中用户usr对item的评分  

def getSlopOne(mat, user, item):  

    #用户user的所有item的列表  

    list = mat[user]  

   #分子  

    mole = 0.0  

    #分母  

    demo = 0.0  

    #对于每一个物品,都计算它和物品item的差值,最终算出相对它item的score  

    for it in list:  

        diff_sum = 0.0  

        user_num = 0  

        for us in mat:  

            us_it = mat[us]  

            #如果该user同时评价过这两个item,则采纳他的评分  

            if item in us_it and it in us_it:  

                diff_sum += us_it[item] - us_it[it]  

                user_num += 1  

        #如果item被人评价过  

        if user_num:  

            diff_avg = diff_sum / user_num  

            mole += (list[it] + diff_avg) * user_num  

            demo += user_num  

    #如果没有人评价过,则取这个人的平均分  

    if user_num == 0:  

        return getAvg(list)  

    #否则返回最终的score  

    return mole / demo  

 

def main():  

    mat = getMatrix()  

    rf = open("u.data", "r")  

    wf = open("o.data", "w")  

    for line in rf:  

        list = map(int, line.strip("\n").split("\t"))  

        score = getSlopOne(mat, list[0], list[1])  

        output = str(list[0]) + "\t" + str(list[1]) + "\t" + str(list[2]) + "\t" + str(score) + "\n"  

        wf.write(output)  

    rf.close()  

    wf.close()  

  

if __name__ == "__main__":  

    main()  




投稿、商业合作

请发邮件到:357062955@qq.com

更多精彩请阅读原文


以上是关于文章自动打分算法的主要内容,如果未能解决你的问题,请参考以下文章

短视频封面抽取和标题自动化生成

打分排序系统漫谈2 - 点赞量?点赞率?! 置信区间!

机器学习框架ML.NET学习笔记自动学习

Python自动给抖音小姐姐视频点赞

Python自动给抖音小姐姐视频点赞

AC自动机