word2vec入门简介

导读:

word2VEC 是什么?

    百科描述:

    Word2vec,是为一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系,该向量为神经网络之隐藏层。

入门篇的理解:

Word2vec可处理文本(有关系的文本数据),通过一些我不懂的公式然后构建每个词的向量,有关系的词会放在一起(既向量相近),两词之间的相关度可以用余弦表示,越相关则值越小。

 

 

干活: 

怎么使用这个玩意呢,(人生苦短,我学python,java众该怎么办呢?python也是根据论文写的算法,java也一样行,其中Deeplearning4J就实现了这些网络,怎么导入项目看快速指引)

前提:

1.因为word2VEC的分词器是默认是英文进行分词,对中文不支持,需要中文的分词器,这里使用了一些分词器,发现还是教授的分词器好用:FNLP,这个fnlp不光有有分词的功能,还包括:信息检索( 文本分类 新闻聚类)、中文处理( 中文分词 词性标注 实体名识别 关键词抽取 依存句法分析 时间短语识别)、结构化学习( 在线学习 层次分类 聚类),这里使用分词功能,怎么导入fnlp后面会讲。

注:word2Vec在处理时,默认标识是由空格分隔的单词,对单词进行向量标识。

2.将https://github.com/deeplearning4j/dl4j-examples.git 的项目导入你的eclipse,然后在pom.xml中加入分词功能,这里加入word分词器进行比较(尴尬了) 。

		<dependency>
			<groupId>org.apdplat</groupId>
			<artifactId>word</artifactId>
			<version>1.3</version>
		</dependency>

开始测试,让word2Vec来读一读关于猴子的故事:

1.下载了基本关于猴子的几本书:西游记、悟空传、大妖孙悟空、重回西游、大泼猴、西游岁月

2.使用fnlp进行分词:

提起 神通 广大 的 “ 齐天 大圣 ” 孙悟空 , 不论 是 大陆 还是 港 台 , 是 星洲 还是 槟屿 , 凡 我 炎黄子孙 、 华夏 儿女 , 乃是 家喻户晓 , 妇孺皆知 , 几乎 人人 都 能 讲

使用word分词:

提起 神通 广大 的 齐天 大圣 孙 悟空 不论是 大 陆 还是 港台 是 星洲 还是 槟 屿 凡 我 炎黄 子孙 华夏 儿女 乃是 家喻户晓 妇孺 皆知 几乎 人 人都 能讲。

这只是其中一段,两者分词的效果还是很明显的,并且两者的性能天差地别..

 

3.设置模型参数读取分隔好的文本进行测试:

		//1.加载数据,创建分词器
		log.info("Load data....");
		SentenceIterator iter = new LineSentenceIterator(new File(targetFile));
		iter.setPreProcessor(new SentencePreProcessor() {
			@Override
			public String preProcess(String sentence) {
				return sentence.toLowerCase();
			}
		});
		
		
		TokenizerFactory t = new DefaultTokenizerFactory();
        t.setTokenPreProcessor(new CommonPreprocessor());
		
        
		//2.培训模型
        log.info("Building model....");
//        Word2Vec vec = new Word2Vec.Builder()
//                .minWordFrequency(10) //是单词必须出现在语料库中的最小次数。在这里,如果它出现少于5次,则不会学习。单词必须出现在多个上下文中才能学习有关它们的有用功能。在非常大的语料库中,提高最小值是合理的。
//                .layerSize(100) //layerSize指定单词向量中的要素数。这等于要素空间中的维数。由500个特征表示的单词成为500维空间中的点。
//                .seed(42) //该方法为随机数发生器定义了随机种子
//                .windowSize(5) 
//                .iterate(iter) //告诉网络它正在训练的数据集的批次。
                .tokenizerFactory(t) //将当前批次中的单词提供给它。
//                .iterations(1)
//                .batchSize(30)
//                .build();
        
        Word2Vec vec = new Word2Vec.Builder()  
                .minWordFrequency(5)  
                .iterations(1)  
                .layerSize(100)  
                .seed(42)  
                .windowSize(15)  
                .iterate(iter)  
                .build(); 

        log.info("Fitting Word2Vec model....");
        vec.fit();
        
