Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
lichenggang
/
bom_identify
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
acdc8fe6
authored
May 10, 2021
by
陈森彬
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
f380381f
c6d055f4
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
125 additions
and
3 deletions
README.md
client/client_unittest.py
http_server.py
predic_fac.py
predict/dict_predict.py
valid_server.py
README.md
0 → 100644
View file @
acdc8fe6
# 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
client/client_unittest.py
0 → 100644
View file @
acdc8fe6
#!/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.3
V'
],
'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)
http_server.py
View file @
acdc8fe6
...
@@ -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
)
predic_fac.py
View file @
acdc8fe6
...
@@ -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
:
...
...
predict/dict_predict.py
View file @
acdc8fe6
...
@@ -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
():
...
...
valid_server.py
View file @
acdc8fe6
...
@@ -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
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment