设备名称聚类:增加有设备分类号信息
简 介: 本文在设备名称聚类过程中,增加了设备分类信息。 通过实验可以看到,增加了设备分类信息之后,通过SOM聚类的效果有所提升。在SOM 聚类的基础上,对于聚类前9的子类设备所使用的时间进行分布分析,并给出了指数分布对应的参数以及这些参数随着年份的变化。对应的变化数据背后的物理解释还需要根据设备管理内容做进一步的解释和分析。对于聚类前9个子列的设备名称参见: 设备子类名称 .
关键词
: 设备名称,使用时间,数据分布
§01 设备名称聚类
一、背景介绍
在 设备管理中设备名称聚类分析 对于 来自于 JYH 提供的 五年(2017 - 2021) 中的设备使用时间进行了初步统计,通过讨论,下面计划进行如下几点探究:
- 在聚类中,除了设备名称之外,增加设备的 “分类号” 信息;
- 对于聚类出现的使用时间分布,求取对应的指数分布参数;
- 探究这些参数在 五年变化中的情况。
使用的数据来源:
- 原始的EXCEL表格: 在 设备管理中数据聚类处理-预处理 中的 【1-2-1】中的EXCEL数据文件。
- 预处理后的DOP文档:在 设备管理中设备名称聚类分析 中最开始的插图稳健。
▲ 原始EXCEL表格
▲ 预处理DOP文件
二、数据预处理
1、设备分类号
下面给出了EXCEL表格中提取出来的主要属性字段,第二栏是设备的分类号。
[['12026444' '04060300' '三室真空定向炉 ' '0.0' '科研' 'ZGD-10BYF' '0']
['12005527' '03040404' '光电发射光谱仪' '0.0' '科研' 'PDA-7000' '0']
['07001233' '03040100' '高分辨率磁力显微镜' '0.0' '教学' 'HR-MFM' '0']
['10016800' '03060301' '超高真空电子束镀膜机' '0.0' '科研' 'SCTES-15CUHV' '0']
['12013022' '03060302' '高真空共溅镀仪' '0.0' '科研' 'LJ-103' '0']
['04004740' '03040100' '原子力显微镜' '0.0' '科研' 'MAC-picoplus' '0']
['00001133' '03030226' '热分析系统' '0.0' '公共服务' 'TGA2050' '0']
['02000177' '03052207' '高级扩展流变仪' '0.0' '公共服务' 'MCR300' '0']
['15031006' '04220304' '粉末烧结快速成形机' '0.0' '科研' 'HK S320' '0']
['08005388' '03040702' '场发射扫描电镜' '0.0' '公共服务' 'S-4500' '0']]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
对照 《高等学校固定资产分类与代码》中关于设备标号,分析可知在 EXCEL 表格中的 设备分类号应该对于编号的 8 - 15 位。因此,将分类号前面 8 位,每两位形成一个数字,这样就形成 分类号的 四个属性。
▲ 图1.2.1 高等学校固定资产分类与代码
将上述分类属性加入原来的 150 维度的字典之后,形成最后的名称数据向量。
2、设备属性向量
设备属性向量长度为 154, 分成两段:
- 前 150 维 是名称的矢量,使用来自于名称分词之后,出现频次最高的前 150 个词语进行 one-hot 编码;
- 后 4 维 是来自于设备的分类号所形成的 4个维度。
from headm import *
cutname = tspload('namecut', 'cutname')
attrstr, alldata = tspload('alldata', 'attrstr', 'alldata')
wordall = tspload('word', 'wordall')
dictlen = 150
dictdim = [w[0] for w in wordall[:dictlen]]
namevect = []
matchnum = 0
for id,n in enumerate(cutname):
nn = [s for s in n.split('`') if len(s.strip(' ')) > 0]
classn = alldata[id][1]
nv = []
flag = 0
for d in dictdim:
if d in nn:
nv.append(1)
flag = 1
else:
nv.append(0)
if classn.isdigit() and len(classn) >= 8:
for i in range(4):
nv.append(int(classn[i*2:i*2+2]))
namevect.append(nv)
matchnum += flag
if id % 100 == 0: printf('%d:%d'%(id, matchnum))
printf(matchnum, len(namevect))
tspsave('namevect154', namevect=namevect)
printf(wordall[:100])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
输出的数据文件存储在: namevect154.npz
三、设备聚类分析
1、设备聚类
仍然使用 SOM(自组织特征映射) 网络对于设备名称进行聚类,聚类的结果存储在 prediction.npz中。
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# NAMECLUST.PY -- by Dr. ZhuoQing 2022-08-13
#
# Note:
#============================================================
from headm import *
from sklearn_som.som import SOM
namevect = tspload('namevect154', 'namevect')
SOM_SIDE = 10
VECT_LEN = shape(namevect)[1]
name_som = SOM(m=SOM_SIDE,n=SOM_SIDE,dim=VECT_LEN)
name_som.fit(namevect)
predictions = name_som.predict(namevect)
tspsave('prediction', pred=predictions)
printf('\a')
printf(predictions)
#------------------------------------------------------------
# END OF FILE : NAMECLUST.PY
#============================================================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
2、聚类结果分析
聚类的结果数值为:
190 023 101 123 108 161 071 157 044 564
086 043 038 086 125 058 021 092 004 155
172 064 081 029 037 017 082 275 159 284
101 121 098 075 017 229 088 057 381 023
045 269 228 210 052 178 258 326 022 264
117 149 081 032 071 055 040 092 254 177
010 082 099 035 100 126 055 025 083 222
198 048 060 024 027 000 156 071 134 075
182 170 091 024 290 024 060 057 036 148
191 145 087 045 107 073 086 074 095 356
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
▲ SOM聚类结果命中频率分布
下面给出聚类结果每个子类别命中频次排列,可以相比于只使用设备名称,增加有设备分类号之后的聚类结果,各个子类频次分布更加的均匀了。
[564, 381, 356, 326, 290, 284, 275, 269, 264, 258, 254, 229, 228, 222, 210, 198, 191, 190, 182, 178, 177, 172, 170, 161, 159, 157, 156, 155, 149, 148, 145, 134, 126, 125, 123, 121, 117, 108, 107, 101, 101, 100, 99, 98, 95, 92, 92, 91, 88, 87, 86, 86, 86, 83, 82, 82, 81, 81, 75, 75, 74, 73, 71, 71, 71, 64, 60, 60, 58, 57, 57, 55, 55, 52, 48, 45, 45, 44, 43, 40, 38, 37, 36, 35, 32, 29, 27, 25, 24, 24, 24, 23, 23, 22, 21, 17, 17, 10, 4, 0]
- 1
下面给出了聚类之后,每个子类对应的分布直方图:
▲ 聚类前10个子类使用时间直方图
通过对比,可以看到通过增加设备的分类号属性,自类对应的分布直方图发生了比较大的改变。特别是有些子类的分布已经明显不在属于 指数分布 的情况。
对于每个聚类子类所包含的设备名称可以参见: 增加设备分类号之后,设备名称SOM聚类前九个子类 中给出的结果。
3、指数分布参数
根据 统计数据背后的指数分布模型 中分析所使用的方法, 对于前面每个子类的直方图进行指数分布拟合,从数值上对比它们的分布与整体设备使用时间分布参数之间的差异。
指数分布的公式为如下,它包括两个参数: a , b a,b a,b 。
f B I N [ x ] = a ⋅ e − b x f_{BIN} \left[ x \right] = a \cdot e^{ - bx} fBIN[x]=a⋅e−bx
使用曲线拟合之后,会得到拟合的协方差矩阵,选择矩阵的 [ 0 , 0 ] \left[ {0,0} \right] [0,0] 参数衡量拟合的方差。
所以每个拟合都会包括有三个参数: a,b,c。
(1)所有数据分布参数
下面给出了 11532 个 所有设备记录中指数拟合对应的参数。
- a=3058.687106,
- b=0.000628,
- c=2729.977329
▲ 所有数据使用时间分布
(2)前面九个子类拟合参数
下面给出了聚类后九个子类设备使用时间指数分布的参数。其中参数 b b b 表明了指数衰减的速度。 可以看到,子类3,4,5,9 与前面所有设备使用时间指数分布参数(b=0.000628)相差比较大。 也说明了这些子类对应的分布出现较大的改变。
Class:1 : a=55.428724,b=0.000574,c=14.802819
Class:2 : a=46.119161,b=0.000693,c=5.414357
Class:3 : a=23.076774,b=0.000337,c=12.599779
Class:4 : a=24.558239,b=0.000443,c=4.880937
Class:5 : a=25.932349,b=0.000475,c=11.112023
Class:6 : a=34.804853,b=0.000741,c=3.695121
Class:7 : a=70.947851,b=0.000713,c=7.842925
Class:8 : a=32.410386,b=0.000712,c=5.933429
Class:9 : a=46.866055,b=0.001619,c=10.514767
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
from headm import *
from scipy.optimize import curve_fit
pred = tspload('prediction', 'pred')
cutname = tspload('namecut', 'cutname')
attrstr, alldata = tspload('alldata', 'attrstr', 'alldata')
alltime = array([float(a[3]) for a in alldata])
predlist = list(pred)
neuralcount = [predlist.count(i) for i in range(100)]
sortcount = sorted(zip(neuralcount, list(range(len(neuralcount)))), key=lambda x:x[0], reverse=True)
def linefun(x,a,b):
return a*exp(-b*x)
def histarg(times):
n,bins,patches = plt.hist(times, 50)
param = (1000, 1/2000)
param,conv = curve_fit(linefun, bins[:len(n)], n, p0=param)
return param, conv[0,0]
'''
for i in range(9):
namelist = cutname[pred==sortcount[i][1]]
namelist = list(set(namelist))
printf(' ')
printf("µÚ%dÀ࣬¸öÊý£º%d"%(i+1, len(namelist)))
for id,n in enumerate(namelist[:]):
printf("%d:%s"%(id+1, n.replace('`','')))
'''
startid = 0
for i in range(9):
timelist = alltime[pred==sortcount[i+startid][1]]
p,c = histarg(timelist)
printf('Class:%d : a=%f,b=%f,c=%f'%(i+1, p[0],p[1], c))
plt.subplot(3,3,i+1)
plt.hist(timelist, bins=50)
plt.title('Cluster%d'%(i+1+startid))
plt.grid(True)
plt.tight_layout()
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
4、五年参数变化
下面给出五个年份中,聚类前9类的分布参数变化。
(1)2017年
Class:1 : a=4.303712,b=0.000558,c=0.574744
Class:2 : a=5.646763,b=0.000576,c=0.461199
Class:3 : a=0.054686,b=-0.001343,c=0.025415
Class:4 : a=3.364089,b=0.000385,c=0.350176
Class:5 : a=1.710481,b=0.000374,c=0.217201
Class:6 : a=2.703569,b=0.000630,c=0.229927
Class:7 : a=3.523999,b=0.000680,c=0.271434
Class:8 : a=4.919452,b=0.000667,c=0.318548
Class:9 : a=6.099263,b=0.001885,c=0.395487
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
▲ 前九类的使用时间直方图
(2)2018年
Class:1 : a=11.082655,b=0.000628,c=1.449873
Class:2 : a=5.542356,b=0.000533,c=0.600269
Class:3 : a=1.301268,b=0.000000,c=0.621874
Class:4 : a=3.775829,b=0.000407,c=0.247475
Class:5 : a=1.470281,b=0.000294,c=0.191878
Class:6 : a=3.687083,b=0.000565,c=0.324805
Class:7 : a=1.757018,b=0.000579,c=0.215271
Class:8 : a=5.380325,b=0.000885,c=0.301912
Class:9 : a=5.738048,b=0.001144,c=0.764846
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
▲ 前9类的使用时间直方图分布
(3)2019年
Class:1 : a=9.941127,b=0.000490,c=1.830319
Class:2 : a=9.185210,b=0.000743,c=0.925339
Class:3 : a=5.149620,b=0.000377,c=2.218917
Class:4 : a=3.937046,b=0.000463,c=0.368407
Class:5 : a=2.761374,b=0.000417,c=0.392567
Class:6 : a=3.076290,b=0.000569,c=0.203958
Class:7 : a=8.322417,b=0.000721,c=1.011617
Class:8 : a=3.244339,b=0.000718,c=0.400159
Class:9 : a=8.728649,b=0.001449,c=1.088617
▲ 前9类使用时间直方图分布
(4)2020年
Class:1 : a=12.912565,b=0.000661,c=1.367273
Class:2 : a=6.730126,b=0.000959,c=0.655044
Class:3 : a=2.491172,b=0.000273,c=0.351833
Class:4 : a=5.787558,b=0.000558,c=0.424540
Class:5 : a=5.555084,b=0.000646,c=1.012982
Class:6 : a=11.111490,b=0.001216,c=0.466180
Class:7 : a=7.001535,b=0.000846,c=1.079377
Class:8 : a=3.837694,b=0.000703,c=0.348361
Class:9 : a=14.503558,b=0.005887,c=1.182979
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
▲ 前9类使用时间直方图
(5)2021年
Class:1 : a=11.325222,b=0.000508,c=1.001180
Class:2 : a=10.648516,b=0.000669,c=0.754177
Class:3 : a=3.490508,b=0.000261,c=0.660059
Class:4 : a=5.144351,b=0.000365,c=0.361800
Class:5 : a=5.075366,b=0.000384,c=0.640348
Class:6 : a=9.072253,b=0.000852,c=0.850641
Class:7 : a=18.321294,b=0.000744,c=1.620445
Class:8 : a=4.038257,b=0.000563,c=0.457812
Class:9 : a=12.378903,b=0.002631,c=2.029987
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
▲ 前九类子类别使用时间分布直方图
5、各个子类参数变化
上面是对于每一年中各个子类的使用时间直方图分布以及对应的指数参数进行的显示。下面对各个参数在五年之内的变化统一进行比较。
(1)参数A变化
参数A对应指数参数的 幅值。
▲ 参数A在五年之内的变化
(2)参数B变化
参数b, 对于 指数分布的 衰减率, 在每个子类对应的五之间的变化。
▲ 参数B在五年之内的变化
(3)参数C变化
参数C表征了指数分布拟合方差,对应了分布与指数分布之间的差异大小。
▲ 参数C在五年之内的变化
※ 总 结 ※
本文在设备名称聚类过程中,增加了设备分类信息。 通过实验可以看到,增加了设备分类信息之后,通过SOM聚类的效果有所提升。在SOM 聚类的基础上,对于聚类前9的子类设备所使用的时间进行分布分析,并给出了指数分布对应的参数以及这些参数随着年份的变化。
对应的变化数据背后的物理解释还需要根据设备管理内容做进一步的解释和分析。
对于聚类前9个子列的设备名称参见: 设备子类名称 .
■ 相关文献链接:
● 相关图表链接:
- 原始EXCEL表格
- 预处理DOP文件
- 图1.2.1 高等学校固定资产分类与代码
- SOM聚类结果命中频率分布
- 聚类前10个子类使用时间直方图
- 所有数据使用时间分布
- 前九类的使用时间直方图
- 前9类的使用时间直方图分布
- 前9类使用时间直方图分布
- 前9类使用时间直方图
- 前九类子类别使用时间分布直方图
- 参数A在五年之内的变化
- 参数B在五年之内的变化
- 参数C在五年之内的变化
▲ 图2.1 处理所使用的程序和中间结果
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# CLUSTANALY.PY -- by Dr. ZhuoQing 2022-08-11
#
# Note:
#============================================================
from headm import *
from scipy.optimize import curve_fit
pred = tspload('prediction', 'pred')
cutname = tspload('namecut', 'cutname')
attrstr, alldata = tspload('alldata', 'attrstr', 'alldata')
#------------------------------------------------------------
yearnum = [1731, 1965, 2201, 2631, 3003]
printf(sum(yearnum))
#------------------------------------------------------------
alltime = array([float(a[3]) for a in alldata])
predlist = list(pred)
neuralcount = [predlist.count(i) for i in range(100)]
sortcount = sorted(zip(neuralcount, list(range(len(neuralcount)))), key=lambda x:x[0], reverse=True)
#------------------------------------------------------------
def linefun(x,a,b):
return a*exp(-b*x)
def histarg(times):
n,bins,patches = plt.hist(times, 50)
param = (1000, 1/2000)
param,conv = curve_fit(linefun, bins[:len(n)], n, p0=param)
return param, conv[0,0]
#p,c = histarg(alltime)
#printf('All: a=%f,b=%f,c=%f'%(p[0],p[1], c))
#------------------------------------------------------------
'''
for i in range(9):
namelist = cutname[pred==sortcount[i][1]]
namelist = list(set(namelist))
printf(' ')
printf("第%d类,个数:%d"%(i+1, len(namelist)))
for id,n in enumerate(namelist[:]):
printf("%d:%s"%(id+1, n.replace('`','')))
'''
#------------------------------------------------------------
startid = 0
yearid = 4
yearaccul = [sum(yearnum[:id+1]) for id in range(5)]
startend = [(yearaccul[id-1] if id>0 else 0, yearaccul[id]) for id in range(5)]
printf(startend)
#------------------------------------------------------------
'''
for i in range(9):
tt = alltime[startend[yearid][0]:startend[yearid][1]]
pp = pred[startend[yearid][0]:startend[yearid][1]]
timelist = tt[pp==sortcount[i+startid][1]]
# p,c = histarg(timelist)
# printf('Class:%d : a=%f,b=%f,c=%f'%(i+1, p[0],p[1], c))
plt.subplot(3,3,i+1)
plt.hist(timelist, bins=50)
plt.title('Cluster%d'%(i+1+startid))
plt.grid(True)
plt.tight_layout()
plt.show()
'''
#------------------------------------------------------------
yeararg = []
for yearid in range(5):
classarg = []
for i in range(9):
tt = alltime[startend[yearid][0]:startend[yearid][1]]
pp = pred[startend[yearid][0]:startend[yearid][1]]
timelist = tt[pp==sortcount[i+startid][1]]
p,c = histarg(timelist)
printf('Class:%d : a=%f,b=%f,c=%f'%(i+1, p[0],p[1], c))
classarg.append((p[0],p[1],c))
yeararg.append(classarg)
#------------------------------------------------------------
tspsave('yeararg9', yeararg = yeararg)
printf(yeararg)
#------------------------------------------------------------
plt.clf()
year = [2017,2018,2019,2020,2021]
for i in range(9):
plt.subplot(3,3,i+1)
plt.plot(year, [y[i][2] for y in yeararg])
plt.xlabel("Year")
plt.ylabel("C")
plt.title('Cluster:%d'%(i+1))
plt.grid(True)
plt.tight_layout()
plt.show()
#------------------------------------------------------------
# END OF FILE : CLUSTANALY.PY
#============================================================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
文章来源: zhuoqing.blog.csdn.net,作者:卓晴,版权归原作者所有,如需转载,请联系作者。
原文链接:zhuoqing.blog.csdn.net/article/details/126316416
- 点赞
- 收藏
- 关注作者
评论(0)