=(year+month+day)%8upper_trigram_num=8ifupper_trigram_num==0elseupper_trigram_num#计算下卦(年+月+日+时之和除以8取余 )lower_trigram_num=(year+month+day+hour)%8lower_trigram_num=8iflower_trigram_num==0elselower_trigram_num =数2÷8取余数动爻=(数1+数2)÷6取余数"""upper_trigram_num=num1%8upper_trigram_num=8ifupper_trigram_num==0elseupper_trigram_numlower_trigram_num self.TRIGRAM_NUMBERS[upper_num]lower_trigram=self.TRIGRAM_NUMBERS[lower_num]#本卦(原始卦)original_hexagram ":upper_trigram,"lower_trigram":lower_trigram}defanalyze_relationship(self,upper_trigram,lower_trigram
_1" ] }, "trigram_analyzer_2":{ _2" ] }, "trigram_analyzer_3":{ _3" ] }, "trigram_analyzer_4":{ _4" ] } }, "filter":{ "trigram_filter _1" }, "name4":{ "type":"text", "analyzer":"trigram_analyzer
让我演示给你看下名字为Daniel的Trigram: ? 但这有用吗? 让我给你看一个例子。 您有以下email的schema: ? 表带有这样的数据: ? Trigram表 我创建了这样的表格: ? 我们可以看到,有一个名为“trigram”的索引。 计划是为每个电子邮件地址创建一个trigram。 我写了以下触发器: ? 当有插入时,它创建并将trigrams插入到email_trigram表中。 anderson.pierre的Trigram: ? 由于使用了Trigram,我们正在寻找单词的一部分(如err或ier),可以有很多匹配。 Trigram并不是最好的选择,但我可以看到可能更好的用例。
pg_trgm(Trigram Matching)通过将字符串拆分为三元组(trigram),再基于相似度计算进行匹配。 举个例子: 字符串 "postgres" 被拆成以下 trigram: " p", " po", "pos", "ost", "stg", "tgr", "gre", "res", "es " 每个 trigram 都是连续的 3 个字符。 PostgreSQL 会在索引中存储这些 trigram,从而实现近似匹配、模糊搜索、相似度排序等高级能力。 ⚡ 五、使用 pg_trgm + GIN 索引提升性能 -- 创建 trigram 索引 CREATE INDEX idx_users_name_trgm ON users USING gin (name
", "type":"shingle" }, "trigram_filter } }, "analyzer":{ "trigram_analyzer "filter":[ "lowercase", "trigram_filter "commonname":{ "type":"completion", "analyzer":"trigram_analyzer "drugname":{ "type":"completion", "analyzer":"trigram_analyzer
的field,这个trigram是自定义的类型,专门服务phrase suggester。 trigram这个field里有一个自定义的trigram analyzer。 field 是否要加.trigram ?网上的教程会有加.trigram的用法,那到底是用 ner 还是 ner.trigram ? ner.trigram的行为是,不仅仅用单个词条作为纠错,而是可以将后续的2,3个词,一起作为整体进行纠错。如果建索引和搜索时,采用的是相同粒度的分词,则采用ner即可。 如果建索引采用细粒度分词,搜索的时候,采用粗粒度分词,则采用ner.trigram。Phrase Suggester的参数如何设置?
例如,当N=1时,模型称为unigram,仅考虑单个词的概率;当N=2时,称为bigram,考虑前一个词来估计当前词的概率;当N=3时,称为trigram,考虑前两个词来估计第三个词的概率,以此类推N-gram 例如,对于句子"The quick brown fox",作为trigram模型,我们会计算 $P("brown" | "The", "quick")$、$P("fox" | "quick", "brown 本开发案例实现了一个完整的N-gram模型系统,支持unigram、bigram和trigram三种模型。系统设计考虑了可扩展性,便于添加更高阶的N-gram模型。2. __init__(n=2)3.2.4 Trigram模型Trigram模型考虑前两个词对当前词的影响:class TrigramModel(NgramModel): def __init__(self 总结本开发案例实现了一个完整的N-gram模型系统,支持unigram、bigram和trigram三种模型。
BIGRAM 和 TRIGRAM 是 N-gram 匹配技术的实例,该技术计算两个字符串之间公共连续子字符串(gram)的数量。 , col1, col2) as jaro_winkler, fuzzy_match(bigram, col1, col2) as bigram, fuzzy_match(trigram , col1, col2) as trigram, fuzzy_match(whole_word_match, col1, col2) as wwm, fuzzy_match , col1, col2, unscaled) as trigram, fuzzy_match(whole_word_match, col1, col2, unscaled) as wwm unscaled) as lcs from match_tab; COL1 COL2 LEVENSHTEIN JARO_WINKLER BIGRAM TRIGRAM
但中文属于「无空格、无词界」的语言,因此直接使用时存在问题: 示例 拆分结果(英文式) 实际语义 影响 张晓明 “张晓明” → “张晓明” (单个 trigram) 张 + 晓 + 明 trigram 方案二:结合全文检索(tsvector) PostgreSQL 内置全文搜索(Full Text Search)可与 trigram 互补。 -- 搜索“张明”相关用户 SELECT * FROM users WHERE name_zh_tsv @@ to_tsquery('张明'); ✅ 优点: 支持中文分词、同义词、前缀匹配 可混合 trigram 如搜索用户、商品、文档),可采用混合策略: SELECT name, similarity(name, '张明') AS sim FROM users WHERE name % '张明' -- trigram
name_scope: with tf.name_scope('input'): query_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D ], name='QueryBatch') doc_positive_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D ], name='DocBatch') doc_negative_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D normed 单层 with tf.name_scope('FC1'): # 激活函数在BN之后,所以此处为None query_l1 = add_layer(query_batch, TRIGRAM_D , L1_N, activation_function=None) doc_positive_l1 = add_layer(doc_positive_batch, TRIGRAM_D, L1_N
name_scope: with tf.name_scope('input'): query_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D ], name='QueryBatch') doc_positive_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D ], name='DocBatch') doc_negative_batch = tf.sparse_placeholder(tf.float32, shape=[None, TRIGRAM_D return normed 单层 with tf.name_scope('FC1'): # 激活函数在BN之后,所以此处为None query_l1 = add_layer(query_batch, TRIGRAM_D =None) doc_negative_l1 = add_layer(doc_negative_batch, TRIGRAM_D, L1_N, activation_function=None) with
"analyzer":"index_ansj_analyzer", "type":"text" }, "trigram ":{ "analyzer":"trigram_analyzer", "type":"text" },
)模型 1. # Build the bigram and trigram models 2. bigram = gensim.models.Phrases(data_words, min_count= 5, threshold=100) # higher threshold fewer phrases. 3. trigram = gensim.models.Phrases(bigram[data_words ], threshold=100) 4. 5. # Faster way to get a sentence clubbed as a trigram/bigram 6. bigram_mod = gensim.models.phrases.Phraser(bigram) 7. trigram_mod = gensim.models.phrases.Phraser(trigram) 8. 9. # See trigram example 10. print(trigram_mod[bigram_mod[data_words[0]]]) 删除停用词(stopword),建立二元模型和词形还原(
TRIGRAM Bigram有时是不够的,让我们看看希尔顿夏威夷度假村在TripAdvisor评论中最常见的trigram(三元语法)? word3 %in% stop_words$word) trigram_counts <- trigrams_filtered %>% count(word1, word2, word3, sort = TRUE) trigrams_united <- trigrams_filtered %>% unite(trigram, word1, word2, word3, sep = " ") trigrams_united %>% count(trigram, sort = TRUE) ? 最常见的trigram 是“hilton hawaiian village”,其次是“hilton hawaiian village”,依此类推。
3.2.2 Trigram Russ Cox 在博客 How Google Code Search Worked 中提出用 Trigram 索引来支持代码搜索,其结构与 3.2.1 节中介绍的 3-gram Positional Trigram 与 Trigram 间的关系就是 Positional Postings 与 Postings 间的关系,基本结构如下: { "${trigram}": { " 3.2.5 基于文本索引的查询过程 无论是 Trigram、Positional Trigram 还是 Suffix Array,如果想支持通过正则表达式搜索代码,都要实现以下流程: 将正则表达式转化成子串的 「与」、「或」组合 将子串的组合查询转化成对应的索引查询 (Trigram, Positional Trigram, Suffix Array)执行索引查询,获取候选文档列表 对每个候选文档执行实际的正则表达式 5.1.3 索引 Google Code Search 使用的是最基本的 Trigram Index。
5.准备停用词 6.导入新闻组数据 7.删除电子邮件和换行符 8.标记单词和清理文本 9.创建Bigram和Trigram模型 10.删除停用词,制作双字母组合词和词形变换 11.创建所需的词典和语料库主题建模 'enlighten', 'me', 'on', 'this', 'car', 'saw', 'the', 'other', 'day', (..truncated..))]] 9.创建Bigram和Trigram # Build the bigram and trigram models bigram = gensim.models.Phrases(data_words, min_count=5, threshold =100) # higher threshold fewer phrases. trigram = gensim.models.Phrases(bigram[data_words], threshold (bigram) trigram_mod = gensim.models.phrases.Phraser(trigram) # See trigram example print(trigram_mod
个字母为一组,#表示开始和结束符),boy 这个单词会被切为 #-b-o, b-o-y, o-y-#
这样做的好处有两个:首先是压缩空间,50 万个词的 one-hot 向量空间可以通过 letter-trigram 3.1 输入层
(1)英文
英文的处理方式,除了上文提到的 letter-trigram,CNN-DSSM 还在输入层增加了word-trigram
如上图所示,word-trigram其实就是一个包含了上下文信息的滑动窗口 这句话提取出前三个词 online auto,之后再分别对这三个词进行letter-trigram映射到一个 3 万维的向量空间里,然后把三个向量 concat 起来,最终映射到一个 9 万维的向量空间里 (2)中文
英文的处理方式(word-trigram letter-trigram)在中文中并不可取,因为英文中虽然用了 word-ngram 把样本空间拉成了百万级,但是经过 letter-trigram 而中文如果用 word-trigram,那向量空间就是百万级的了,显然还是字向量(1.5 万维)比较可控。
这样做的好处有两个:首先是压缩空间,50 万个词的 one-hot 向量空间可以通过 letter-trigram 压缩为一个 3 万维的向量空间。 3.1 输入层
(1)英文
英文的处理方式,除了上文提到的 letter-trigram,CNN-DSSM 还在输入层增加了word-trigram
? 如上图所示,word-trigram其实就是一个包含了上下文信息的滑动窗口。 举个例子:把 online auto body ... (2)中文
英文的处理方式(word-trigram letter-trigram)在中文中并不可取,因为英文中虽然用了 word-ngram 把样本空间拉成了百万级,但是经过 letter-trigram 而中文如果用 word-trigram,那向量空间就是百万级的了,显然还是字向量(1.5 万维)比较可控。
3.2 表示层
CNN-DSSM 的表示层由一个卷积神经网络组成,如下图所示:
?
pg_trgm + GIN 索引确实强大,但当表达到千万级后,你可能会遇到这些问题: 问题 表现 原因 索引体积暴涨 GIN 索引文件 > 数据表 trigram 组合多 查询变慢 原本几十毫秒 → 数百毫秒 二、索引膨胀与查询变慢的原理 GIN 索引的结构特点: 类似倒排索引(Inverted Index) 存储大量 trigram → 出现“索引页碎片” 插入频繁时,PostgreSQL 不会立即合并空页 name ~~* '%张%'::text) Planning Time: 0.135 ms Execution Time: 1.920 ms ✅ 若看到 “Bitmap Index Scan”,说明 trigram
使用 Trigram 最多可以将其减慢 5 倍。 随着数据的增长进行扩展更易于管理,它支持所有搜索选项,例如 Trigram、EdgeGram、Stemming、Fuzziness 在我的本地(Razer Blade 2.4 GHz 6 Core i7 最常用的 NGram 类型是 Trigram 和 EdgeGram。 模糊性:模糊匹配允许您获得不完全匹配的结果。例如,搜索单词框也会返回包含 fox 的结果。常见应用包括拼写检查和垃圾邮件过滤。