资讯专栏INFORMATION COLUMN

4种方法计算句子相似度

timger / 2491人阅读

摘要:距离杰卡德系数用于比较有限样本集之间的相似性与差异性。将字中间加入空格转化为矩阵求交集求并集计算杰卡德系数你在干啥呢你在干什么呢计算计算矩阵中两个向量的相似度,即求解两个向量夹角的余弦值。

Edit Distance

计算两个字符串之间,由一个转成另一个所需要的最少编辑次数,次数越多,距离越大,也就越不相关。比如,“xiaoming”和“xiamin”,两者的转换需要两步:

去除‘o’

去除‘g’

所以,次数/距离=2。

!pip install distance
import distance

def edit_distance(s1, s2):
    return distance.levenshtein(s1, s2)

s1 = "xiaoming"
s2 = "xiamin"
print("距离:"+str(edit_distance(s1, s2)))

杰卡德系数

用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高,计算方式是:两个样本的交集除以并集。

from sklearn.feature_extraction.text import CountVectorizer
import numpy as np


def jaccard_similarity(s1, s2):
    def add_space(s):
        return " ".join(list(s))
    
    # 将字中间加入空格
    s1, s2 = add_space(s1), add_space(s2)
    # 转化为TF矩阵
    cv = CountVectorizer(tokenizer=lambda s: s.split())
    corpus = [s1, s2]
    vectors = cv.fit_transform(corpus).toarray()
    # 求交集
    numerator = np.sum(np.min(vectors, axis=0))
    # 求并集
    denominator = np.sum(np.max(vectors, axis=0))
    # 计算杰卡德系数
    return 1.0 * numerator / denominator


s1 = "你在干啥呢"
s2 = "你在干什么呢"
print(jaccard_similarity(s1, s2))

TF 计算

计算矩阵中两个向量的相似度,即:求解两个向量夹角的余弦值。

计算公式:cosθ=a·b/|a|*|b|
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
from scipy.linalg import norm

def tf_similarity(s1, s2):
    def add_space(s):
        return " ".join(list(s))
    
    # 将字中间加入空格
    s1, s2 = add_space(s1), add_space(s2)
    # 转化为TF矩阵
    cv = CountVectorizer(tokenizer=lambda s: s.split())
    corpus = [s1, s2]
    vectors = cv.fit_transform(corpus).toarray()
    # 计算TF系数
    return np.dot(vectors[0], vectors[1]) / (norm(vectors[0]) * norm(vectors[1]))


s1 = "你在干啥呢"
s2 = "你在干什么呢"
print(tf_similarity(s1, s2))

高阶模型Bert

Bert的内部结构,请查看从word2vec到bert这篇文章,本篇文章我们只讲代码实现。我们可以下载Bert模型源码,或者使用TF-HUB的方式使用,本次我们使用下载源码的方式。
首先,从Github下载源码,然后下载google预训练好的模型,我们选择Bert-base Chinese。

预模型下载后解压,文件结构如图:

vocab.txt是训练时中文文本采用的字典,bert_config.json是BERT在训练时,可选调整的一些参数。其它文件是模型结构,参数等文件。

准备数据集

修改 processor
class MoveProcessor(DataProcessor):
  """Processor for the move data set ."""
  def get_train_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "train.tsv")), "train")

  def get_dev_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "dev.tsv")), "dev")

  def get_test_examples(self, data_dir):
    """See base class."""
    return self._create_examples(
        self._read_tsv(os.path.join(data_dir, "test.tsv")), "test")

  def get_labels(self):
    """See base class."""
    return ["0", "1"]

  @classmethod
  def _read_tsv(cls, input_file, quotechar=None):
        """Reads a tab separated value file."""
        with tf.gfile.Open(input_file, "r") as f:
            reader = csv.reader(f, delimiter="	", quotechar=quotechar)
            lines = []
            for line in reader:
                lines.append(line)
            return lines
 
  def _create_examples(self, lines, set_type):
    """Creates examples for the training and dev sets."""
    examples = []
    for (i, line) in enumerate(lines):
      guid = "%s-%s" % (set_type, i)
      if set_type == "test":
        text_a = tokenization.convert_to_unicode(line[0])
        label = "0"
      else:
        text_a = tokenization.convert_to_unicode(line[1])
        label = tokenization.convert_to_unicode(line[0])
      examples.append(
          InputExample(guid=guid, text_a=text_a, text_b=None, label=label))
    return examples
修改 processor字典
def main(_):
  tf.logging.set_verbosity(tf.logging.INFO)

  processors = {
      "cola": ColaProcessor,
      "mnli": MnliProcessor,
      "mrpc": MrpcProcessor,
      "xnli": XnliProcessor,
      "setest":MoveProcessor
  }
Bert模型训练
export BERT_BASE_DIR=/Users/xiaomingtai/Downloads/chinese_L-12_H-768_A-12
export MY_DATASET=/Users/xiaomingtai/Downloads/bert_model
python run_classifier.py 
  --data_dir=$MY_DATASET 
  --task_name=setest 
  --vocab_file=$BERT_BASE_DIR/vocab.txt 
  --bert_config_file=$BERT_BASE_DIR/bert_config.json 
  --output_dir=/Users/xiaomingtai/Downloads/ber_model_output/ 
  --do_train=true 
  --do_eval=true 
  --do_predict=true
  --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt 
  --max_seq_length=128 
  --train_batch_size=16 
  --eval_batch_size=8
  --predict_batch_size=2
  --learning_rate=5e-5
  --num_train_epochs=3.0

Bert模型训练结果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43331.html

相关文章

  • 咋做长文本去重

    摘要:新问题抛出有没有一种签名算法,如果文本非常相似,签名值也非常相似呢二文本相似性的签名算法上文提出的问题,可以用局部敏感哈希解决,局部敏感哈希是一类文本越相似,哈希值越相似的算法,有兴趣的同学自行百度,这里分享一下的思路。 缘起:(1)原创不易,互联网抄袭成风,很多原创内容在网上被抄来抄去,改来改去(2)百度的网页库非常大,爬虫如何判断一个新网页是否与网页库中已有的网页重复呢?这是本文要...

    coordinate35 评论0 收藏0
  • 4方法计算句子相似

    摘要:距离杰卡德系数用于比较有限样本集之间的相似性与差异性。将字中间加入空格转化为矩阵求交集求并集计算杰卡德系数你在干啥呢你在干什么呢计算计算矩阵中两个向量的相似度,即求解两个向量夹角的余弦值。 Edit Distance 计算两个字符串之间,由一个转成另一个所需要的最少编辑次数,次数越多,距离越大,也就越不相关。比如,xiaoming和xiamin,两者的转换需要两步: 去除‘o’ 去除...

    用户83 评论0 收藏0
  • 自然语言处理真实项目实战

    摘要:在自然语言处理中,一个很重要的技术手段就是将文档转换为一个矢量,这个过程一般是使用这个库进行处理的。自然语言处理中,一般来说,代表词。自然语言预处理中,一个很重要的步骤就是将你收集的句子进行分词,将一个句子分解成词的列表。 前言 本文根据实际项目撰写,由于项目保密要求,源代码将进行一定程度的删减。本文撰写的目的是进行公司培训,请勿以任何形式进行转载。由于是日语项目,用到的分词软件等,在...

    王岩威 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<