python3利用LSI算法实现自动打分机制
适用于主观题(解答之类的)
前面也是利用结巴分词把多个学生的同一个问题连同正确答案转为词向量,然后利用SVD分解,取出前几个指定数量的奇异值并且还原成新的向量,然后求解相似度乘以总分就得到某个答案的分数
main.py
# coding:utf-8
import jieba
import codecs
from numpy import *
import re
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
#cut_word
def cut_txt(cut_file,out_file):
try:
fi = codecs.open(cut_file, 'r',encoding='utf-8')
except BaseException as e: # 因BaseException是所有错误的基类,用它可以获得所有错误类型
print(Exception, ":", e) # 追踪错误详细信息
text = fi.read() # 获取文本内容
#filter punctuation
punc = "!?。?"#$%&'()*+,-/:;<=>@[\]^_`。{|}~⦅⦆「」、、〃》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏."
stoplist = {}.fromkeys([line.strip() for line in open("stoplist.txt")])
text_del_puc=re.sub("[%s]+" % punc, "", text)
cut_str = jieba.cut(text_del_puc, cut_all=False) # 精确模式
segs = [word for word in cut_str if word.encode('utf-8') not in stoplist]
fo = codecs.open(out_file, 'w',encoding='utf-8')
fo.write(' '.join(segs))
def tfidf_txt(corpus_file):
corpus = []
with open(corpus_file, 'r') as f:
for line in f:
corpus.append(line)
# 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
vectorizer = CountVectorizer(min_df=0)
# 该类会统计每个词语的tf-idf权值
transformer = TfidfTransformer()
# 第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
# 获取词袋模型中的所有词语
word = vectorizer.get_feature_names()
# 将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
weight = tfidf.toarray()
# print(tfidf.shape)
# 打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
# for i in range(len(weight)):
# print u"-------这里输出第", i, u"类文本的词语tf-idf权重------"
# for j in range(len(word)):
# print word[j], weight[i][j]
#返回文档-TF-IDF矩阵
return weight
# 对矩阵进行SVD分解
def svd_(tfidf):
# print tfidf.shape
U,Sigma,VT=linalg.svd(tfidf)
# print('SVD分解Sigma的结果为:',Sigma.shape,Sigma)
return U,Sigma,VT
# 近似重构原始矩阵
def reconstructMat(tfidf,k):
U,Sigma,VT=svd_(tfidf)
# print(U)
# print(Sigma)
# print(VT)
# exit()
Sigk= np.zeros([k, k])
#取奇异值的前k个
for i in range(k):
Sigk[i][i] = Sigma[i]
reconMat=np.dot(np.dot(U[:,:k], Sigk), VT[:k,:])#取topN后重构矩阵
return reconMat
#计算两个向量的相关系数
def correlation(x, y):
# std_x = (x-x.mean())/(x.std(ddof=0))
# std_y = (y-y.mean)/(y.std(ddof=0))
return (((x - x.mean()) / (x.std(ddof=0))) * ((y - y.mean()) / (y.std(ddof=0)))).mean()
# std(ddof=0) 为禁止使用贝塞耳校正系数
if __name__ == "__main__":
cut_file='input.txt'
out_file='output.txt'
#加上正确答案一共有多少个答案
numQuestion = 13
#这个题的总分
c = 25
# cut_txt(cut_file,out_file)#begin cut word (1)
# tfidf_txt() #then csount doc-tfidf (2)
#reconstructMat() #threed svd(lsi) and rebuid mat (3)
#correlation() #end count corrcoef with real-answer and student-answer (4)
#分词
cut_txt(cut_file, out_file)
tfidf=tfidf_txt(out_file)
# tip:k的取值
mat=reconstructMat(tfidf,10)
# correlation(mat[2, :], mat[3, :])
for i in range(numQuestion):
if(correlation(mat[0,:], mat[i,:])<0):
print(0)
else:
print(math.ceil(c*correlation(mat[0,:], mat[i,:])))input.txt
超键(super key):在关系中能惟一标识元素属性的集称为关系模式的超键。候选键:(Candidate Key):不含有多余属性的超键称为候选键。也就是说在候选键中在删除属性,就不是键了。主键(Primary Key):用户选作元组标识的候选键为主键。一般不佳说明,键就是主键。外键(Froeign Key):如果模式R中的属性k是其他模式的主键,那么k在模式R中称为外键 超键(super key):在关系中能惟一标识元素属性的集称为关系模式的超键。 候选键:(Candidate Key):不含有多余属性的超键称为候选键。也就是说在候选键中在删除属性,就不是键了。 主键(Primary Key):用户选作元组标识的候选键为主键。一般不佳说明,键就是主键 外键(Froeign Key):如果模式R中的属性k是其他模式的主键,那么k在模式R中称为外键 主键就是一个表才有一个键位, DBMS提供数据定义语言DDL(Data Definition Language) 超键(super key):在关系中能惟一标识元素属性的集称为关系模式的超键。候选键:(Candidate Key):不含有多余属性的超键称为候选键。也就是说在候选键中在删除属性,就不是键了。主键(Primary Key):用户选作元组标识的候选键为主键。一般不佳说明,键就是主键。 主键(Primary Key):用户选作元组标识的候选键为主键。一般不佳说明,键就是主键。 外键(Froeign Key):如果模式R中的属性k是其他模式的主键,那么k在模式R中称为外键 超键(super key):在关系中能惟一标识元素属性的集称为关系模式的超键。候选键:(Candidate Key):不含有多余属性的超键称为候选键。也就是说在候选键中在删除属性,就不是键了。主键(Primary Key):用户选作元组标识的候选键为主键。外键(Froeign Key):如果模的属性k是其他模式的主键,那么k在模式R中称为外键 主键用户选作元组标识的候选键为主键 DBMS提供数据定义语言DDL(Data Definition Language)
output.txt
超键 super key 在 关系 中 能 惟一 标识 元素 属性 的 集 称为 关系 模式 的 超键 候选 键 Candidate Key 不 含有 多余 属性 的 超键 称为 候选 键 也就是说 在 候选 键 中 在 删除 属性 就 不是 键 了 主键 Primary Key ) 用户 选作 元组 标识 的 候选 键 为主 键 一般 不佳 说明 键 就是 主键 外键 Froeign Key : 如果 模式 R 中 的 属性 k 是 其他 模式 的 主键 那么 k 在 模式 R 中 称为 外键 超键 super key 在 关系 中 能 惟一 标识 元素 属性 的 集 称为 关系 模式 的 超键 候选 键 Candidate Key 不 含有 多余 属性 的 超键 称为 候选 键 也就是说 在 候选 键 中 在 删除 属性 就 不是 键 了 主键 Primary Key ) 用户 选作 元组 标识 的 候选 键 为主 键 一般 不佳 说明 键 就是 主键 外键 Froeign Key : 如果 模式 R 中 的 属性 k 是 其他 模式 的 主键 那么 k 在 模式 R 中 称为 外键 主键 就是 一个 表才 有 一个 键位 DBMS 提供数据 定义语言 DDLData Definition Language 超键 super key 在 关系 中 能 惟一 标识 元素 属性 的 集 称为 关系 模式 的 超键 候选 键 Candidate Key 不 含有 多余 属性 的 超键 称为 候选 键 也就是说 在 候选 键 中 在 删除 属性 就 不是 键 了 主键 Primary Key ) 用户 选作 元组 标识 的 候选 键 为主 键 一般 不佳 说明 键 就是 主键 主键 Primary Key ) 用户 选作 元组 标识 的 候选 键 为主 键 一般 不佳 说明 键 就是 主键 外键 Froeign Key : 如果 模式 R 中 的 属性 k 是 其他 模式 的 主键 那么 k 在 模式 R 中 称为 外键 超键 super key 在 关系 中 能 惟一 标识 元素 属性 的 集 称为 关系 模式 的 超键 候选 键 Candidate Key 不 含有 多余 属性 的 超键 称为 候选 键 也就是说 在 候选 键 中 在 删除 属性 就 不是 键 了 主键 Primary Key ) 用户 选作 元组 标识 的 候选 键 为主 键 外键 Froeign Key : 如果 模 的 属性 k 是 其他 模式 的 主键 那么 k 在 模式 R 中 称为 外键 主键 用户 选作 元组 标识 的 候选 键 为主 键 DBMS 提供数据 定义语言 DDLData Definition Language
stoplist.txt
吗 怎么回事 的 了 什么 是 啊 ,