用Python做SVD文档聚类---奇异值分解----文档相似性----LSI(潜在语义分析)
转载请注明出处:电子科技大学EClab——落叶花开http://www.cnblogs.com/nlp-yekai/p/3848528.html
SVD,即奇异值分解,在自然语言处理中,用来做潜在语义分析即LSI,或者LSA。最早见文章
An introduction to latent semantic analysis
SVD的有关资料,从很多大牛的博客中整理了一下,然后自己写了个python版本,放上来,跟大家分享~
关于SVD的讲解,参考博客
本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用,但请注明出处,如果有问题,请联系wheeleast@gmail.com
python的拓展包numpy,scipy都能求解SVD,基于numpy写了一个文档做svd的程序。首先将每篇文档向量化,然后对向量化后的文档集合做SVD,取计算后的矩阵U,进行分析。先上代码:
#coding=utf-8
import re
import math
import numpy as np
import matplotlib.pylab as plt def f_file_open(trace_string):
"""open the document_set, save in the list called txt"""
f=open(trace_string,'r')
txt=f.readlines()
f.close()
return txt def f_vector_found(txt):
"""calculate all of the word in the document set---构造词空间"""
word_list=[]
for line in txt:
line_clean=line.split()
for word in line_clean:
if word not in word_list:
word_list.append(word)
else:
pass
return word_list def f_document_vector(document,word_list):
"""transform the document to vector---文档向量化"""
vector=[]
document_clean=document.split()
for word in word_list:
a=document_clean.count(word)
vector.append(a)
return vector def f_svd_calculate(document_array):
"""calculate the svd and return the three matrics"""
U,S,V=np.linalg.svd(document_array)
return (U,S,V) def f_process_matric_U(matric_U,Save_N_Singular_value):
"""according to the matric U, choose the words as the feature in each document,根据前N个奇异值对U进行切分,选择前N列"""
document_matric_U=[]
for line in matric_U:
line_new=line[:Save_N_Singular_value]
document_matric_U.append(line_new)
return document_matric_U def f_process_matric_S(matric_S,Save_information_value):
"""choose the items with large singular value,根据保留信息需求选择奇异值个数"""
matricS_new=[]
S_self=0
N_count=0
Threshold=sum(matric_S)*float(Save_information_value)
for value in matric_S:
if S_self<=Threshold:
matricS_new.append(value)
S_self+=value
N_count+=1
else:
break
print ("the %d largest singular values keep the %s information " %(N_count,Save_information_value))
return (N_count,matricS_new) def f_process_matric_V(matric_V,Save_N_Singular_value):
"""according to the matric V, choose the words as the feature in each document,根据前N个奇异值对U进行切分,选择前N行"""
document_matric_V=matric_V[:Save_N_Singular_value]
return document_matric_V def f_combine_U_S_V(matric_u,matric_s,matirc_v):
"""calculate the new document对奇异值筛选后重新计算文档矩阵""" new_document_matric=np.dot(np.dot(matric_u,np.diag(matric_s)),matirc_v)
return new_document_matric def f_matric_to_document(document_matric,word_list_self):
"""transform the matric to document,将矩阵转换为文档"""
new_document=[]
for line in document_matric:
count=0
for word in line:
if float(word)>=0.9: #转换后文档中词选择的阈值
new_document.append(word_list_self[count]+" ")
else:
pass
count+=1
new_document.append("\n")
return new_document def f_save_file(trace,document):
f=open(trace,'a')
for line in document:
for word in line:
f.write(word) trace_open="/home/alber/experiment/test.txt"
trace_save="/home/alber/experiment/20140715/svd_result1.txt"
txt=f_file_open(trace_open)
word_vector=f_vector_found(txt)
print (len(word_vector)) document=[]
Num_line=0
for line in txt: #transform the document set to matric
Num_line=Num_line+1
document_vector=f_document_vector(line,word_vector)
document.append(document_vector)
print (len(document))
U,S,V=f_svd_calculate(document)
print (sum(S))
N_count,document_matric_S=f_process_matric_S(S,0.9)
document_matric_U=f_process_matric_U(U,N_count)
document_matric_V=f_process_matric_V(V,N_count)
print (len(document_matric_U[1]))
print (len(document_matric_V))
new_document_matric=f_combine_U_S_V(document_matric_U,document_matric_S,document_matric_V)
print (sorted(new_document_matric[1],reverse=True))
new_document=f_matric_to_document(new_document_matric,word_vector)
f_save_file(trace_save,new_document)
print ("the new document has been saved in %s"%trace_save)
第一篇文档对应的向量的结果如下图(未列完,已排序):
[1.0557039715196566, 1.0302828340480468, 1.0177955652284856, 1.0059864028992798, 0.99050787479103541, 0.93109816291875147, 0.70360233131357808, 0.22614603502510683, 0.10577134907675778, 0.098346889985350489, 0.091221506093784849, 0.085227549911874326, 0.052355994530275715, 0.049805639460153352, 0.046430974364203001, 0.046430974364203001, 0.045655634442695908, 0.043471974743277547, 0.041953839699628029, 0.041483792741663243, 0.039635143169293147, 0.03681955156197822, 0.034893319065413916, 0.0331697465114036, 0.029874818442883051, 0.029874818442883051, 0.028506042937487715, 0.028506042937487715, 0.027724455461901349, 0.026160357130229708, 0.023821284531034687, 0.023821284531034687, 0.017212073571417009, 0.016793815602261938, 0.016793815602261938, 0.016726955476865021, 0.015012207148054771, 0.013657280765244915。。。。。
基于这样一种结果,要对分解后的矩阵进行分析,如上图,值越大,表明该位置的词对该文档贡献越大,而值越小则该词无意义,因而,下一步就是设定阈值,取每一篇文档的特征词,至于阈值的设定,有很多种方法,可以对所有值进行排序,取拐点。如图(不是上面的结果做出来的图):

显然,只有拐点以后的值对文档的贡献较高,而拐点以后的值变为0,这样,一个文档--词矩阵就通过SVD分解而降低了维度。
这个过程中,有两个认为设定的参数,一个是奇异值的选择,如上图(右):奇异值下降较快,而其中前N个奇异值已经能够代替整个矩阵大部分的的信息。在我的程序中,通过设定需要保留的信息比率(保留90%或者95%或者其他等等)来控制奇异值个数。
另一个需要设定的就是在对上图(左),对于重新构造的矩阵,要用来代替原来的文档矩阵,需要对词进行选择,上面已经说过的,取拐点值是一种。
词--文档矩阵的SVD分解基本上就是这些内容。欢迎纠错和吐槽。
用Python做SVD文档聚类---奇异值分解----文档相似性----LSI(潜在语义分析)的更多相关文章
- [原创博文] 用Python做统计分析 (Scipy.stats的文档)
[转自] 用Python做统计分析 (Scipy.stats的文档) 对scipy.stats的详细介绍: 这个文档说了以下内容,对python如何做统计分析感兴趣的人可以看看,毕竟Python的库也 ...
- Kmeans文档聚类算法实现之python
实现文档聚类的总体思想: 将每个文档的关键词提取,形成一个关键词集合N: 将每个文档向量化,可以参看计算余弦相似度那一章: 给定K个聚类中心,使用Kmeans算法处理向量: 分析每个聚类中心的相关文档 ...
- Python爬虫、自动化常用库&帮助文档URL
一.Python下载地址 Windows终端Cmder.exe下载--->http://cmder.net/ Python下载(Windows) ---> https://w ...
- 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档
孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...
- Python之文件处理-批量修改md文档内容
目录 Python之文件处理-批量修改md文档内容 Python之文件处理-批量修改md文档内容 #!/usr/bin/env python # -*- coding:utf-8 -*- import ...
- 【技术博客】利用Python将markdown文档转为html文档
利用Python将markdown文档转为html文档 v1.0 作者:FZK 元素简单的md文件 Python中自带有一个markdown库,你可以直接这样使用 md_file = open(&qu ...
- docfx 做一个和微软一样的文档平台
开发中,有一句话叫 最不喜欢的是写文档,最不喜欢的是看别人家代码没有文档.那么世界上文档写最 la 好 ji 的就是微软了,那么微软的api文档是如何做的?难道请了很多人去写文档? 实际上微软有工具用 ...
- k-means+python︱scikit-learn中的KMeans聚类实现( + MiniBatchKMeans)
来源:, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, ...
- 使用python做科学计算
这里总结一个guide,主要针对刚开始做数据挖掘和数据分析的同学 说道统计分析工具你一定想到像excel,spss,sas,matlab以及R语言.R语言是这里面比较火的,它的强项是强大的绘图功能以及 ...
随机推荐
- Sql Server实现多行数据按分组用逗号分隔成一行数据
例如,要将下面的数据 以GROUP_ID进行分组,一组一行,一组中的多个PRODUCT_ID用逗号分隔,select 出来成如下结果: 在Sql Server中,我目前想到的一种方法是写一个函数,如下 ...
- Microsoft Push Notification Service(MPNS)的最佳体验
如何获得 Microsoft Push Notification Service(MPNS)的最佳体验 有很多同学抱怨MPNS的各种问题,其中包括服务超时.返回各种错误代码不知如何处理等等..今天我用 ...
- 译文:User-agent的历史
这是一篇译文,译文出处在文章底部贴出.由于技术水平,英语水平,翻译水平有限,请各路大侠多多指正,谢谢,提高你也提高我:) 几个礼拜之前,我谈论了特征检测和浏览器检测.这篇帖子提到了一点点嗅探U ...
- Android开发过程中git、repo、adb、grep等指令的使用
chown 是一条在Unix系统中用于设置文件所有者和文件关联组的命令. 需要超级用户的权限才能执行此命令.只有超级用户和属于组的文件所有者才能变更文件关联组.非特权用户(非超级用户)如需要设置关联组 ...
- GC算法精解(五分钟教你终极算法---分代搜集算法)
GC算法精解(五分钟教你终极算法---分代搜集算法) 引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们 ...
- WCF引用方式
WCF之各种WCF引用方式 写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法. 准备工作: 1.创建解决方案WCFS ...
- 创建简单的响应式HTML5模版
创建简单的响应式HTML5模版 HTML5目前发展势头良好,已经逐渐得到大部分浏览器不同程度的支持.许多web开发者也已经学习到了不少关于HTML 5的基础知识并开始试图使用HTML 5制作网页.与此 ...
- 三千万数据量下redis2.4的一统计情况
先说一下工作场景,要求做一个服务,满足:处理千万级别数据,单个请求响应时间在20ms以下.由于是存储的数据格式为key:list[],所以很适合使用redis来存放数据,为了测试一下redis存储的效 ...
- ONLY三行脚本 SQL数据恢复到指定时间点
经常看到有人误删数据,或者误操作,特别是Update和Delete的时候没有加WHERE ... 然后就喊爹喊娘了,怕是亲爹妈也无奈摇肩. 话说,如果没有犯过错误,那你还算是程序猿(媛)麽?!没了偶尔 ...
- log4net 开箱即用
废话少说,先上代码 log4net Demo 好的系统都有日志,log4net 是我在.net平台下用过最爽的日志库,简单易用.功能强大. 基于配置(配置很简单,一看就明,通用,拷去即用): 可同时保 ...