热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LSA和SVD两种矩阵分解

谈谈SVD和LSA首先SVD和LSA是什么呢,SVD全称是singularvaluedecomposition,就是俗称的奇异值分解,SV

谈谈SVD和LSA











首先SVD和LSA是什么呢,SVD全称是singular value decomposition,就是俗称的奇异值分解,SVD的用处有很多,比如可以做PCA(主成分分析),做图形压缩,做LSA,那LSA是什么呢,LSA全称Latent semantic analysis,中文的意思是隐含语义分析,LSA算是topic model的一种,对于LSA的直观认识就是文章里有词语,而词语是由不同的主题生成的,比如一篇文章包含词语计算机,另一篇文章包含词语电脑,在一般的向量空间来看,这两篇文章不相关,但是在LSA看来,这两个词属于同一个主题,所以两篇文章也是相关的。





特征值特征向量





要谈到SVD,特征值和特征向量是需要首先交代的。具体内容可以在wiki上看,这里我做个简单的介绍。对于方阵M如果有





M∗v=λ∗v

v是个向量,λ是个数,那么我们称v是M的特征向量,λ是M的特征值,并且我们可以对M进行特征分解得到





M=Q∗Λ∗Q−1

其中Q是特征向量组成的矩阵,Λ是对角阵,对角线上的元素就是特征值。对于特征的几何理解就是矩阵M其实是一种线性变换,而线性变换对于向量的影响有两种,旋转和拉伸,而特征向量就是在这种线性变换下方向保持不变的向量,但是长度还是会作相应的拉伸,特征值就是拉伸的程度。





从另一个角度说如果我们取特征值比较大的几项,那么就是对原矩阵做了一种近似。





M≈Q1..k∗Λ1..k∗Q−11..k

这样我们就可以用更少的元素去近似的表示原矩阵,但是特征分解的限制比较多,比如要求矩阵必须是方阵





奇异值分解





wiki是个好东西,你要想深入了解的话,建议还是去看wiki。奇异值分解是将矩阵变成了这样的形式





M=U∗Σ∗VT

其中Σ依旧是对角阵,而U和V是正交矩阵正交矩阵是说U∗UT=I。





我们还是先回到矩阵是线性变换这个思路上。














如果我们用M去作用空间里的一组基,那么我们就会得到另一组基,如上图那样。那么我们旋转一下最初的一组基。














这样我们经过M的变换由一组正交基变换到了另一组正交基上面。也是也就是下面这样。














也就是我们有





M∗v1=σ1∗u1

M∗v2=σ2∗u2

并且对于任意一个向量x,我们有





x=v1∗(vT1∗x)+v2∗(vT2∗x)

于是我们可以得到





M∗x=M∗v1∗(vT1∗x)+M∗v2∗(vT2∗x)

M∗x=σ1∗u1∗(vT1∗x)+σ2∗u2∗(vT2∗x)

M=σ1∗u1∗vT1+σ2∗u2∗vT2

M=U∗Σ∗VT

恩,我们得到了和特征值和特征向量相似的东西,SVD分解出来的就是在M的线性变换下,正交基变换仍是正交基,而奇异值就是拉伸的程度。其实SVD和特征值和特征向量的关系还是很大的。





M∗MT=U∗Σ∗VT∗V∗ΣT∗UT

M∗MT=U∗Σ2∗UT

也就是说SVD求出的是M∗MT和MT∗M的特征向量。同样的得到这SVD分解这种形式后我们就可以利用他来对原数据进行降维操作。














这里我们分别将RBG矩阵进行SVD,左上角的是原图,其他的依次是取最大的100个,50个,20个,10个,5个奇异值做的近似图像。