//        batchSize是您一次处理的单词数量。
//        minWordFrequency是单词必须出现在语料库中的最小次数。在这里,如果它出现少于5次,则不会学习。单词必须出现在多个上下文中才能学习有关它们的有用功能。在非常大的语料库中,提高最小值是合理的。
//        useAdaGrad - Adagrad为每个要素创建不同的渐变。在这里,我们并不关心这一点。
//        layerSize指定单词向量中的要素数。这等于要素空间中的维数。由500个特征表示的单词成为500维空间中的点。
//        learningRate是系数每次更新的步长,因为在特征空间中重新定位了单词。
//        minLearningRate是学习率的最低点。随着您训练的单词数减少,学习率会下降。如果学习率下降太多,网络的学习就不再有效。这使系数保持移动。
//        iterate告诉网络它正在训练的数据集的批次。
//        tokenizer将当前批次中的单词提供给它。
//        vec.fit()告诉配置的网络开始训练。
        
        
        //3.模型评估
        WordVectorSerializer.writeWordVectors(vec, "pathToWriteto.txt");
        
        log.info("保存模型前进行一次数据匹配----");
        Collection<String> lst = vec.wordsNearest(word, 10);
        System.out.println(lst);
        
        //4.保存训练的模型,读取训练的模型
        log.info("Save vectors....");
        WordVectorSerializer.writeWord2VecModel(vec, "pathToSaveModel.txt");
        
        vec = WordVectorSerializer.readWord2VecModel("pathToSaveModel.txt");
        
        
        
        log.info("读取序列化模型后进行数据匹配---------");
        log.info("Closest Words:");
        lst = vec.wordsNearest(word, 10);
        System.out.println(lst);

4.测试结果:

匹配词为 猴子,输出结果:

// windowSize 5    [六耳猕, 六耳猕猴, 通背猿, 龙血, 林夕, 抓到, 碧海, 猿猴和, 马猴, 猿猴]
// windowSize 15     [六耳猕, 通背, 耳, 猿猴和, 猴子, 六, 赤尻, 六耳猕猴, 耳猕猴, 名字]

模型参数不同,得到的结果也不一致(下一篇会讲解参数设置),

 

后记:

1.使用fnlp:

  首先将项目down下来:

 git clone https://github.com/FudanNLP/fnlp.git 

编译:

进入fnlp目录,执行下面的命令

mvn install -Dmaven.test.skip=true   会编译fnlp的核心包

mvn dependency:copy-dependencies -DoutputDirectory=libs     会将需要的jar都拷贝到libs这个目录

将commons-cli-1.2.jar  、trove4j-3.0.3.jar 、hamcrest-core-1.3.jar 、fnlp-core-2.1-SNAPSHOT.jar 将如build path 环境中,

还需要下载下面的文件,并将模型文件放在“models”目录。(下载地址:https://github.com/FudanNLP/fnlp/releases

  • seg.m 分词模型
  • pos.m 词性标注模型
  • dep.m 依存句法分析模型

最后的目录结构:

 

创建工具类:

public class FudanTokenizer {

	private CWSTagger tag;

	private StopWords stopWords;

	public FudanTokenizer() {
		String path = this.getClass().getClassLoader().getResource("").getPath();
		System.out.println(path);
		try {
			tag = new CWSTagger(path + "models/seg.m");
		} catch (LoadModelException e) {
			e.printStackTrace();
		}

	}

	public String processSentence(String context) {
		return tag.tag(context);
	}

	public String processSentence(String sentence, boolean english) {
		if (english) {
			tag.setEnFilter(true);
		}
		return tag.tag(sentence);
	}

	public String processFile(String filename) {
		return tag.tagFile(filename);
	}

	/**
	 * 设置分词词典
	 */
	public boolean setDictionary() {
		String dictPath = this.getClass().getClassLoader().getResource("models/dict.txt").getPath();

		Dictionary dict;
		try {
			dict = new Dictionary(dictPath);
		} catch (IOException e) {
			return false;
		}
		tag.setDictionary(dict);
		return true;
	}

	/**
	 * 去除停用词
	 */
	public List<String> flitStopWords(String[] words) {
		try {
			return stopWords.phraseDel(words);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}

 

//分词工具类
public class FNLPTokenizerUtil {

	private static Logger log = LoggerFactory.getLogger(FNLPTokenizerUtil.class);

	private static FudanTokenizer tokenizer = new FudanTokenizer();

	public static boolean processFile(String targetFile, String outFile) {

		boolean flag = false;
		log.info("开始处理文本,进行分词处理:文件名位置:{},文件处理后的输出位置:{}", targetFile, outFile);

		try {
			BufferedReader in = new BufferedReader(new FileReader(targetFile));

			File outfile = new File(outFile);
			if (outfile.exists()) {
				outfile.delete();
			}
			FileOutputStream fop = new FileOutputStream(outfile);

			// 构建FileOutputStream对象,文件不存在会自动新建
			String line = in.readLine();
			OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
			while (line != null) {
				line = tokenizer.processSentence(line);
				writer.append(line);
				line = in.readLine();
			}
			in.close();
			writer.close(); // 关闭写入流,同时会把缓冲区内容写入文件
			fop.close(); // 关闭输出流,释放系统资源
			log.info("文件分词处理完成,输出位置:{}", outFile);
			flag = true;
		} catch (Exception e) {
			log.error("分词器处理文本异常", e);
		}

		return flag;
	}

}

word分词工具方法:

	 /**
     * 获取文本的所有分词结果
     * @param text 文本
     * @return 所有的分词结果,去除重复
     */
    public static Set<String> defaultSeg(String text) {
        return segMore(text).values().stream().collect(Collectors.toSet());
    }
	
	
	public static Map<String, String> segMore(String text) {
	    Map<String, String> map = new HashMap<>();
	    for(SegmentationAlgorithm segmentationAlgorithm : SegmentationAlgorithm.values()){
	        map.put(segmentationAlgorithm.getDes(), seg(text, segmentationAlgorithm));
	    }
	    return map;
	}
	
	
	private static String seg(String text, SegmentationAlgorithm segmentationAlgorithm) {
	    StringBuilder result = new StringBuilder();
	    for(Word word : WordSegmenter.segWithStopWords(text, segmentationAlgorithm)){
	        result.append(word.getText()).append(" ");
	    }
	    return result.toString();
	}

 

下面参考官网文档的描述:

2.word2vec的基本概念:

1.Word2vec的应用程序不仅仅是解析野外的句子。它也可以应用于基因,代码,喜欢,播放列表,社交媒体图以及可以辨别模式的其他语言或符号系列

2.特征向量:

将相似单词的向量组合在空间中,它以数学方式检测数据相似性,输出一个词汇表,每个单词都对应一个向量,可以将其输入网络中检测单词之间的关系,他们的相对意义已被转为为可被检测的距离。

3.构建步骤:

1.迭代文本库创建文档列表,senteceIterator(通过分割文本库来创建字符串集合)

2.Tokenizer 将文本分隔为单个单词,某人是由空格分隔的单词

每个文档都必须被标记化以创建词汇,即对该文档或语料库重要的词汇集。这些单词存储在词汇缓存中,其中包含有关文档中计算的单词子集的统计信息,即“重要”字样。区分显着和不重要词语的界限是移动的,但区分两组的基本思想是,只发生一次(或少于,比如五次)的单词难以学习,并且它们的存在代表无用的。

4.doc2vec(下一篇一起介绍) :可将文档与标签相关联,是word2vec的扩展。

更多关于word2vec的文章和论文:

介绍word2vec是如何工作:

https://www.quora.com/How-does-word2vec-work-Can-someone-walk-through-a-specific-example

https://skymind.ai/wiki/ai-vs-machine-learning-vs-deep-learning

 

这一篇更多是参考官方文档做一个小demo,简单的使用word2vec,下一篇对word2vec模型参数详细介绍和将文档和标签进行关联。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值