【原】KMeans与深度学习自编码AutoEncoder结合提高聚类效果
这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的:
- id goods_name goods_amount
- 男士手袋 1882.0
- 淑女装 2491.0
- 女士手袋 345.0
- 基础内衣 328.0
- 商务正装 4985.0
- 时尚 969.0
- 女饰品 86.0
- 专业运动 399.0
- 童装(中大童) 2033.0
- 男士配件 38.0
我们看到同一个id下面有不同的消费记录,这个数据不能直接拿来用,写了python程序来进行处理:test.py
- #!/usr/bin/python
- #coding:utf-8
- #Author:Charlotte
- import pandas as pd
- import numpy as np
- import time
- #加载数据文件(你可以加载自己的文件,文件格式如上所示)
- x=pd.read_table('test.txt',sep = " ")
- #去除NULL值
- x.dropna()
- a1=list(x.iloc[:,0])
- a2=list(x.iloc[:,1])
- a3=list(x.iloc[:,2])
- #A是商品类别
- dicta=dict(zip(a2,zip(a1,a3)))
- A=list(dicta.keys())
- #B是用户id
- B=list(set(a1))
- # data_class = pd.DataFrame(A,lista)
- #创建商品类别字典
- a = np.arange(len(A))
- lista = list(a)
- dict_class = dict(zip(A,lista))
- print dict_class
- f=open('class.txt','w')
- for k ,v in dict_class.items():
- f.write(str(k)+'\t'+str(v)+'\n')
- f.close()
- #计算运行时间
- start=time.clock()
- #创建大字典存储数据
- dictall = {}
- for i in xrange(len(a1)):
- if a1[i] in dictall.keys():
- value = dictall[a1[i]]
- j = dict_class[a2[i]]
- value[j] = a3[i]
- dictall[a1[i]]=value
- else:
- value = list(np.zeros(len(A)))
- j = dict_class[a2[i]]
- value[j] = a3[i]
- dictall[a1[i]]=value
- #将字典转化为dataframe
- dictall1 = pd.DataFrame(dictall)
- dictall_matrix = dictall1.T
- print dictall_matrix
- end = time.clock()
- print "赋值过程运行时间是:%f s"%(end-start)
输出结果:
- {'\xe4\xb8\x93\xe4\xb8\x9a\xe8\xbf\x90\xe5\x8a\xa8': 4, '\xe7\x94\xb7\xe5\xa3\xab\xe6\x89\x8b\xe8\xa2\x8b': 1, '\xe5\xa5\xb3\xe5\xa3\xab\xe6\x89\x8b\xe8\xa2\x8b': 2, '\xe7\xab\xa5\xe8\xa3\x85\xef\xbc\x88\xe4\xb8\xad\xe5\xa4\xa7\xe7\xab\xa5)': 3, '\xe7\x94\xb7\xe5\xa3\xab\xe9\x85\x8d\xe4\xbb\xb6': 9, '\xe5\x9f\xba\xe7\xa1\x80\xe5\x86\x85\xe8\xa1\xa3': 8, '\xe6\x97\xb6\xe5\xb0\x9a': 6, '\xe6\xb7\x91\xe5\xa5\xb3\xe8\xa3\x85': 7, '\xe5\x95\x86\xe5\x8a\xa1\xe6\xad\xa3\xe8\xa3\x85': 5, '\xe5\xa5\xb3\xe9\xa5\xb0\xe5\x93\x81': 0}
- 0 1 2 3 4 5 6 7 8 9
- 1 0 1882 0 0 0 0 0 0 0 0
- 2 0 0 345 0 0 0 0 2491 0 0
- 4 0 0 0 0 0 0 0 0 328 0
- 5 86 0 0 0 0 4985 969 0 0 0
- 6 0 0 0 2033 399 0 0 0 0 38
- 赋值过程运行时间是:0.004497 s
- linux环境下字符编码不同,class.txt:
- 专业运动 4
- 男士手袋 1
- 女士手袋 2
- 童装(中大童) 3
- 男士配件 9
- 基础内衣 8
- 时尚 6
- 淑女装 7
- 商务正装 5
- 女饰品 0
- 得到的dicta_matrix 就是我们拿来跑数据的格式,每一列是商品名称,每一行是用户id
现在我们来跑AE模型(Auto-encoder),简单说说AE模型,主要步骤很简单,有三层,输入-隐含-输出,把数据input进去,encode然后再decode,cost_function就是output与input之间的“差值”(有公式),差值越小,目标函数值越优。简单地说,就是你输入n维的数据,输出的还是n维的数据,有人可能会问,这有什么用呢,其实也没什么用,主要是能够把数据缩放,如果你输入的维数比较大,譬如实际的特征是几千维的,全部拿到算法里跑,效果不见得好,因为并不是所有特征都是有用的,用AE模型后,你可以压缩成m维(就是隐含层的节点数),如果输出的数据和原始数据的大小变换比例差不多,就证明这个隐含层的数据是可用的。这样看来好像和降维的思想类似,当然AE模型的用法远不止于此,具体贴一篇梁博的博文
不过梁博的博文是用c++写的,这里使用python写的代码(开源代码,有少量改动):
- #/usr/bin/python
- #coding:utf-8
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- from sklearn import preprocessing
- class AutoEncoder():
- """ Auto Encoder
- layer 1 2 ... ... L-1 L
- W 0 1 ... ... L-2
- B 0 1 ... ... L-2
- Z 0 1 ... L-3 L-2
- A 0 1 ... L-3 L-2
- """
- def __init__(self, X, Y, nNodes):
- # training samples
- self.X = X
- self.Y = Y
- # number of samples
- self.M = len(self.X)
- # layers of networks
- self.nLayers = len(nNodes)
- # nodes at layers
- self.nNodes = nNodes
- # parameters of networks
- self.W = list()
- self.B = list()
- self.dW = list()
- self.dB = list()
- self.A = list()
- self.Z = list()
- self.delta = list()
- for iLayer in range(self.nLayers - 1):
- self.W.append( np.random.rand(nNodes[iLayer]*nNodes[iLayer+1]).reshape(nNodes[iLayer],nNodes[iLayer+1]) )
- self.B.append( np.random.rand(nNodes[iLayer+1]) )
- self.dW.append( np.zeros([nNodes[iLayer], nNodes[iLayer+1]]) )
- self.dB.append( np.zeros(nNodes[iLayer+1]) )
- self.A.append( np.zeros(nNodes[iLayer+1]) )
- self.Z.append( np.zeros(nNodes[iLayer+1]) )
- self.delta.append( np.zeros(nNodes[iLayer+1]) )
- # value of cost function
- self.Jw = 0.0
- # active function (logistic function)
- self.sigmod = lambda z: 1.0 / (1.0 + np.exp(-z))
- # learning rate 1.2
- self.alpha = 2.5
- # steps of iteration 30000
- self.steps = 10000
- def BackPropAlgorithm(self):
- # clear values
- self.Jw -= self.Jw
- for iLayer in range(self.nLayers-1):
- self.dW[iLayer] -= self.dW[iLayer]
- self.dB[iLayer] -= self.dB[iLayer]
- # propagation (iteration over M samples)
- for i in range(self.M):
- # Forward propagation
- for iLayer in range(self.nLayers - 1):
- if iLayer==0: # first layer
- self.Z[iLayer] = np.dot(self.X[i], self.W[iLayer])
- else:
- self.Z[iLayer] = np.dot(self.A[iLayer-1], self.W[iLayer])
- self.A[iLayer] = self.sigmod(self.Z[iLayer] + self.B[iLayer])
- # Back propagation
- for iLayer in range(self.nLayers - 1)[::-1]: # reserve
- if iLayer==self.nLayers-2:# last layer
- self.delta[iLayer] = -(self.X[i] - self.A[iLayer]) * (self.A[iLayer]*(1-self.A[iLayer]))
- self.Jw += np.dot(self.Y[i] - self.A[iLayer], self.Y[i] - self.A[iLayer])/self.M
- else:
- self.delta[iLayer] = np.dot(self.W[iLayer].T, self.delta[iLayer+1]) * (self.A[iLayer]*(1-self.A[iLayer]))
- # calculate dW and dB
- if iLayer==0:
- self.dW[iLayer] += self.X[i][:, np.newaxis] * self.delta[iLayer][:, np.newaxis].T
- else:
- self.dW[iLayer] += self.A[iLayer-1][:, np.newaxis] * self.delta[iLayer][:, np.newaxis].T
- self.dB[iLayer] += self.delta[iLayer]
- # update
- for iLayer in range(self.nLayers-1):
- self.W[iLayer] -= (self.alpha/self.M)*self.dW[iLayer]
- self.B[iLayer] -= (self.alpha/self.M)*self.dB[iLayer]
- def PlainAutoEncoder(self):
- for i in range(self.steps):
- self.BackPropAlgorithm()
- print "step:%d" % i, "Jw=%f" % self.Jw
- def ValidateAutoEncoder(self):
- for i in range(self.M):
- print self.X[i]
- for iLayer in range(self.nLayers - 1):
- if iLayer==0: # input layer
- self.Z[iLayer] = np.dot(self.X[i], self.W[iLayer])
- else:
- self.Z[iLayer] = np.dot(self.A[iLayer-1], self.W[iLayer])
- self.A[iLayer] = self.sigmod(self.Z[iLayer] + self.B[iLayer])
- print "\t layer=%d" % iLayer, self.A[iLayer]
- data=[]
- index=[]
- f=open('./data_matrix.txt','r')
- for line in f.readlines():
- ss=line.replace('\n','').split('\t')
- index.append(ss[0])
- ss1=ss[1].split(' ')
- tmp=[]
- for i in xrange(len(ss1)):
- tmp.append(float(ss1[i]))
- data.append(tmp)
- f.close()
- x = np.array(data)
- #归一化处理
- xx = preprocessing.scale(x)
- nNodes = np.array([ 10, 5, 10])
- ae3 = AutoEncoder(xx,xx,nNodes)
- ae3.PlainAutoEncoder()
- ae3.ValidateAutoEncoder()
- #这是个例子,输出的结果也是这个
- # xx = np.array([[0,0,0,0,0,0,0,1], [0,0,0,0,0,0,1,0], [0,0,0,0,0,1,0,0], [0,0,0,0,1,0,0,0],[0,0,0,1,0,0,0,0], [0,0,1,0,0,0,0,0]])
- # nNodes = np.array([ 8, 3, 8 ])
- # ae2 = AutoEncoder(xx,xx,nNodes)
- # ae2.PlainAutoEncoder()
- # ae2.ValidateAutoEncoder()
这里我拿的例子做的结果,真实数据在服务器上跑,大家看看这道啥意思就行了
- [0 0 0 0 0 0 0 1]
- layer=0 [ 0.76654705 0.04221051 0.01185895]
- layer=1 [ 4.67403977e-03 5.18624788e-03 2.03185410e-02 1.24383559e-02
- 1.54423619e-02 1.69197292e-03 2.34471751e-05 9.72956513e-01]
- [0 0 0 0 0 0 0]
- layer=0 [ 0.08178768 0.96348458 0.98583155]
- layer=1 [ 8.18926274e-04 7.30041977e-04 1.06452565e-02 9.94423121e-03
- 3.47329848e-03 1.32582980e-02 9.80648863e-01 8.42319408e-08]
- [0 0 0 0 0 0 0]
- layer=0 [ 0.04752084 0.01144966 0.67313608]
- layer=1 [ 4.38577163e-03 4.12704649e-03 1.83408905e-02 1.59209302e-05
- 2.32400619e-02 9.71429772e-01 1.78538577e-02 2.20897151e-03]
- [0 0 0 0 0 0 0]
- layer=0 [ 0.00819346 0.37410028 0.0207633 ]
- layer=1 [ 8.17965283e-03 7.94760145e-03 4.59916741e-05 2.03558668e-02
- 9.68811657e-01 2.09241369e-02 6.19909778e-03 1.51964053e-02]
- [0 0 0 0 0 0 0]
- layer=0 [ 0.88632868 0.9892662 0.07575306]
- layer=1 [ 1.15787916e-03 1.25924912e-03 3.72748604e-03 9.79510789e-01
- 1.09439392e-02 7.81892291e-08 1.06705286e-02 1.77993321e-02]
- [0 0 0 0 0 0 0]
- layer=0 [ 0.9862938 0.2677048 0.97331042]
- layer=1 [ 6.03115828e-04 6.37411444e-04 9.75530999e-01 4.06825647e-04
- 2.66386294e-07 1.27802666e-02 8.66599313e-03 1.06025228e-02]
可以很明显看layer1和原始数据是对应的,所以我们可以把layer0作为降维后的新数据。
最后在进行聚类,这个就比较简单了,用sklearn的包,就几行代码:
- # !/usr/bin/python
- # coding:utf-8
- # Author :Charlotte
- from matplotlib import pyplot
- import scipy as sp
- import numpy as np
- import matplotlib.pyplot as plt
- from sklearn.cluster import KMeans
- from scipy import sparse
- import pandas as pd
- import Pycluster as pc
- from sklearn import preprocessing
- from sklearn.preprocessing import StandardScaler
- from sklearn import metrics
- import pickle
- from sklearn.externals import joblib
- #加载数据
- data = pd.read_table('data_new.txt',header = None,sep = " ")
- x = data.ix[:,1:141]
- card = data.ix[:,0]
- x1 = np.array(x)
- xx = preprocessing.scale(x1)
- num_clusters = 5
- clf = KMeans(n_clusters=num_clusters, n_init=1, n_jobs = -1,verbose=1)
- clf.fit(xx)
- print(clf.labels_)
- labels = clf.labels_
- #score是轮廓系数
- score = metrics.silhouette_score(xx, labels)
- # clf.inertia_用来评估簇的个数是否合适,距离越小说明簇分的越好
- print clf.inertia_
- print score
这个数据是拿来做例子的,维度少,效果不明显,真实环境下的数据是30W*142维的,写的mapreduce程序进行数据处理,然后通过AE模型降到50维后,两者的clf.inertia_和silhouette(轮廓系数)有显著差异:
clf.inertia_ |
silhouette |
|
base版本 |
252666.064229 |
0.676239435 |
AE模型跑后的版本 |
662.704257502 |
0.962147623 |
所以可以看到没有用AE模型直接聚类的模型跑完后的clf.inertia_比用了AE模型之后跑完的clf.inertia_大了几个数量级,AE的效果还是很显著的。
以上是随手整理的,如有错误,欢迎指正:)
【原】KMeans与深度学习自编码AutoEncoder结合提高聚类效果的更多相关文章
- 【原】KMeans与深度学习模型结合提高聚类效果
这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的: id goods_name goods_amount 男士手袋 1882.0 淑女装 2491.0 女士手袋 345.0 ...
- 深度学习的集成方法——Ensemble Methods for Deep Learning Neural Networks
本文主要参考Ensemble Methods for Deep Learning Neural Networks一文. 1. 前言 神经网络具有很高的方差,不易复现出结果,而且模型的结果对初始化参数异 ...
- 【AI in 美团】深度学习在文本领域的应用
背景 近几年以深度学习技术为核心的人工智能得到广泛的关注,无论是学术界还是工业界,它们都把深度学习作为研究应用的焦点.而深度学习技术突飞猛进的发展离不开海量数据的积累.计算能力的提升和算法模型的改进. ...
- 深度学习 CNN CUDA 版本2
作者:zhxfl 邮箱:zhxfl##mail.ustc.edu.cn 主页:http://www.cnblogs.com/zhxfl/p/4155236.html 第1个版本blog在这里:http ...
- 深度学习GPU集群管理软件 OpenPAI 简介
OpenPAI:大规模人工智能集群管理平台 2018年5月22日,在微软举办的“新一代人工智能开放科研教育平台暨中国高校人工智能科研教育高峰论坛”上,微软亚洲研究院宣布,携手北京大学.中国科学技术大学 ...
- 深度学习笔记之CNN(卷积神经网络)基础
不多说,直接上干货! 卷积神经网络(ConvolutionalNeural Networks,简称CNN)提出于20世纪60年代,由Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经 ...
- arcpy地理处理工具案例教程-生成范围-自动画框-深度学习样本提取-人工智能-AI
arcpy地理处理工具案例教程-生成范围-自动画框-深度学习样本提取-人工智能-AI 商务合作,科技咨询,版权转让:向日葵,135-4855_4328,xiexiaokui#qq.com 目的:对面. ...
- Predicting effects of noncoding variants with deep learning–based sequence model | 基于深度学习的序列模型预测非编码区变异的影响
Predicting effects of noncoding variants with deep learning–based sequence model PDF Interpreting no ...
- DDos攻击,使用深度学习中 栈式自编码的算法
转自:http://www.airghc.top/2016/11/10/Dection-DDos/ 最近研究了一篇论文,关于检测DDos攻击,使用了深度学习中 栈式自编码的算法,现在简要介绍一下内容论 ...
随机推荐
- Windows批处理命令学习中遇到的坑--持续更新中
再次拾起windows批处理命令,下边将一些遇到的小问题写出来,希望可以帮到大家 1.set命令:set主要的作用是为变量赋值,类似于编程语言中的var i = Value:但是在使用的过程中一定要注 ...
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- 查询树节点、oracle、select...start with...connect by prior...
通过子节点向根节点追朔. select * from persons.dept start with deptid=76 connect by prior paredeptid=deptid 通过根节 ...
- 自定义Token的CAS登录
工作中实际遇到的需求,我们有一个旧系统,用了CAS的单点登录,现在有一个外部系统,准备从它那里单点进来,这个外部系统提供了一个token参数来标记这是哪一个用户,我们用他们提供的方式解析出对应的用户, ...
- 关于 Block 中捕获 self 的分析
问题 最近遇到一个已经使用了weak-strong dance的block依旧强引用了self的情况,好在block没被VC持有只是延迟释放,但这里的关键是用了weak_self的blcok理应不会强 ...
- redis主从架构,分片集群详解
写在前面:这篇笔记有点长,如果你认真看完,收获会不少,如果你只是忘记了相关命令,请翻到末尾. redis的简单介绍: 一个提供多种数据类类型储存,整个系统都在内存中运行的, 定期通过异步的方式把数据刷 ...
- FFmpeg 学习(三):将 FFmpeg 移植到 Android平台
首先需要去FFmpeg的官网http://www.ffmpeg.org/去下载FFmpeg的源码,目前的版本号为FFmpeg3.3(Hilbert). 下载的文件为压缩包,解压后得到ffmpeg-3. ...
- nginx安装配置并布置网站
之前做的网站都是用的apache,关于apache和Nginx的区别也不说了,百度上也都有,而且apche和nginx可以共存,这个之后再说. 首先安装nginx,我用的云主机,直接用yum安装 #y ...
- 判断浏览器是否支持HTML5 video
话不多说,下面是我从W3C扒的判断浏览器是是否支持H5视频的代码,有需要的小伙伴,拿走不谢 HTML <div id="checkVideoResult"><bu ...
- dubbo实用知识点总结(三)
1. 服务降级 2. 优雅停机 3. 主机绑定 4. 访问日志 5. Multicast注册中心 6. zookeeper注册中心 7. 推荐用法 8. 容量规划 9. 基准测试工具包