文章目录
前言
善始者繁多,克终者盖寡。
身为一名教技专业的人,刚刚基础弗兰德斯行为矩阵的时候颇感震惊,竟然有如此神奇的测量方法,不愧是大牛学者。但是本人在具体实施时遇到了一些问题,下面同各位分享一下使用python自动生成FLAS行为矩阵,以此免去费时费力的手动操作。
一、任务分解(拟解决的问题)
相关理论知识就不再赘述,此处仅讨论具体任务的具体实现,创建FLAS行为矩阵大抵可以分为如下几个步骤:
①划分学习行为;
②获取素材(主要是视频),按一定间隔判断视频中教师与学生的行为;
③在表格中记录教师与学生的行为类型;
④生成行为矩阵(行为序列);
⑤统计各行为序列出现频次;
⑥分析课堂教学效果。
注意:本文拟解决的问题是④和⑤
步骤②和③或许也能够通过技术手段实现,比如模式识别、动作识别,某些高校智慧教室里有有能够识别学生行为的系统,但本人能力有限,只能来解决步骤④和步骤⑤。
二、代码实现
2.1 读取文件
为了提高程序的通用性,本文考虑通过读取配置文件的方式加载数据,配置文件与主程序同一级目录下。
def read_config(config_path):
with open(config_path, "r", encoding="utf-8") as f:
path = f.readline()[4:].strip()
return path
图中仅演示包含拟读取文件的文件名。
2.2 生成FLAS行为矩阵
2.2.1 两种表
我们在表格中记录课堂中教师和学生的行为类型,将其记录到表格中,最终得到的表可以分为两种类型:
尾部对齐
尾部不齐
2.2.2 六种情况
根据可能出现的两种类型的表,汇总行为序列时需要考虑6种情况:
①表格头部使用0连接,例如首个单元格行为类型为3,则应生成[0,3]
②非末行的行尾与下一行行首连接,例如当前行末为6,下一行行首为2,则应生成[6,2]
③2.2.1中尾部不齐的情况,末行最后一个数据使用0连接,例如最后一行最后一个单元格为7,则应生成[7,0]
④2.2.1中尾部对齐的情况,需要创建新的行,例如尾部为4,则应生成[4,0]
⑤没有数据的单元格使用None填充
⑥正常情况下,前一个单元格与后一个单元格连接
参看示例:
2.2.3 代码实现
在程序运行时,尾部不齐情况下,程序并不能够正常运行,所有在生成矩阵前我们对表格中的控制进行替换和填充。
def Fias(filename):
# data = pandas.read_excel(filename,header=None)
data = read_file(filename)
data.fillna(666,inplace=True)
for i in range(data.shape[1]):
data[i] = data[i].astype("int64")
data[i] = data[i].astype(str)
data[i] = data[i].mask(data[i]=="666","")
data_copy_re = data.copy()
row,col = data.shape
s=","
sl="["
sr="]"
# print(len(data.loc[0]))
for i in range(row):
for j in range(len(data.loc[i])):
if i==0 and j==0:
data_copy_re.loc[i][j] = sl + "0" + s + data.loc[i][j] + sr
elif i == row - 1 and data.loc[i][j]=="" and data.loc[i][j-1]!="":
data_copy_re.loc[i][j] = sl + data.loc[i][j-1] + s + "0" + sr
elif i == row - 1 and data.loc[i][j]=="" and data.loc[i][j-1]=="":
data_copy_re.loc[i][j] = None
elif j==0:
data_copy_re.loc[i][j] = sl + data.loc[i-1][len(data.loc[i])-1] + s + data.loc[i][j] + sr
elif i == row - 1 and j == len(data.loc[i]) - 1:
none_data = [None] * len(data.loc[i])
data_copy_re.loc[row] = none_data
data_copy_re.loc[i][j] = sl + data.loc[i][j - 1] + s + data.loc[i][j] + sr
data_copy_re.loc[row][0] = sl + data.loc[i][j] + s + "0" + sr
else:
data_copy_re.loc[i][j] = sl + data.loc[i][j-1] + s + data.loc[i][j] + sr
print(data_copy_re)
data_copy_re.to_excel("t2.xlsx")
return data_copy_re
2.3 统计行为序列出现频次
此处使用的是经典的FLAS行为编码,总共有10中行为类别,我们使用10*10的矩阵接收并统计各种行为序列出现的频次。
def Fias_count(data:pandas.DataFrame):
df = pandas.DataFrame(numpy.zeros((10,11),dtype="int64"))
df.index = range(1,11)
df.drop(columns=0,inplace=True)
row,col = data.shape
for i in range(row):
for j in range(col):
if data.loc[i][j]!=None:
r = int(data.loc[i][j][1])
c = int(data.loc[i][j][3])
if r==0 and c==0:
df.loc[10][10] += 1
elif r==0:
df.loc[10][c] += 1
elif c==0:
df.loc[r][10] += 1
else:
df.loc[r][c] += 1
print(df)
df.to_excel("t3.xlsx")
2.4 其他方法
读取配置文件中的数据文件。
def read_file(path):
data = pandas.read_excel(path,header=None)
return data
三、测试程序
3.1 测试数据
以3秒为间隔,在表中记录下某堂27分钟左右的课中各行为出现的情况,得到543个标记。
3.2 测试程序
if __name__ == '__main__':
config_path = f"config.txt"
filename = read_config(config_path)
data = Fias(filename)
Fias_count(data)
3.3 运行结果
运行程序后会得到544个行为序列。
不同行为序列出现次数如下图所示,行为或者说动作是分先后顺序的,即[3,2]和[2,3]表示的含义并不相同,下图从第二行开始从左往右看;行为编号中的0使用10来替换,这样更加符合阅读习惯。
例如,行为序列[5,5]出现的次数最多;行为序列[0,0[出现的次数其次;行为序列[4,9]出现的次数第三多。