这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的:

 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结合提高聚类效果的更多相关文章

  1. 【原】KMeans与深度学习模型结合提高聚类效果

    这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的: id goods_name goods_amount 男士手袋 1882.0 淑女装 2491.0 女士手袋 345.0 ...

  2. 深度学习的集成方法——Ensemble Methods for Deep Learning Neural Networks

    本文主要参考Ensemble Methods for Deep Learning Neural Networks一文. 1. 前言 神经网络具有很高的方差,不易复现出结果,而且模型的结果对初始化参数异 ...

  3. 【AI in 美团】深度学习在文本领域的应用

    背景 近几年以深度学习技术为核心的人工智能得到广泛的关注,无论是学术界还是工业界,它们都把深度学习作为研究应用的焦点.而深度学习技术突飞猛进的发展离不开海量数据的积累.计算能力的提升和算法模型的改进. ...

  4. 深度学习 CNN CUDA 版本2

    作者:zhxfl 邮箱:zhxfl##mail.ustc.edu.cn 主页:http://www.cnblogs.com/zhxfl/p/4155236.html 第1个版本blog在这里:http ...

  5. 深度学习GPU集群管理软件 OpenPAI 简介

    OpenPAI:大规模人工智能集群管理平台 2018年5月22日,在微软举办的“新一代人工智能开放科研教育平台暨中国高校人工智能科研教育高峰论坛”上,微软亚洲研究院宣布,携手北京大学.中国科学技术大学 ...

  6. 深度学习笔记之CNN(卷积神经网络)基础

    不多说,直接上干货! 卷积神经网络(ConvolutionalNeural Networks,简称CNN)提出于20世纪60年代,由Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经 ...

  7. arcpy地理处理工具案例教程-生成范围-自动画框-深度学习样本提取-人工智能-AI

    arcpy地理处理工具案例教程-生成范围-自动画框-深度学习样本提取-人工智能-AI 商务合作,科技咨询,版权转让:向日葵,135-4855_4328,xiexiaokui#qq.com 目的:对面. ...

  8. 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 ...

  9. DDos攻击,使用深度学习中 栈式自编码的算法

    转自:http://www.airghc.top/2016/11/10/Dection-DDos/ 最近研究了一篇论文,关于检测DDos攻击,使用了深度学习中 栈式自编码的算法,现在简要介绍一下内容论 ...

随机推荐

  1. Linux-3.0.8中基于S5PV210的GPIO模块代码追踪和分析

    编写按键驱动时,想知道内核是如何管理GPIO的,所以开始追踪代码,中间走了一些弯路,现记录于此. 追踪代码之前,我猜测:第一,这部分代码应该在系统set up阶段执行:第二,GPIO的代码应该在mac ...

  2. Python成绩雷达图

    代码 import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.rcParams['font.fa ...

  3. 《高质量C++&C 编程指南》学习笔记

    这本电子书是在国科大上课时候,老师在课件资源里边提供的.之所以会重视这个文件,是因为本科时候,有个老师提到过:那个学生遍的代码很整齐,看起来让人舒服,我就知道工大留不下他.因此,我就格外注意这件事,但 ...

  4. 《JavaScript》高级程序设计第21章:Ajax和Comet,jsonp

    一.创建XMLHttpRequest对象 二.XHR的用法 五.跨域资源共享 六.其他跨域技术七.安全七.安全 1. 图像Ping 2. JSONP(JSON with padding,填充式JSON ...

  5. 前端框架本质之探究——以Vue.js为例

    问:我们在使用Vue时,实际上干了什么?   答:实际上只干了一件事——new了一个Vue对象.后面的事,都交由这个对象自动去做.就好像按了下开关,机器跑起来了,剩下的事就不用我们再操心了.   各位 ...

  6. Javascript高级编程学习笔记(23)—— 函数表达式(1)递归

    前面的文章中,我在介绍JS中引用类型的时候提过,JS中函数有两种定义方式 第一种是声明函数,即使用function关键字来声明 第二种就是使用函数表达式,将函数以表达式的形式赋值给一个变量,这个变量就 ...

  7. JavaScript实现input输入框限制输入值的功能

    限制只能输入正整数 <input type="text" onkeyup="if(this.value.length==1){this.value=this.val ...

  8. oracle select in超过1000条报错解决方法

    本博客介绍oracle select in超过1000条数据的解决方法,java框架是采用mybatis的,这可以说是一种比较常见的错误:select * from A where id in(... ...

  9. Aseprite+Cocos:打包像素画图,导入到cocos里并动起来

    前言:Aseprite入门教程            Aseprite入门:第一个gif动图 1.制作像素画: 按照上一次的小球跳动制作过程,先制作一个像素画动画: 若是导出gif动态图,效果如下: ...

  10. 神经网络架构PYTORCH-前馈神经网络

    首先要熟悉一下怎么使用PyTorch来实现前馈神经网络吧.为了方便理解,我们这里只拿只有一个隐藏层的前馈神经网络来举例: 一个前馈神经网络的源码和注释如下:比较简单,这里就不多介绍了. class N ...