Commit acdc8fe6 by 陈森彬

Merge remote-tracking branch 'origin/master'

parents f380381f c6d055f4
# BOM识别工具 说明书
##bom_identify 的功能主要有
1. 解析BOM: 接收BOM表单, 返回表单中哪一列是什么字段类型, 如第一列是参数, 第二列是型号等等, 这个是主要功能, 下面两个功能都是比较简单的基于模型直接预测的.
2. 预测字符串类型: 接收单个字符串. 返回判断结果如"参数", "型号"等等
3. 判断字符串类型: 判断某个字符串是否是型号(或参数等等), 返回1或0
## 目录结构
* **models_and_extractors** 此包里面存放的是各个模型和相应的特征提取器
* **predict** 此包里面存放的是各个预测类
- base_handler模块里面的BasePredictor为所有预测类的基类
- dict_hanadler里面的DicPredict为字典预测, 一般情况下只有BOM预测才会传入字典型数据, 需要预测某一列是什么类型, 分表头预测和模型预测两大方法.
- kw_predict里面的KwPredict为关键字预测, 一般情况下是接收传入的单个字符串, 需要预测其是哪个类型, 或者判断它是不是某个类型.
- txt_predict里面的TxtPredict为文本预测, 一般情况下是接收传入的列表, 形如["lm358 三星 20", "lm777 村田 10"], 需要提取型号/数量/品牌等信息.
* **protobuf** 此包里面存放的是用于rpc调用的关键模块
* **utils** 工具类
* **classify_server** 该模块为启动rpc接口的服务, 不过由于后端调用不了rpc, 所以暂时废弃
* **http_server** 该模块为启动http接口的服务
* **id_server** 该模块是综合rpc接口的启动和http接口的启动
* **predic_fac** 模块里面的PredictorFac是预测器的工厂类, 传入不同的参数生成不同的预测器
* **static_config** 存放用于表头预测的数据依据和用于排除干扰项的静态配置
* **valid_server** 用于验证单个字符串的验证服务
##
### 解析BOM
目前主要有表头预测和模型预测两种预测方法, 而最终的结果是表头预测为主, 模型预测为辅的综合预测方法.
1. 在预测开始前需要预处理, 去掉空置率大于0.8的列, 因为这些列的有效数据太稀少, 没有预测的意义.
2. 先进行表头预测, 原理就是根据static_config里面存好的一些可能的表头字符串, 扫面BOM单里面的各个单元格里面的字符串看看有没有出现表头字符串. 例如BOM单里面的第2列第3行单元单元格里面的字符串是"型号", 那么这列就可以视为型号列.
3. 再进行模型预测, 模型预测前需要排除一些干扰项例如"序号", "数量"等等.
### 部署启动
* 环境 python3.6.5以上 pip install -r requirements.txt 安装依赖包
* 启动命令
- 单独启动BOM识别的http服务: python3 http_server.py
- 同时启动BOM识别的http和rpc服务: python3 id_server.py
- 启动单个字符串验证的服务: python3 valid_server.py
### 所在目录
测试环境:
IP: 192.168.2.232
PATH: /home/lic/bom_identify
正式环境:
IP: 119.23.79.136
PATH: /data/soft/bom_identify
备注: 由于单个字符串验证的服务无需对外开放, 暂时只在本地测试环境运行
\ No newline at end of file
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json
import pandas as pd
import unittest
from random import randint
import requests
def get_test_data(path):
df = pd.read_excel(path, header=None)
df.fillna('?', inplace=True)
dic_dft = df.to_dict(orient='list')
return dic_dft
class MyclassTest(unittest.TestCase):
def setUp(self) -> None:
pass
def tearDown(self) -> None:
pass
# @unittest.skip
def test_bomhttp_bydict(self):
"""直接用字典数据测试BOM服务的http接口, '?'是占位符, 对应BOM表单里面的空白单元格, 后端传过来的数据格式也就是这样子, 只不过'?'是空白"""
d = {'3': ['?', '?', '名称', '电阻', '电阻', '电阻', '电阻', '电容', '钽电容', '钽电容', '二极管', '二极管', '发光二极管', '自恢复保险丝', '三极管',
'MOS管', '电源芯片', '逻辑器件', 'WIFI模组', '接线座子', '接线座子', '轻触按键', '?'],
'4': ['?', '?', '?', '0402X105K6R3NT', '0402X105K6R3NT', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
'?', '?', '?', '?', '?', '?', '?', 'JMK105BJ105KV-F'],
'5': ['?', '?', '描述', 'RES,0603,10Ω±5%,1/10W', 'RES,0603,1KΩ±5%,1/10W', 'RES,0603,4.7KΩ±5%,1/10W',
'RES,0603,10KΩ±5%,1/10W', 'CAP,SMD0603,100nF±10%,16V', 'CAP,SMD3528,10uF±10%,16V',
'CAP,SMD3528,22uF±10%,16V', 'DIODE,SMB(DO-214AA),SMBJ5.0CA', 'SMA(DO-214AC) ,SS34 肖特基二极管 40V/3A',
'SMD0805 红色LED', '贴片封装1812 6V 3A', 'TRIODE,SOT-23,2N3904', 'N-MOSFET,SOT-23,SI2302',
'IC,CJA1117B-3.3 ,SOT-89-3N', 'IC,SN74HC125PW TSSOP-14', 'ESP-F1 模组', '贴片卧式插座 间距1.25/1.27MM 8PIN',
'KF2EDG-2PIN间距3.81mm 弯脚一对', '侧脚 6*6*5MM 轻触按键 带支架 立式', '1uF(105) ±10% 6.3V'],
'6': ['?', '?', '用量', 3, 4, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 10],
'7': ['?', '?', 'A面位置', 'R10,R11,R12', 'R2,R4,R7,R8', 'R6', 'R1,R5,R9', 'C3,C4,C6', 'E1', 'E2', 'D1', 'D3',
'D2', 'F1', 'Q2', 'Q1', 'U2', 'U4', 'U3', 'J4', 'J1,J2', 'K1', '?'],
'8': ['?', '?', 'B面位置', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
'?', '?', '?', '?'],
'9': ['?', '?', '品牌', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
'右侧参考图片', '右侧参考图片', '右侧参考图片', 'TAIYO '],
'10': ['?', '?', '备注', '?', 10, 0.3, '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
'https://detail.tmall.com/item.htm?id=555809251133&ali_refid=a3_430673_1006:1109983619:N:%E5%BA%A7%E5%AD%90:6670de4731121049ff6e61b5ac2ad7d1&ali_trackid=1_6670de4731121049ff6e61b5ac2ad7d1&spm=a2e15.8261149.07626516002.6&skuId=3598966783405',
'?', 100],
'11': ['?', '需求数量', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?',
'?', '?', '?', '?']}
d = json.dumps(d)
res = requests.post("http://127.0.0.1:50052/dict", data=d).json()
print(res)
# @unittest.skip
def test_bomhttp_byxls(self):
"""用excel文件测试BOM服务的http接口, 需要先转化为字典类型"""
path = r"C:\Users\ICHUNT\Documents\DZ0901_V1.4_BOM.xlsx"
d = get_test_data(path)
d=json.dumps(d)
res = requests.post("http://127.0.0.1:50052/dict", data=d).json()
print(res)
if __name__ == '__main__':
pass
# suite = unittest.TestSuite()
# suite.addTest(MyclassTest('test_add'))
# suite.addTest(MyclassTest('test_sub'))
#
# runner = unittest.TextTestRunner()
# runner.run(suite)
...@@ -77,4 +77,5 @@ def http_server(port): ...@@ -77,4 +77,5 @@ def http_server(port):
if __name__ == '__main__': if __name__ == '__main__':
port = 50052 port = 50052
bom_log.info("BOM识别http服务监听在: %d"%port)
http_server(port) http_server(port)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
import json import json
from predict import dict_predict, kw_predict, txt_predict from predict import dict_predict, kw_predict, txt_predict
from utils.status import code2msg, Status, StatusCode from utils.status import code2msg, Status
class PredictorFac: class PredictorFac:
......
...@@ -21,7 +21,7 @@ def get_head_row(li: list) -> int: ...@@ -21,7 +21,7 @@ def get_head_row(li: list) -> int:
return index + 1 return index + 1
# 取前多少行做表头预测 # 取前HEAD_ROW行做表头预测
HEAD_ROW = 7 HEAD_ROW = 7
# 空置率阈值 # 空置率阈值
NAN_RATE = 0.8 NAN_RATE = 0.8
...@@ -284,7 +284,7 @@ class DicPredict(BasePredictor): ...@@ -284,7 +284,7 @@ class DicPredict(BasePredictor):
def pre_deal(self, dic_data): def pre_deal(self, dic_data):
""" """
模型预测不预测空置率大于0.8的列 预测前的预处理, 不预测空置率大于0.8的列
""" """
new_dic_data = {} new_dic_data = {}
for k, v in dic_data.items(): for k, v in dic_data.items():
......
...@@ -176,4 +176,5 @@ def http_server(port): ...@@ -176,4 +176,5 @@ def http_server(port):
if __name__ == '__main__': if __name__ == '__main__':
port = 50053 port = 50053
print("验证服务监听在%d" % port)
http_server(port) http_server(port)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment