lucene学习教程
1Lucene的介绍
①Lucene是什么:
是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎
②Lucene有什么用
Lucene是一个高性能、可伸缩的信息搜索(IR)库。它可以为你的应用程序添加索引和搜索能力,和对搜索词进行分析过滤
③Lucene怎么用
// Lucene使用步骤
// 1创建索引
// 1.1创建索引目录
Directory directory=FSDirectory.open(new File("indexDir"));
// 1.2创建indexWriter
IndexWriterConfig conf=new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35));
IndexWriter indexWriter=new IndexWriter(directory, conf);
// 1.3创建document
Document document=new Document();
// 1.4为document指定不同的域(Field)
document.add(new Field("fileName","java.txt",Store.YES,Index.ANALYZED));
document.add(new NumericField("creatDate",Store.YES,true).setLongValue(new Date().getTime()));
document.add(new NumericField("size",Store.YES,true).setDoubleValue(10101.22));
document.add(new Field("content",FileUtils.readFileToString(new File("java.txt")),Store.NO,Index.ANALYZED));
// 1.5使用indexWriter.add(doc)方法,添加索引
indexWriter.addDocument(document);
// 1.6关闭indexWriter
indexWriter.close();
// 2搜索索引
// 2.1指定索引存放位置
Directory indexDirectory=FSDirectory.open(new File("indexDir"));
// 2.2创建indexReader
IndexReader indexReader=IndexReader.open(indexDirectory);
// 2.3创建indexSearcher
IndexSearcher indexSearcher=new IndexSearcher(indexReader);
// 2.4创建query
Query query=new TermQuery(new Term("fileName","java"));
// 2.5根据indexSearcher.seacher(query,maxDoc);获取topDocs
TopDocs topDocs = indexSearcher.search(query, 100);
// 2.6根据topDocs获取ScoreDocs[]
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
// 2.7遍历ScoreDocs[]获取docId
for (ScoreDoc scoreDoc : scoreDocs) {
int docId=scoreDoc.doc;
// 2.8根据docId调用indexSearcher.doc(docId)方法获取一个document
Document doc = indexSearcher.doc(docId);
// 2.9对document进行解析,获取需要的值
System.out.println("fileName-->"+document.get("fileName")+"createDate--->"+new Date(Long.parseLong(doc.get("createDate"))));
}
// 3.0关闭indexSearcher和indexReader
indexSearcher.close();
indexReader.close();
2Lucene的组成
①索引
I索引建立的主要流程
// 1指定索引的存放目录
Directory directory=FSDirectory.open(new File("paht"));//硬盘
// //OR
Directory directory2=new RAMDirectory();//内存
// 2创建indexWriter
IndexWriterConfig conf=new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35));
IndexWriter indexWriter=new IndexWriter(directory, conf);
// 3创建文档(document)(对于数据库而言,一个条记录就是一个文档,对于文件而言,一个文件就是一个文档)
// 1.3创建document
Document document=new Document();
// 4为文档指定域(Field)(对于数据库而言,域相当于字段,对于文件而言域相当于属性)
document.add(new Field("fileName","java.txt",Store.YES,Index.ANALYZED));
document.add(new NumericField("creatDate",Store.YES,true).setLongValue(new Date().getTime()));
document.add(new NumericField("size",Store.YES,true).setDoubleValue(10101.22));
document.add(new Field("content",FileUtils.readFileToString(new File("java.txt")),Store.NO,Index.ANALYZED));
// 5添加索引
indexWriter.addDocument(document);
II、重要类的介绍
directory
是用来指定索引的存放位置,可以是内存也可以是硬盘,FSDirectory.open(new File("paht")),会根据本地文件系统,自动选择一种最合适的方式存储索引
indexWriter
是用来对索引的进行增删改的重要操作类
Document
document对象对于数据库而言,一个条记录就是一个document,对于文件而言,一个文件就是一个document
Field
Field对象对于数据库而言,Field相当于字段(例如 name、age、、、、),对于文件而言Field相当于属性(例如文件名(name)..)
子类NumericField是用来存储数据类型的的字段的值,例如int 、long、double、,还有日期可以转换为long型后存储
II索引的增删改
①增加索引
indexWriter.addDocument(document);
②删除索引
//删除索引
indexWriter.deleteDocuments(new Term("fileName","java"));//删除文件名等于Java的document--删除后只是放在一个临时文档里,不被检索,并没有真正删除
indexWriter.forceMergeDeletes();//强制把删除的document删除掉
③更新索引
//更新索引--索引的更新原理:1根据query删除掉对应document,然后再把新的document放进去
indexWriter.updateDocument(new Term("fileName","java"), document);
III索引的权重
//①对于默认情况下,索引的排序是按照评分来排序的,评分公式是Score=Score*Boot ,
//分数*权重,只要保证Boot的足够大,那么对应搜索的document就会排在第一位
//设置权重的办法是:
document.setBoost(1000F);
②分词
I分词运行流程分析
①searchWord首先会被Tokenizer分成一个一个的语汇单元,
②然后会经过一系列的TokenFilter(分词过滤器),过滤掉没意义的分词,例如“的,啊 ”这些感叹词
③经过一系列TokenFilter后,返回一个TokenStream,就是一个分词字符流,流里存有分词个各种信息
如下图:
II分词的类介绍
1Analyzer:分词器,是一个抽象类
//其主要包含两个接口,用于生成TokenStream:
TokenStream tokenStream(String fieldName, Reader reader);
TokenStream reusableTokenStream(String fieldName, Reader reader) ;
//为了提高性能,在同一个线程中无需再生成新的TokenStream对象,旧的可以被重用,reusableTokenStream是获取当前线程TokenSteam。
2Tokenizer
Tokenizer继承与TokenStream,是用来对searchWord的reader流进行分词,把searchWord分成一个一个的语汇单元
3TokenFilter
TokenFilter,过滤分词后的语汇单元,
主要方法incrementToken(),可以依次遍历语汇单元的信息
4TokenStream
分词字符流,流里存有分词个各种信息
例如:CharTermAttribute、OffsetAttribute、PositionIncrementAttribute、TypeAttribute、、等等
III扩展分词器
基本原理:就是使用自定义分词器的扩展原生analyzer的构造方法,然后用analyzer对应的Tokenizer分词,然后再使用自定义的TokenFilter过滤业务逻辑数据,
1自定义一个类继承analyzer
public class MyAnalyzer extends Analyzer {}
2实现tokenStream方法
public class MyAnalyzer extends Analyzer {
@Override
public TokenStream tokenStream(String arg0, Reader reader) {
return null;
}
}
3自定义TokenFilter
package com.lucence.analyzer; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack; import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
/**
* 自定义分词过滤器
* 1自定义类继承TokenFilter
* 2实现指定的方法-incrementToken
* 3在incrementToken里会遍历所有被分词的词汇单元,
* 4实现自己的业务逻辑
*
*/
public class MyAnalyzerFilter extends TokenFilter {
private CharTermAttribute cta;
private PositionIncrementAttribute pia;
private State state;
private Stack<String> sameWordStack;
protected MyAnalyzerFilter(TokenStream input) {
super(input);
this.cta=input.addAttribute(CharTermAttribute.class);
this.pia=input.addAttribute(PositionIncrementAttribute.class);
sameWordStack=new Stack<String>();
} @Override
public boolean incrementToken() throws IOException {
if(sameWordStack.size()>0){
String pop = sameWordStack.pop();
//恢复状态
restoreState(state);
cta.setEmpty();
cta.append(pop);
pia.setPositionIncrement(0);
//System.out.print("["+cta+"]"+pia.getPositionIncrement()); System.out.println(state.hashCode());
return true;
}
if (!input.incrementToken()) {
return false;
}
if(getSameWorder(cta.toString())){
//捕获当前状态
state=captureState();
}
return true;
}
/**
* 同义词处理--数据
*/
private Boolean getSameWorder(String key){
//1申明一个map存放同义词---模拟数据库
Map<String, String[]> map=new HashMap<String, String[]>();
map.put("我",new String[]{"咱","吾","俺"});
map.put("中国",new String[]{"大陆","天朝"});
String[] strings = map.get(key);
if(strings!=null&&strings.length>0){
for (int i = 0; i < strings.length; i++) {
sameWordStack.push(strings[i]);
}
return true;
}else{
return false;
}
}
}
4使用自定义的TokenFilter返回处理后的TokenStream
public class MyAnalyzer extends Analyzer {
@Override
public TokenStream tokenStream(String arg0, Reader reader) {
return new MyAnalyzerFilter(new IKTokenizer(reader,false));
}
}
③搜索
I搜索的运行流程
// 1.1指定索引存放位置
Directory indexDirectory=FSDirectory.open(new File("indexDir"));
// 1.2创建indexReader---indexReader.openIfChanged(oldReader),监听索引是否有改变,若索引有改变则重新获取indexReader
IndexReader indexReader=IndexReader.open(indexDirectory);
// 1.3创建indexSearcher
IndexSearcher indexSearcher=new IndexSearcher(indexReader);
// 1.4创建query
Query query=new TermQuery(new Term("fileName","java"));
// 1.5根据indexSearcher.seacher(query,maxDoc);获取topDocs
TopDocs topDocs = indexSearcher.search(query, 100);
// 1.6根据topDocs获取ScoreDocs[]
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
// 1.7遍历ScoreDocs[]获取docId
for (ScoreDoc scoreDoc : scoreDocs) {
int docId=scoreDoc.doc;
// 1.8根据docId调用indexSearcher.doc(docId)方法获取一个document
Document doc = indexSearcher.doc(docId);
// 1.9对document进行解析,获取需要的值
System.out.println("fileName-->"+doc.get("fileName")+"createDate--->"+new Date(Long.parseLong(doc.get("createDate"))));
}
// 2.0关闭indexSearcher和indexReader
indexSearcher.close();
indexReader.close();
IIquery类的介绍
①termQuery:精确查询 new term(field,value)
②termRangeQuery:字符串范围查询new TermRangeQuery(field, lowerTerm, upperTerm, includeLower, includeUpper)
③NumericRange:数字范围查询,NumericRangeQuery.newTRange(field, min, max, minInclusive, maxInclusive)--T代表泛型
④QueryParser:
⑤prefixQuery:前缀查询--new PrefixQuery(new term(field,prefix))
⑥wildCartQuery:通配符查询--new wildCartQuery(new term(field,value))---value已经包含通配符,例如"*bb*",查找包含bb的数据
⑦BooleanQuery:条件查询,可以连接多个多个条件
例如:
BooleanQuery booleanQuery=new BooleanQuery();
booleanQuery.add(query1,occur)
booleanQuery.add(query2,occur)
booleanQuery.add(query3,occur)
occur的值说明
must:一定,必须有,相当于数据库的and
should:可能有,,相当于数据库的or
MUST_NOT:一定没有,不存在,相当于数据库的不等于
⑧FuzzyQuery:模糊查询,
new FuzzyQuery(term, minimumSimilarity),可以 设置minimumSimilarity来设置匹配程度,越高匹配程度越高,
new FuzzyQuery(new term("name","bbcs"), minimumSimilarity)---含有bbc或者bbXs会被匹配出来
⑨phraseQuery:语义查询,对于中文,使用作用不大,
PhraseQuery phraseQuery=new PhraseQuery();
// 1设置跳跃的范围
phraseQuery.setSlop(2);
//2设置开始的单词
phraseQuery.add(new Term("content","i"));
// 3设置结束的单词
phraseQuery.add(new Term("content","you"));
//例如包含i love you的内容将会出来
III扩展queryParse类
package com.lucence.query; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.util.Version; /**
* 扩展queryParse类
* queryParse的查询的原理:先对查询的字符串进行分析,然后再使用对应的query去查询,
* 例如有通配符字符,就添加wildCartQuery去查询 ,如果*这些的,就添加FuzzyQuery去查询
* 也就说,如果我们想扩展queryParse的查询,那么可以自定义一个类,然后继承queryParse的,然后重构对应的getxxxquery()方法,并且在里面实现业务逻辑,则就可以实现扩展queryParse的功能
*/
//1第一步自定义类继承Lucene的queryParse
public class myQueryParse extends QueryParser { //2选择一个重写一个构造方法
public myQueryParse(Version matchVersion, String f, Analyzer a) {
super(matchVersion, f, a);
}
//3重写对应的getXXQuery方法--并且在方法里实现业务逻辑
/**
* field--搜索域
* termStr---搜索值
*/
@Override
protected org.apache.lucene.search.Query getWildcardQuery(String field,
String termStr) throws ParseException {
if(termStr.indexOf("?")!=-1){
throw new ParseException("不能使用通配符查询");
}
return super.getWildcardQuery(field, termStr);
}
/**
* field--搜索域
* termStr---搜索值
*/
@Override
protected org.apache.lucene.search.Query getFuzzyQuery(String field,
String termStr, float minSimilarity) throws ParseException {
return super.getFuzzyQuery(field, termStr, minSimilarity);
}
}
IV排序与分页
排序:
//①排序:默认是根据score排序,score默认是=score(关联性)*boot(权重)
SortField sortField1=new SortField("fileName",SortField.STRING,true);//content--"字段名称", ,SortField.STRING-"字段在存放时的类型",true--是否反转
SortField sortField2=new SortField("size",SortField.INT,false);//content--"字段名称", ,SortField.BYTE-"字段在存放时的类型",true--是否反转
Sort sort=new Sort(sortField1,sortField2);
TopDocs topDocs = searcher.search(query,10,sort);
分页:
//1searchAfter(scoreDocAfter, query, pagezie)方法是每次返回scoreDocAfter后面的document,
int docId=(pagezie-1)*pageNumber-1;//每次查询是记录开始行
ScoreDoc scoreDocAfter=new ScoreDoc(docId,0f);
TopDocs topDocs = searcher.searchAfter(scoreDocAfter, query, pagezie);
V搜索过滤器
package com.lucence.searchFilter; import java.io.IOException; import org.apache.lucene.document.Document;
import org.apache.lucene.index.AbstractAllTermDocs;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.Filter;
import org.apache.lucene.util.OpenBitSet;
/**
* 自定义搜索过滤器
* 1新建一个类继承Lucene的Filter
* 2实现getDocIdSet方法
* 3根据indexReader获取到返回的document
* 4根据自己的业务逻辑处理后返回DocIdSet
* @author Jeremy
*
*/
public class MySearchFilter extends Filter { @SuppressWarnings("unused")
@Override
public DocIdSet getDocIdSet(IndexReader indexReader)
throws IOException {
// TODO Auto-generated method stub
int maxDoc = indexReader.maxDoc();//获取返回document的数目
OpenBitSet docIdSet=new OpenBitSet(maxDoc);//默认是64位大小,但是如果超出没报异常,所以一般在indexReader里获取返回document的大小
//docIdSet是一个相当于一个列表--如下面
//status document
// 0 docId
// 1 docId
//若status是0 ,则document将不会被显示出来,
//也就说,我们在filter把不需要的document可以过滤掉
//1填满列表---默认是空
docIdSet.set(0, maxDoc);
//2获取返回的document
//2.1直接使用indexReader来获取符合过滤条件的document
//TermDocs---存储了两个变量,一个是返回的docId数组,一个每个document出现"javass.txt"的频率次数
TermDocs termDocs =indexReader.termDocs(new Term("content","jeremy"));
while (termDocs.next()) {
System.out.println(termDocs.doc());
Document document = indexReader.document(termDocs.doc());
System.out.println("fileName"+document.get("fileName")+"---出现频率:"+termDocs.freq()+"---被过滤掉了");
docIdSet.clear(termDocs.doc());//clear()方法相当于把status设置为0
}
return docIdSet;
} }
VI自定义评分
实现步骤:
* 自定义评分
* 默认的评分机制是 score=score*Root = 分数*索引的权重
* 自定义评分的实现流程
* 1新建一个类及承诺CustomScoreQuery
* 2覆盖CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery)的构造方法--ValueSourceQuery:评分域查询对象
* 3覆盖 getCustomScoreProvider(IndexReader reader)方法
* 4新建一个类继承CustomScoreProvider
* 5覆盖CustomScoreProvider的customScore(int doc, float subQueryScore, float valSrcScore)方法,
* --------doc:docId,subQueryScore:原有评分,valSrcScore:我们自定义传入的评分
* 6在customScore(int doc, float subQueryScore, float valSrcScore)方法里返回经过业务逻辑处理的的自定义评分
* 7在getCustomScoreProvider返回自定的义的MyCustomScoreProvider对象
* 8在查询中使用MyCustomerScroeQuery
代码示例:
package com.lucence.scoreQuery;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.function.CustomScoreProvider;
import org.apache.lucene.search.function.CustomScoreQuery;
import org.apache.lucene.search.function.ValueSourceQuery;
/**
* 自定义评分
* 默认的评分机制是 score=score*Root = 分数*索引的权重
* 自定义评分的实现流程
* 1新建一个类及承诺CustomScoreQuery
* 2覆盖CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery)的构造方法--ValueSourceQuery:评分域查询对象
* 3覆盖 getCustomScoreProvider(IndexReader reader)方法
* 4新建一个类继承CustomScoreProvider
* 5覆盖CustomScoreProvider的customScore(int doc, float subQueryScore, float valSrcScore)方法,
* --------doc:docId,subQueryScore:原有评分,valSrcScore:我们自定义传入的评分
* 6在customScore(int doc, float subQueryScore, float valSrcScore)方法里返回经过业务逻辑处理的的自定义评分
* 7在getCustomScoreProvider返回自定的义的MyCustomScoreProvider对象
* 8在查询中使用MyCustomerScroeQuery
* @author Jeremy
*
*/
// 1新建一个类及承诺CustomScoreQuery
public class MyCustomerScroeQuery extends CustomScoreQuery {
//2覆盖CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery)的构造方法--ValueSourceQuery:评分域查询对象
public MyCustomerScroeQuery(Query subQuery, ValueSourceQuery valSrcQuery) {
super(subQuery, valSrcQuery);
}
public MyCustomerScroeQuery(Query subQuery) {
super(subQuery);
}
@Override
//3覆盖 getCustomScoreProvider(IndexReader reader)方法
protected CustomScoreProvider getCustomScoreProvider(IndexReader reader)throws IOException {
//7在getCustomScoreProvider返回自定的义的MyCustomScoreProvider对象
return new MyCustomScoreProvider(reader);
} }
package com.lucence.scoreQuery; import java.io.IOException; import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.function.CustomScoreProvider;
// 4新建一个类继承CustomScoreProvide
public class MyCustomScoreProvider extends CustomScoreProvider{ public MyCustomScoreProvider(IndexReader reader) {
super(reader);
}
@Override
/**
* 5覆盖CustomScoreProvider的customScore(int doc, float subQueryScore, float valSrcScore)方法,
* --------doc:docId,subQueryScore:原有评分,valSrcScore:我们自定义传入的评分
*/
//subQueryScore * valSrcScore;---默认的评分是原有的评分乘以评分域的的值
public float customScore(int doc, float subQueryScore, float valSrcScore)
throws IOException {
//6在customScore方法里返回业务逻辑处理后的自定义评分
System.out.println(subQueryScore+"------"+valSrcScore);
Document document = reader.document(doc);
if(document.get("fileName").endsWith(".txt")){//文件类型为。txt的优先排序
return subQueryScore*valSrcScore*100;
}
return super.customScore(doc, subQueryScore, valSrcScore);
}
}
使用代码示例:
public void test01(){
//3.1指定搜索目录
try {
Directory directory=FSDirectory.open(new File("C:/lucence/index"));
//3.2创建索引读取器(IndexReader)
IndexReader indexReader=IndexReader.open(directory);
//3.3根据IndexReader创建索引搜索器(indexSeacher)
IndexSearcher searcher=new IndexSearcher(indexReader);
//3.4创建查询器query----使用QueryParser的parser()方法创建--创建query
Query query=null;
QueryParser parser=new QueryParser(Version.LUCENE_35,"content",new StandardAnalyzer(Version.LUCENE_35));
query=parser.parse("spring");
// //3.4.2c创建评分域---可以使用评分域去评分,也可以不使用----评分域的得类型必须是数据类型---
// FieldScoreQuery fieldScoreQuery=new FieldScoreQuery("fileName",Type.BYTE);
// //3.4.3使用MyCustomerScroeQuery来构建query
// MyCustomerScroeQuery myCustomerScroeQuery = new MyCustomerScroeQuery(query, fieldScoreQuery);
MyCustomerScroeQuery myCustomerScroeQuery=new MyCustomerScroeQuery(query);
//3.5使用自定义的myCustomerScroeQuery进行查询过,IndexSeacher执行查询,并获取返回TopDocs---文档集合
TopDocs topDocs = searcher.search(myCustomerScroeQuery,100);
//3.6根据TopDocs(文档集合)获取scoreDocs---分数文档
ScoreDoc[] scoreDocs=topDocs.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) {
//3.7根据ScoreDocs的doc Id在indexSeacher(索引搜索器)中获取文档对象,
Document doc = searcher.doc(scoreDoc.doc);
//3.8解析文档对象,获取对应的值
System.out.println(doc.get("fileName")+"["+doc.get("dir")+"]"+doc.getBoost());
} //3.9关闭索引读取器
indexReader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
lucene学习教程的更多相关文章
- Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息
Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息 在此回复牛妞的关于程序中分词器的问题,其实可以直接很简单的在词库中配置就好了,Lucene中分词的所有信息我们都可以从 ...
- Deep Learning 19_深度学习UFLDL教程:Convolutional Neural Network_Exercise(斯坦福大学深度学习教程)
理论知识:Optimization: Stochastic Gradient Descent和Convolutional Neural Network CNN卷积神经网络推导和实现.Deep lear ...
- WebPack 简明学习教程
WebPack 简明学习教程 字数1291 阅读22812 评论11 喜欢35 WebPack是什么 一个打包工具 一个模块加载工具 各种资源都可以当成模块来处理 网站 http://webpack. ...
- MyBatis入门学习教程-使用MyBatis对表执行CRUD操作
上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...
- 深入浅出的javascript的正则表达式学习教程
深入浅出的javascript的正则表达式学习教程 阅读目录 了解正则表达式的方法 了解正则中的普通字符 了解正则中的方括号[]的含义 理解javascript中的元字符 RegExp特殊字符中的需要 ...
- 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- LaTeX学习教程
本来我对LaTeX不是看好的,毕竟都是命令格式的.觉得有word就足够啦word可视化操作方便快捷. 但是由于要写论文等,在导师要求下潜心学习一下,不知不觉间被LaTeX的强大功能所吸引.现在很多出版 ...
- Deep Learning 13_深度学习UFLDL教程:Independent Component Analysis_Exercise(斯坦福大学深度学习教程)
前言 理论知识:UFLDL教程.Deep learning:三十三(ICA模型).Deep learning:三十九(ICA模型练习) 实验环境:win7, matlab2015b,16G内存,2T机 ...
- Deep Learning 12_深度学习UFLDL教程:Sparse Coding_exercise(斯坦福大学深度学习教程)
前言 理论知识:UFLDL教程.Deep learning:二十六(Sparse coding简单理解).Deep learning:二十七(Sparse coding中关于矩阵的范数求导).Deep ...
随机推荐
- Teigha.NET开发入门1- Teigha介绍
对于CAD开发,无疑较强大的方式是Lisp.AutoCAD二次开发,且学习资源丰富,依靠强大的AutoCAD的环境可以干很多事,省很多力.但若要脱离AutoCAD环境,那就当属Teigha了. 名称问 ...
- 使用pyenv安装多个Python版本
pyenv是一个便于使用多版本Python环境的工具 pyenv使用shell脚本编写的,只需要下载就可以使用了,不需要root用户,这个我比较喜欢. 具体介绍看网址:https://github.c ...
- 市场风险~VaR的概述
1.概念理解 VaR的含义:Value at Risk 按字面的解释就是"处于风险状态的价值",可译为受险价值.在险价值.风险价值等. 通常解释为:VaR是在一定置信水平和一定持有 ...
- 微信SDK登录无法调起,微信SDK无法接收回调的几种解决办法
今天有位同事请求帮忙调试微信登录问题,他遇到了以下2个问题,所以,写篇日志备忘,如果有其它朋友遇到此类问题,都可以照此解决! 平时在开发中,有些开发者经常会遇到微信登录SDK登录时,无法调起微信客户端 ...
- AI创业的技术方案选择
观察了许多初创公司技术方案的选择,我总结基本遵循8个字:快速灵活,物美价廉.我们也应该根据自身实际情况,跳出束缚与时俱进,选择智能互联网时代最有力的技术和工具. 基础编程语言 候选者:C#/C++/P ...
- WCF Restful Service Get / Post请求
Rest 它是用于创建分布式超文本媒体的一种架构方式,我们可以通过标准的HTTP(GET,POST,PUT,DELETE)操作来构建基于面向资源的软件架构方式(Resource-Oriented Ar ...
- Android studio Program type already present: com.****.BuildConfig
Android studio 抛错,是因为有2个module在 AndroidManifest.xml 里面具有一样的package name,修改不同名字即可. 还有一种情况是多个module对同一 ...
- Mysql中NUMERIC和DECIMAL类型区别比较
decimal(numeric ) 同义,用于精确存储数值 . decimal 数据类型最多可存储 38 个数字,所有数字都能够放到小数点的右边.decimal 数据类型存储了一个准确(精确)的数字表 ...
- 基于properties文件的Spring Boot多环境切换
当我们使用properties文件作为Spring Boot的配置文件而不是yaml文件时,怎样实现多环境使用不同的配置信息呢? 在Spring Boot中,多环境配置的文件名需要满足appl ...
- 程序猿必备的10款超有趣的SVG绘制动画赏析
SVG作为时下比较新颖的技术标准,已经建立了很多基于SVG的前端项目.由于SVG在绘制路径上非常灵活,我们将很多网页上的元素使用SVG来绘制而成,有各种人物.小图标.小动画等等.今天我们收集了10个非 ...