gradio简单搭建——关键词匹配筛选[进一步优化]
- 任务回顾
- 新的想法:无效元素筛选
- 界面搭建
- 数据处理与生成过程
- 交互界面展示
任务回顾
在 apply \text{apply} apply方法的使用一节中,简单提到了任务目标:通过关键词的形式,在文本数据中体现出主体的工作类型。
但这个目标执行之前,可以尝试对数据先一步进行清洗:如果文本数据满足一些关键词构成的模板,这种数据更容易地被查找出与工作性质相关的信息,而不需要去观察文本数据的其他位置。例如如下几组关键词组成模板:
mode = {
1:['进行','作业'],
2:['进行','工作'],
3:['操作','时'],
4:['操作','过程中']
}
在一些示例中,可以轻松地通过这些模板推理出主体对应的工作性质。例如:
某人在车间内操作钻床时,不小心被铁屑蹭伤。
结合上述模板,可以直接观察出:主体的工作性质和钻床相关。从而引出上一节使用展示工具gradio
实现一个通过单元素/多元素顺序匹配筛选表格数据的简单交互平台,本节将对其进行进一步优化。
新的想法:无效元素筛选
在单元素/多元素思路的启发后,想起了《三体3:死神永生》中的低光速黑域:
若星球被低光速黑域笼罩,外星文明远远地看上一眼,就知道是绝对安全的——光都无法逃离出来,黑域内的生物自然无法逃离,这就是宇宙安全声明。
言归正传,在文本数据中是否也可能存在这种情况——“远远”地看上一眼,就可以知道:文本内信息对于主体工作性质的描述几乎无关联。例如:
某人在上班途中,与电动车相撞受伤。
分析:首先文本中并没有直接描述主体的工作性质信息(岗位、职位),其次可以通过推理:上班途中,意味着其没有到达预定岗位开始工作,可以归纳出:上班途中发生的事情,大概率与主体的工作性质无关。
也存在极个别情况~但减轻工作量的目的确实达到了。
想法有了,继续使用展示工具gradio
对交互平台进行优化,包含两个方面:
- 加入无效元素筛选功能:只要数据中出现关键词,将该数据在本次匹配筛选过程中去除;
- 与关键词模板功能不冲突:各自可以单独执行,也可以混用。
界面搭建
import gradio as gr
from file_generator import generate_file
class CONST:
file_type_list = ['xlsx']
def submit(input_file,
invalid_task,
invalid_keyword_input,
task,
keyword_input,
desc):
print(f'task:{task}')
print(f'keyword_input:{keyword_input}')
print(f'invalid_task:{invalid_task}')
print(f'invalid_keyword_input:{invalid_keyword_input}')
# 输入文件格式设置
if '\\' in input_file:
input_file = input_file.replace('\\','/')
suf = input_file.split('.')[-1]
if suf not in CONST.file_type_list:
raise gr.Error('不支持的格式:{},请检查文件格式'.format(suf))
if not invalid_task and not task:
raise gr.Error('[无效元素匹配]与[单/多元素匹配]至少选择一个')
else:
# [无效元素匹配]逻辑描述
if invalid_task:
if invalid_keyword_input:
if invalid_task == '禁用':
raise gr.Error('无效元素匹配[禁用]时,无法输入无效元素') # 选择禁用时,文本框不可用
else:
if ',' in invalid_keyword_input:
invalid_keyword_input = invalid_keyword_input.replace(',',',')
if ',' in invalid_keyword_input:
invalid_keyword_list = invalid_keyword_input.split(',')
else:
invalid_keyword_list = [invalid_keyword_input]
else:
if invalid_task == '启用':
raise gr.Error('无效元素匹配[启用]时,请输入无效元素') # 选择启用时,文本框内必须输入无效元素
else:
invalid_keyword_list = list()
else:
invalid_keyword_list = list() # 未选择使用[无效元素匹配]
# [单/多元素匹配]逻辑描述
if task:
if not keyword_input:
raise gr.Error('请输入匹配关键词') # 已选择[单/多元素匹配]条件下,文本框内必须输入匹配元素
else:
if ',' in keyword_input:
keyword_input = keyword_input.replace(',',',')
if ',' in keyword_input:
if task == '单元素匹配':
raise gr.Error('单元素匹配模式不支持输入多个关键词')
else:
keyword_list = keyword_input.split(',')
else:
if task == '多元素匹配':
raise gr.Error('多元素匹配模式不支持输入单个关键词')
else:
keyword_list = [keyword_input]
else:
task = '无元素匹配'
keyword_list = list() # 未选择使用[单/多元素匹配]
output = generate_file(input_file,task,invalid_task,keyword_list,invalid_keyword_list)
return output
description = """
1. 单元素匹配:筛选出包含输入元素的样本;
2. 多元素匹配:筛选出按输入元素顺序,包含输入元素的样本;
3. 无效元素匹配:元素匹配过程中,一旦出现无效元素,则不包含该样本;
一次性可以输入多个元素,使用逗号(英文)分隔;
例: 上班途中,下班途中,...
4. [无效元素匹配]与[单/多元素匹配]操作之间可单独使用,也可混用;
"""
demo = gr.Interface(
fn=submit,
inputs = [
gr.File(
file_count="single",
label="上传文件",
file_types=CONST.file_type_list
),
# 无效元素匹配
gr.Radio(
choices=['启用','禁用'],
label='无效元素匹配'
),
gr.Textbox(
label='无效关键词',
placeholder='可以一次输入多个数据,使用逗号(英文)间隔;若选择禁用,文本框为空'
),
# 匹配元素单选框
gr.Radio(
choices=['单元素匹配','多元素匹配'],
label='选择元素匹配模式'
),
gr.Textbox(
label='匹配关键词',
placeholder='请输入匹配关键词'
),
gr.Text(
description,
label='使用说明'
)],
outputs=gr.File(label='输出文件'),
title='单元素/多元素匹配筛选数据',
examples=[['测试文件.xlsx','启用','上班途中,下班途中','',''],
['测试文件.xlsx','禁用','','',''],
['测试文件.xlsx','','','单元素匹配','作业时'],
['测试文件.xlsx','','','多元素匹配','操作,过程中'],
['测试文件.xlsx','启用','上班途中,下班途中','多元素匹配','操作,时']]
)
demo.launch(share=True, server_name='0.0.0.0',server_port=8706)
数据处理与生成过程
import pandas as pd
import os
def sorted_keywords_update(df,task,invalid_task,keyword_list,invalid_keyword_list):
def sorted_keywords(str_input,sorted_word_list):
"""查找列表中的关键词,如果关键词有序地匹配成功返回True,否则返回False"""
count = 0
while count < len(sorted_word_list):
if sorted_word_list[count] in str_input:
str_input = "".join(str_input.split(sorted_word_list[count])[1:])
count += 1
else:
break
if count == len(sorted_word_list):
return True
else:
return False
def eliminate_invalid(df_input,invalid_keyword_list):
"""无效元素匹配[启用]状态下,筛除包含invalid_keyword_list内词对应的行"""
for invalid_word in invalid_keyword_list:
df_input = df_input[~df_input['文本信息'].str.contains(invalid_word)]
return df_input
def mode_2_rules(row):
"""多元素匹配模式规则"""
return sorted_keywords(row['文本信息'],keyword_list) == True
def mode_1_rules(df_input, keyword_list):
"""单元素匹配模式规则"""
assert len(keyword_list) == 1
contain_df = df_input[df_input['文本信息'].str.contains(keyword_list[0])]
return contain_df
# 删除字段中的空元素
sub_df = df[~df['文本信息'].isna()]
# 筛选无效元素过程
if invalid_task == '启用':
invalid_sub_df = eliminate_invalid(sub_df,invalid_keyword_list)
else:
invalid_sub_df = sub_df #[禁用/未选择]时不做处理;
# 元素匹配过程
if task == '单元素匹配':
contain_df = mode_1_rules(invalid_sub_df,keyword_list)
elif task == '多元素匹配':
contain_df = invalid_sub_df[invalid_sub_df.apply(mode_2_rules,axis=1)]
else:
contain_df = invalid_sub_df #同上,[未选择]时不做处理;
# 创建输出文件夹并输出文件
output_dir = f'./output/match_keyword/{task}'
output_path = f'{output_dir}/{task}_res.xlsx'
os.makedirs(output_dir, exist_ok=True)
contain_df.to_excel(output_path,index=False)
return output_path
def generate_file(file_path,
task,
invalid_task,
keyword_input,
invalid_keyword_input):
"""
file_path: 待优化数据文件路径
task: 匹配模式:[单模式匹配,多模式匹配]
invalid_task: 无效匹配模式:[启用,禁用]
keyword_input: 匹配关键词
invalid_keyword_input: 无效匹配关键词
"""
df = pd.read_excel(file_path)
# 数据生成平台
output_file_path = sorted_keywords_update(df,task,invalid_task,keyword_input,invalid_keyword_input)
return output_file_path
交互界面展示
初始状态下,交互界面的展示效果如下:
试了几个例子~
执行结束后,交互界面的展示效果如下: