自己部署本地大模型

可以CPU

https://github.com/ollama/ollama直接下载安装(有可linux,windows)
安装后打开CMD,按提示运行相应的模型,如
ollama run llama3

以下是70B的,
ollama run llama3:70b
以下是根据llama3微调后的100万上下文模型
ollama run llama3-gradient
还有其它模型,看官网。

按以上命令运行后会自动下载相应的模型,然后就可以直接在命令行窗口和大模型聊天了,
你也可以在huggface上下载其它模型用https://liaoxuefeng.com/blogs/all/2024-05-06-llama3/index.html

只有命令行,如果要UI,网上有开源的,
对开发人员来说,有https://github.com/ollama/ollama-python这个库是python对API接口的包装,可以直接拉来用

Ollama本身也提供了restAPI,可以直接调用

Generate a response

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt":"Why is the sky blue?"
}'

Chat with a model

curl http://localhost:11434/api/chat -d '{
  "model": "llama3",
  "messages": [
    { "role": "user", "content": "why is the sky blue?" }
  ]
}'


人工智能文本处理突破-从one-hot到embedding模型

文本向量化是将文本数据转换为数值向量的过程。这种转换使得计算机能够理解和处理文本数据,从而可以应用各种机器学习和自然语言处理技术。文本向量化的主要问题是将非结构化的文本数据转换为结构化的向量表示,以便计算机能够对其进行处理和分析。通过文本向量化,可以实现文本分类、文本聚类、信息检索等任务。

在大模型时代下,文本向量化的技术发展到了embedding阶段。Embedding是一种将高维的文本数据映射到低维空间的技术,它能够捕捉到文本数据中的语义信息,并将其表示为稠密向量。这种表示更具有语义信息,相比于传统的词袋模型或者TF-IDF等表示方法,embedding能够更好地捕捉到单词之间的语义关系。

文本向量化技术发展史

整个文本向量化的发展过程是一个由简单到复杂,由低维到高维的演变过程。在早期,人们使用基于统计的方法,如词袋模型、TF-IDF等来表示文本。这些传统的基于统计的方法虽然能够实现一些简单的文本处理和自然语言理解任务,但是对于语义信息的把握能力有限,而且很难处理复杂的语言现象。随着深度学习技术的演变,尤其是Word2Vec、GloVe等词向量模型的提出,文本处理的效果和性能大幅提升,文本向量化技术开始向embedding方向发展。而后来的BERT、GPT等大型预训练模型的出现,则进一步推动了文本向量化技术的进步,使得文本向量化不仅能够表示单词或短语,还能够表示整个句子或文档的语义信息。新技术生成的文本向量不仅可以高效完成传统的自然语言处理任务,还在新兴的生成式人工智能技术(如检索增强生成等技术)中发挥了作用。

One-Hot编码(出现于2000年前)

One-Hot编码是一种将分类数据转换为二进制表示的方法,常用于数据处理和机器学习。One-Hot编码的概念一般被认为是随着计算机科学的发展而自然出现。在数字计算和数据处理的早期阶段,二进制表示极为盛行。当需要计算机处理非数值的数据(如颜色,产品类型等)时,One-Hot编码就是一种将各类数据数值化的朴素方法。

在文本向量化中,One-Hot编码的分类数据一般为单词或字符,以下以单词为例。通过这种编码方式,每个唯一的单词都用一个向量表示。向量的长度等于词汇表的单词数量,其中只有一个位置为1,其余位置都为0。这种表达方式生成的是稀疏向量,其中每个单词都由一个唯一的二进制向量表示,该向量中只有一个高位(1),其他都是低位(0)。

以“猫”、“狗”、“鱼”为例,One-Hot编码在文本向量化中的实现步骤大致如下:

首先识别所有的唯一单词,并建立长度为3的词汇表{“猫”, “狗”, “鱼”}。其次为每个单词分配索引,比如“猫”、“狗”、“鱼”分别分配索引位置0,1,2。然后为每个单词创建向量,例如,“猫”的向量是[1, 0, 0]。最后假使有一段文本内容为“猫猫狗狗”,它经过向量化后就是

[[1, 0, 0],

[1, 0, 0],

[0, 1, 0],

[0, 1, 0]]。

优点:

● 简单易实现。

● 能提供清晰明确的单词表示。

缺点:

● 词汇表偏大时会导致向量维度过高,从而造成内存使用量偏大。

● 无法存储单词之间的语义相似性(例如,”猫“和”狗“同为宠物动物应更加相似,然而在One-Hot编码中“猫”、“狗”、“鱼”三者的向量距离相同,所以不能体现这一特性)。

● 稀疏向量在某些任务中计算效率低。

Bag of words (出现于2000年前)

Bag of Words(BoW)又称词袋模型,是一种简单而有效的文本向量化方法。词袋模型目前没有归属一个具体的发明者,而是在信息检索、文本分类和自然语言处理等领域中逐渐发展演变出来的一种常用的文本表示方法。One-Hot编码虽然完成了数据从非数值到数值的转变,但在文本分类,特征提取等方面作用十分有限,且每个词都对应一个稀疏向量,存储效率较低。词袋模型将文本看作是单词的无序集合,忽略词的顺序和语法,只关注词的出现频率。因此词袋模型在One-Hot编码的基础上提升了文本向量化的效果,并减少了存储负担。

仍以“猫”、“狗”、“鱼”为例,词袋模型在文本向量化中的实现步骤大致如下:

与One-Hot编码相同,首先识别所有的唯一单词,并建立长度为3的词汇表{“猫”, “狗”, “鱼”}。其次对于每一文本,创建一个与词汇表等长的向量。向量的每个位置对应词汇表中的一个词,该位置的值表示该词在文档中出现的次数。假使“猫”、“狗”、“鱼”的索引位置仍然分别为0,1,2,而文本依然是“猫猫狗狗”。与one-hot编码会生成一组向量不同,词袋模型只会产生一个向量[2, 2, 0]。向量中第0个元素2代表“猫”出现了两次,第1个元素2代表“狗”出现了两次,第2个元素0代表“鱼”出现了零次。

优点:

● 简单易实现。

● 对于小规模数据集,词袋模型的计算效率很高。

缺点:

● 对于大型词汇表,词袋模型生成的向量维度很高,从而导致内存使用量大。

● 完全忽略了词的顺序,无法捕捉句子的语法和结构信息。

● 仅仅统计词频,而无法捕捉词与词之间的语义关系。

TF-IDF(出现于2000年前)

TF-IDF(Term Frequency-Inverse Document Frequency),翻译为词频-逆文档频率,是一种常用于文本挖掘和信息检索的统计方法,用来评估一个词在一个文档集或语料库中的重要程度。现今的TF-IDF方法被认为是文本挖掘和信息检索领域逐渐发展和完善的结果,但逆文档频率的基本概念由计算机科学家Karen Spärck Jones在1957年提出,用来评估在一个文档集中,一个词对它所在的文档的重要性。TF-IDF可以帮助筛选出在文档中具有重要意义的词汇,常用于关键词提取、文档相似度计算和文本分类等任务。

TF-IDF由两个部分组成:词频(TF)和逆文档频率(IDF)。词频是一个词在一个文档中出现的频率。词频越高,表明这个词在该文档中越重要。词频的公式为:

逆文档频率衡量一个词在整个文档集(可能包含多个文档)中出现的稀有程度。一个词在越多文档中出现,其区分能力越低,IDF值就越小。逆文档频率的计算公式为:

两个公式中:

ft,d是词t在文档d中出现的次数。

nd是文档d中所有词的总数。

N是文档集D中文档的总数。

|{d∈D:t∈d}|是包含词t的文档总数。

最后,TF-IDF 是词频和逆文档频率的乘积,用来衡量一个词在一个文档中的重要性,其计算公式为:

举例来说,假设有以下三个文档:

文档1: ”狗追猫。“

文档2: “猫爬墙。”

文档3: “狗趴地。”

TF-IDF(“猫”,文档1, 文档集)的计算如下:

TF(“猫”,文档1) = 1/3。

IDF(“猫”,文档集) = log(3 / (1 + 2)) = 0。

TF-IDF(“猫”,文档1,文档集) = 1/3 * 0 = 0。

可以看出,由于“猫” 在多个文档中出现,因此其区分能力较低,IDF值为0,导致TF-IDF值也为0。

优点:

● 简单易实现。

● 考虑了词的重要性,减少了常见但不重要的词(如“的”、“与”等)的权重。

● 适用于自然语言处理中的多种任务,如文本分类、文本聚类、信息检索等。

缺点:

● 对于大型文档集,由于词汇量庞大,生成的 TF-IDF 矩阵往往非常稀疏,所以计算效率不高。

● 只考虑了词汇的出现频率,而忽略了词汇在文本中的顺序信息。

● 没有考虑词汇之间的语义关系。

● TF-IDF 的计算方式导致它的效果依赖于足够大的文档集,数据量不足可能导致效果不佳。

应用场景:

● 关键词提取

● 文档相似度计算

● 信息检索

● 文本分类

Word2Vec(出现于2013年)

Word2Vec是一种基于神经网络的embedding模型,由谷歌的研究人员Tomas Mikolov等在2013年提出。Word2Vec的作者认为之前的文本向量化方法很少考虑词与词之间的意义关联,所以效果不佳。因此,Word2Vec将单词映射到低维向量空间中,使得相似词在向量空间中也保持相近的距离。

Word2Vec主要由两种模型架构组成:Skip-Gram和Continuous Bag of Words(CBOW)。Skip-Gram通过当前词预测其上下文词。给定一个中心词,模型会预测一个固定长度的上下文窗口(前后若干词)中的所有词。训练过程中,模型会学习到每个词的向量表示,使得能够更好地预测这些上下文词。与Skip-Gram相反,CBOW的目标是通过上下文词预测当前词。给定一个上下文窗口中的所有词,模型会预测这个窗口的中心词。

Word2Vec模型的核心思想是通过训练神经网络,使得单词与其上下文之间的关系可以在向量空间中被有效地表示。Word2Vec的输入层是一个one-hot向量(one-hot vector),长度为词汇表大小(V)。紧接着是一个投影层,由输入层经过一个权重矩阵W(维度为V x N,N为嵌入向量的维度),投影到N维向量空间中。投影层的输出通过另一个权重矩阵W’(维度为N x V),映射回一个词汇表大小的向量,此为输出层。最后经过一个Softmax层得到每个词的概率。在训练过程中,Word2Vec模型通过最大化目标函数(取决于使用Skip-Gram还是CBOW,以及采用的优化函数的方法)来更新权重矩阵,从而使得embedding能够捕捉到词汇的语义信息。

优点:

● 由于采用了浅层神经网络,训练速度较快,适合处理大规模数据。

● 能够捕捉到词与词之间的语义关系,如词性、同义词等。

● 可以用于多种自然语言处理任务,如文本分类、情感分析、机器翻译等。

缺点:

● 每个词只有一个固定的向量表示,无法处理多义词的不同语义。

● 无法考虑词在不同上下文中的语义变化。

应用场景:

● 信息检索

● 文本分类

● 推荐系统,如根据用户的评论调整推荐的产品

GloVe(出现于2014年)

GloVe (Global Vectors for Word Representation)是一种无监督的文本向量化的学习算法,由斯坦福大学的Jeffrey Pennington等在2014年提出。它通过捕捉单词在大规模语料库中的共现统计信息,生成高质量的词向量。GloVe的作者认为使用共现词的概率的比可以更好地区分相关和无关的词,因此GloVe的核心是共现矩阵和词对共现概率。共现矩阵中的每个元素Xi,j表示词j出现在词i的上下文中的次数。词对共现概率定义为:

意为词j在词i的上下文中出现的概率。GloVe 的优化目标是通过最小化一个损失函数,使得embedding能够很好地预测共现概率。损失函数如下:

其中,wi和wj分别是词i和词j的词向量,bi和bj是偏置项,f(Xij)是一个加权函数,用于减少高频共现对模型的影响。加权函数f通常定义为:

其中Xmax是一个阈值,在GloVe作者的实验中被设置为100,而3/4被认为是一个合适的α的值。
优点:
●充分利用了全局共现统计信息,使得词向量可以捕捉到词语之间的复杂关系。
●通过对共现矩阵进行处理,GloVe 的训练速度较快,适合大规模语料库。
●生成的词向量在语义上具有较强的解释力,可以很好地应用于各种自然语言处理任务,如文本分类、情感分析、问答系统等。


缺点:
●每个词只有一个固定的向量表示,无法处理多义词的不同语义。
●通常需要大规模的语料库来获得高质量的词向量表示。
● 尽管训练过程可以并行化,但仍需要较高的计算资源和时间来训练高质量embeddings。
●虽然关注单词之间的共现频率,但忽略了语法结构。


应用场景:
●文本分析
●信息检索
●问答系统

FastText(出现于2016年)

FastText是由Facebook的人工智能研究团队开发的一种用于文本分类和词向量表示的开源库,适用于大规模数据集和高性能需求的任务。FastText的相关论文由Piotr Bojanowski等人在2016年发表,FastText的作者认为之前的文本向量化方法没有考虑单词内部的子词之间的关系,所以性能受限。为了改善这个限制,FastText的核心原理包括两大部分:词向量表示和文本分类。
词向量表示


FastText 的一个关键创新在于利用了子词信息(Subword Information),即将每个单词表示为多个 n-gram 的组合。

例如,单词 “where” 可以分解为”wh”, “whe”, “her”, “ere”, “re”等 n-gram。这种方法使得模型能够捕捉到词的子词信息,从而更好地处理未登录词和拼写错误。FastText 使用基于在上文中提到的Skip-Gram的方法来训练embedding。值得注意的是,FastText不仅使用单词本身,还使用单词的所有n-gram。每个单词被表示为它所有n-gram向量的组合。为了提高计算效率,FastText 使用分层Softmax代替传统的Softmax。分层Softmax将所有类别组织成一棵二叉树,每个叶节点对应一个类别。通过减少类别数量的对数级计算,分层Softmax极大地加速了训练和预测过程。


文本分类原理


在文本分类任务中,FastText通过将文本表示为一系列词向量的平均来生成文档向量。对于一个文本d中的每个词w,其向量表示为vw。文本d的表示为所有词向量的平均,即:

FastText使用线性分类器来进行文本分类。文本向量vd通过一个全连接层,并使用Softmax函数来输出类别概率。分类模型的公式为:

其中W是权重矩阵,b是偏置项。

优点:

● 训练和预测速度也很快,适合实时应用。

● 能够处理具有大量类别的任务,并保持高效性。

● 支持多种语言的文本处理。

缺点:

● 使用静态词向量,无法捕捉上下文相关的词义变化。

应用场景:

● 文本分类

● 关键词提取

● 拼写错误纠正

ELMo(出现于2018年)

ELMo(Embeddings from Language Models)是一种由Allen Institute for AI的研究者Matthew E. Peters等在2018年提出的embedding方法,通过上下文中的词语来捕捉语义。ELMo的作者认为之前的文本向量化方式没有考虑一个词在不同上下文中意义的变化,所以与Word2Vec和GloVe不同,ELMo能够捕捉到词在不同上下文中的不同意义,从而生成更为丰富和精确的embedding。

ELMo使用双向LSTM(Long Short-Term Memory)网络作为基础架构。该网络包括一个向前的LSTM和一个向后的LSTM,它们分别从左到右和从右到左遍历文本序列,学习每个词的前向和后向上下文。这个双向LSTM被训练为一个语言模型,目标是预测句子中的下一个词(对于前向LSTM)和前一个词(对于后向LSTM)。对于给定的文本序列,ELMo会为每个词提取多层的表示。对于每个词,ELMo提供三层的embedding输出:一层来自embedding层(类似于传统的embedding),另外两层来自双向LSTM的各自输出。最后,ELMo使用这些层的加权和作为结果,公式如下:

其中γ是一个可学习的标量;sj是层j的可学习权重;ht(j)是词t在层j的表示。为了使这些输出被应用在不同任务中,ELMo提出了一种动态加权的方法,可以为不同层的输出分配不同的权重。这样,模型不仅使用了所有层的信息,还根据任务动态调整了每层信息的重要性。

优点:

● 基于整个句子的上下文信息生成embedding,能够更好地处理多义词和上下文依赖性强的词。

● 能够捕捉复杂的句子结构和长距离依赖关系。

● 预训练的ELMo模型可以很容易地迁移到各种下游自然语言处理任务中。

缺点:

● 模型较大,训练和推理过程需要大量的计算资源。

● 由于模型复杂,推理速度较慢。

应用场景:

● 情感分析

● 问答系统

● 文本分类

● 机器翻译

基于Transformer结构的embedding模型(出现于2018年后)

谷歌的研究人员Ashish Vaswani等在2017年提出了带有注意力机制的Transformer模型结构,可以利用输入序列的全局信息进行输出,改善了在RNN和LSTM中的长距离依赖问题,同时提高了并行计算能力使训练过程大幅加速。

随着transformer结构的推出,在2018年开始出现了许多各具特色的基于Transformer结构的embedding模型。其中BERT (Bidirectional Encoder Representations from Transformers) 是一种双向Transformer编码器,用于生成上下文感知的词向量。GPT (Generative Pre-trained Transformer) 系列则是单向,且主要用于文本生成任务。T5 (Text-To-Text Transfer Transformer) 将所有任务统一为文本到文本的转换。RoBERTa (Robustly Optimized BERT Approach) 对BERT进行了优化,提升了性能。DistilBERT 则是BERT的轻量级版本,旨在减少计算资源。ALBERT (A Lite BERT) 通过参数共享和因子分解,进一步减小了模型大小。这些模型同传统的embedding方法相比效果显著提高,被广泛应用于自然语言处理的各种任务。

结语

在大模型时代,embedding成为一项必不可少的技术,主要是因为它能够有效地将大量高维数据(如文本、图像和音频信息)转换成更低维的、密集的向量表示。这种表示可以捕捉到数据的本质特征,并且在处理和计算上更为高效。通过embedding,模型可以在这些压缩的向量空间中学习数据之间的复杂关系和模式,从而提高了处理速度和准确性。此外,embedding使得模型能够在较小的表示空间中进行操作,减少了计算资源的需求,同时也便于模型的训练和推理,这对于处理现代大规模数据集尤为关键。Embedding在大模型时代扮演着桥梁的角色,跨越了原始数据和机器学习算法之间的巨大鸿沟。

在自然语言处理领域,文本向量化技术的发展带来了革命性的变化。从最早的One-Hot编码到当前基于Transformer结构的embedding模型,每一次创新都带来了更高效、更精准的文本表示方式,为文本处理提供了更为灵活、高效的解决方案。未来,随着技术的不断进步和应用场景的不断拓展,文本向量化技术将继续发挥着重要的作用,并为人工智能在文本理解和处理领域带来更广阔的发展空间。

深入研究 Transformer 模型时,将反复提到 architecture 和 checkpoints 以及 model。这些术语的含义略有不同:architecture:这是模型的结构——每个层的定义以及模型中发生的每个操作。checkpoints:这些是将在给定架构中加载的权重。model:这是一个总括术语,不像 “architecture” 或 “checkpoints” 那么精确。它可以同时表示两者。例如,BERT是一种 architecture,而BERT-base-cased(谷歌团队 BERT 的第一个版本训练的一组权重)是一个 checkpoints。然而,人们可以说 “BERT model” 和“BERT-base-cased model”

召回率

召回率是指在所有正样本中,被成功预测为正样本的样本数占比。在机器学习领域,召回率是评估模型预测性能的重要指标之一。在本文中,我们将从多个方面深入探讨召回率的概念和应用。
阈值越高,精准率越高,召回率越低;阈值越低,精准率越低,召回率越高。
精准率(precision)的实际含义是,在所有预测为正例的样本中,真实为正例的比例。

召回率(recall)的实际含义是,在所有真实为正例的样本中,被正确预测为正例的比例。

举个例子,假设有一个垃圾邮件分类器,它要从100封邮件中识别出垃圾邮件。假设其中有20封是真正的垃圾邮件,80封是正常邮件。如果分类器预测出了15封垃圾邮件,其中10封是真的垃圾邮件,5封是误判的正常邮件,那么它的召回率和精准率分别是:

精准率 = 10 / 15 = 0.67,表示分类器预测出的垃圾邮件中有三分之二是真的垃圾邮件。

召回率 = 10 / 20 = 0.5,表示分类器只能找到一半的真正垃圾邮件。

一、什么是召回率
召回率是指模型成功检测到的所有真实正样本个数与真实正样本总数的比例。直观来讲,它衡量了模型在识别正样本方面的准确性。召回率数值越高,模型对正样本的识别越精准,但也可能带来更高的误报率。当真实正样本比较少时,召回率也会相对较低。

二、如何计算召回率
召回率的计算公式如下:

召回率 = 模型成功检测到的所有真实正样本个数 / 真实正样本总数
举个例子,假设某个模型对500个正样本进行了预测,其中正确识别出了450个,但漏识别了50个。这个模型的召回率为450/500=0.9,即90%。

三、什么情况下需要召回率
召回率适用于以下场景:

二分类问题,其中正样本数相对较少。
模型的预测结果需要被进一步修正或筛选。
需要优化模型的敏感性,即尽可能地识别更多的真实正样本。
四、如何提高召回率
提高召回率的方法有以下几种:

增加正样本数。增加正样本数能够提高召回率,但前提是正样本确实存在,并且可以扩大正样本范围。
调整模型阈值。降低模型阈值能够减少漏识别,但也会增加误报。调整模型阈值需要根据具体场景进行。
优化模型训练。在模型训练时,可以多采用正样本,增加正样本的特征和数量,有效提高模型的召回率。
采用不同的算法和模型。不同的算法和模型具有不同的优劣特点,在选择算法和模型时需要充分考虑召回率的需求。
五、召回率与精确率的关系
召回率和精确率都是模型评估中比较重要的指标。召回率注重的是尽可能识别更多的真实正样本,而精确率则注重的是尽可能排除误识别的负样本。一般而言,召回率与精确率存在一定的负相关关系,提高其中一个指标可能会降低另一个指标。在实际应用中,需要根据具体场景进行取舍。

六、总结
本文对召回率进行了深入的探讨,并从多个方面介绍了召回率的概念、计算、应用和提高方法。在实际应用中,需要根据具体场景选择合适的召回率指标和优化方法,以实现更好的模型性能。

稀疏向量

稀疏向量和密集向量都是向量的表示方法

密集向量和稀疏向量的区别: 密集向量的值就是一个普通的Double数组 而稀疏向量由两个并列的 数组indices和values组成 例如:向量(1.0,0.0,1.0,3.0)用密集格式表示为[1.0,0.0,1.0,3.0],用稀疏格式表示为(4,[0,2,3],[1.0,1.0,3.0]) 第一个4表示向量的长度(元素个数),[0,2,3]就是indices数组,[1.0,1.0,3.0]是values数组 表示向量0的位置的值是1.0,2的位置的值是1.0,而3的位置的值是3.0,其他的位置都是0

稀疏向量 [1]通常用两部分表示:一部分是顺序向量,另一部分是值向量。例如稀疏向量(4,0,28,53,0,0,4,8)可用值向量(4,28,53,4,8)和顺序向量(1,0,1,1,0,0,1,1)表示。

Doc2Bow简介与实践Demo

Doc2Bow是Gensim中封装的一个方法,主要用于实现Bow模型,下面主要介绍下Bow模型。

1、BoW模型原理
Bag-of-words model (BoW model) 最早出现在自然语言处理(Natural Language Processing)和信息检索(Information Retrieval)领域.。该模型忽略掉文本的语法和语序等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的。BoW使用一组无序的单词(words)来表达一段文字或一个文档.。近年来,BoW模型被广泛应用于计算机视觉中。
基于文本的BoW模型的一个简单例子如下:
首先给出两个简单的文本文档如下:

John likes to watch movies. Mary likes too.
John also likes to watch football games.

1
2
基于上述两个文档中出现的单词,构建如下一个词典 (dictionary):

{“John”: 1, “likes”: 2,”to”: 3, “watch”: 4, “movies”: 5,”also”: 6, “football”: 7, “games”: 8,”Mary”: 9, “too”: 10}
1
上面的词典中包含10个单词, 每个单词有唯一的索引, 那么每个文本我们可以使用一个10维的向量来表示。如下:

 [1, 2, 1, 1, 1, 0, 0, 0, 1, 1]
 [1, 1,1, 1, 0, 1, 1, 1, 0, 0]

1
2
该向量与原来文本中单词出现的顺序没有关系,而是词典中每个单词在文本中出现的频率。
也是通过余弦定理计算两个句子的相似度。

以下是实践DEMO

import gensim
import jieba
# 训练样本
from gensim import corpora
from gensim.similarities import Similarity


# fin = open("questions.txt",encoding='utf8').read().strip(' ')   #strip()取出首位空格
jieba.load_userdict("userdict.txt")
stopwords = set(open('stopwords.txt',encoding='utf8').read().strip('\n').split('\n'))   #读入停用词
raw_documents = [
    '0无偿居间介绍买卖毒品的行为应如何定性',
    '1吸毒男动态持有大量毒品的行为该如何认定',
    '2如何区分是非法种植毒品原植物罪还是非法制造毒品罪',
    '3为毒贩贩卖毒品提供帮助构成贩卖毒品罪',
    '4将自己吸食的毒品原价转让给朋友吸食的行为该如何认定',
    '5为获报酬帮人购买毒品的行为该如何认定',
    '6毒贩出狱后再次够买毒品途中被抓的行为认定',
    '7虚夸毒品功效劝人吸食毒品的行为该如何认定',
    '8妻子下落不明丈夫又与他人登记结婚是否为无效婚姻',
    '9一方未签字办理的结婚登记是否有效',
    '10夫妻双方1990年按农村习俗举办婚礼没有结婚证 一方可否起诉离婚',
    '11结婚前对方父母出资购买的住房写我们二人的名字有效吗',
    '12身份证被别人冒用无法登记结婚怎么办?',
    '13同居后又与他人登记结婚是否构成重婚罪',
    '14未办登记只举办结婚仪式可起诉离婚吗',
    '15同居多年未办理结婚登记,是否可以向法院起诉要求离婚'
]
corpora_documents = []
for item_text in raw_documents:
    item_str = jieba.lcut(item_text)
    print(item_str)
    corpora_documents.append(item_str)
print(corpora_documents)
# 生成字典和向量语料
dictionary = corpora.Dictionary(corpora_documents)
corpus = [dictionary.doc2bow(text) for text in corpora_documents]
#num_features代表生成的向量的维数(根据词袋的大小来定)
similarity = Similarity('-Similarity-index', corpus, num_features=400)

test_data_1 = '你好,我想问一下我想离婚他不想离,孩子他说不要,是六个月就自动生效离婚'
test_cut_raw_1 = jieba.lcut(test_data_1)

print(test_cut_raw_1)
test_corpus_1 = dictionary.doc2bow(test_cut_raw_1)
similarity.num_best = 5
print(similarity[test_corpus_1])  # 返回最相似的样本材料,(index_of_document, similarity) tuples

print('################################')

test_data_2 = '家人因涉嫌运输毒品被抓,她只是去朋友家探望朋友的,结果就被抓了,还在朋友家收出毒品,可家人的身上和行李中都没有。现在已经拘留10多天了,请问会被判刑吗'
test_cut_raw_2 = jieba.lcut(test_data_2)
print(test_cut_raw_2)
test_corpus_2 = dictionary.doc2bow(test_cut_raw_2)
similarity.num_best = 5
print(similarity[test_corpus_2])  # 返回最相似的样本材料,(index_of_document, similarity) tuples