# -*- coding: utf-8 -*-from scipy import linalg, dot
from PIL import Imagedef main(num&#61;5):im &#61; Image.open(&#39;ai.jpg&#39;)pix &#61; im.load()ma &#61; [[], [], []]for x in xrange(im.size[0]):for i in xrange(3):ma[i].append([])for y in xrange(im.size[1]):for i in xrange(3):ma[i][-1].append(pix[x, y][i])for i in xrange(3):u, s, v &#61; linalg.svd(ma[i])u &#61; u[:, :num]v &#61; v[:num, :]s &#61; s[:num]ma[i] &#61; dot(dot(u, linalg.diagsvd(s, num, num)), v)for x in xrange(im.size[0]):for y in xrange(im.size[1]):ret &#61; []for i in xrange(3):tmp &#61; int(ma[i][x][y])if tmp <0:tmp &#61; 0if tmp > 255:tmp &#61; 255ret.append(tmp)pix[x, y] &#61; tuple(ret)im.show()im.save(&#39;test.jpg&#39;)if __name__ &#61;&#61; &#39;__main__&#39;:main()






如果对矩阵先进行归一化&#xff0c;再SVD就是PCA的形式了&#xff0c;这种形式可以用方差最大化或者误差最小化来求得&#xff0c;具体可以去看PCA相关的东西。所以和scturtle讨论了下直接SVD的意义&#xff0c;但是最后也没得出什么结论。。。





隐含语义分析





终于讲到最后的隐含语义分析了&#xff0c;首先我们构造文本和词语的矩阵&#xff0c;也就是对于矩阵来说每一个向量表示一篇文章&#xff0c;每个向量里就是单词的出现次数(更好的是每个是单词的tf/idf值&#xff0c;tf/idf不在赘述&#xff0c;具体可以看wiki)。那么SVD分解之后&#xff0c;我们就得到了降维的矩阵&#xff0c;就是下面这个样子













就是说原来我们有1000000篇文章&#xff0c;总共有500000个单词&#xff0c;我们保留最大的100个来做降维&#xff0c;于是现在我们可以这样理解&#xff0c;我们保留了100个主题&#xff0c;其中U是文章对应的主题分布&#xff0c;而V则是主题对应的词语的分布&#xff0c;这样&#xff0c;我们可以减少噪音&#xff0c;并且这样计算文章间的相关性也更加合理&#xff0c;并且可以把相关的单词聚合到一起。代码如下





# -*- coding: utf-8 -*-import os
import re
import heapq
import codecs
from math import log
from scipy import linalgimport unigram_good_turing as segseg.init()def tfidf(docs):doclen &#61; len(docs)&#43;1.0for doc in docs:wordtotal &#61; sum(doc.values())&#43;0.0for word in doc:tf &#61; doc[word]/wordtotalidf &#61; log(doclen/(sum([word in tmp for tmp in docs])&#43;1))doc[word] &#61; tf*idfreturn docsdef solve(data):re_zh, re_other &#61; re.compile(ur"([\u4E00-\u9FA5]&#43;)"), re.compile(ur"[^a-zA-Z0-9&#43;#\n]")blocks &#61; re_zh.split(data)for item in blocks:if re_zh.match(item):for i in seg.solve(item):yield ielse:tmp &#61; re_other.split(item)for x in tmp:if x !&#61; &#39;&#39;:passdef show(dic, p):p &#61; heapq.nlargest(10, enumerate(p), key&#61;lambda x:x[1])print &#39; &#39;.join(map(lambda x:dic[x[0]], p))def main():names &#61; os.listdir(&#39;text&#39;)dic &#61; {}cnt &#61; 0ma &#61; []for name in names:data &#61; codecs.open(&#39;text/&#39;&#43;name, &#39;r&#39;, &#39;utf-8&#39;).read()doc &#61; {}for word in solve(data):if not word in dic:dic[word] &#61; cntcnt &#43;&#61; 1tmp &#61; dic[word]if tmp not in doc:doc[tmp] &#61; 0doc[tmp] &#43;&#61; 1ma.append(doc)ma &#61; tfidf(ma)ret &#61; []for item in ma:tmp &#61; []for i in xrange(cnt):if i in item:tmp.append(item[i])else:tmp.append(0)ret.append(tmp)u, s, v &#61; linalg.svd(ret)for i in xrange(10):show(dict(zip(dic.values(), dic.keys())), list(v[i]))if __name__ &#61;&#61; &#39;__main__&#39;:main()





推荐阅读
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
author-avatar
手机用户2602921555
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有