计算文本相关度,转http://www.wespoke.com/

本文介绍了一种通过关键词相关性扩展提高文本信息相关度计算精度的方法。该方法不仅考虑关键词的表面意义,还通过引入关键词相关度矩阵,实现了关键词的深度分析与扩展,进而提升文本间相关性的计算准确性。

你知道google和百度两个关键词的相关度是多少么?
--最后我将来回答这个问题

通常我们对于文本信息之间得相关性得计算都是采用向量的办法,我在以前的PPT里曾经提到过。然而对于文本信息更深层次的分析不能单纯从字面上分析一篇文章的关键词,更重要的是它隐含的扩展的意义。

传统的关于计算文本相关度和【网页和查询的相关性】的计算都是采用匹配的方式进行的,然而这只能是基于字面意义上的统计计算。这里介绍的做法是采用关键词相关性扩展的做法从而得到更加精确的相关度计算。

例子:
文章 A: 谈论的是大学教育,最高频的关键词是:学生[3],学习[2],大学[2]
文章 B: 谈论的是普通教育,最高频的关键词是:教育[5],教师[1],进修[1]
[]里是相对的权重,可以理解成 TF*IDF

根据传统的相关性计算,我们会得到如下的结果:

1. 文章A 与 文章B 不相关
2. 查询 学生,学习,大学只能返回文章A,不能返回文章B
3. 查询 教育,教师,进修只能返回文章B,不能返回文章A

分析:
这个显然是有一定的问题的,问题的出现在于我们通常将“字面”的意思做为分析的来源而且依靠和仅仅依靠这些“字面”的关键词做为文章相关性和查询相关性判断的唯一要素。

如何避免?
我在以前的文章中提到过【关键词相关度】的概念,举例说明:
当出现:{学习}这个词汇的时候,真实的表达的意义往往是这样的:
{W1*学习,W2*教育,W3*教师,W4*大学。。。。。。}
其中W1,W2...是学习和相关词汇的相关权重。

基于这样一个矩阵,我们就能够将一个词扩展成为一组词汇,因而也同时可以将文章所对应的向量扩展成一个更多词汇的集合。

这里的计算需要一个完整的相关度矩阵:M

M(i,j) = {关键词i,j的相关度}
而两篇文章的相关度的计算,也由简单的
R= Sigma Vi*Vi
变为
R= Sigma Vi*M(i,j)*Vj

查询关键词和文章的相关度也由简单的
R(i)=TF(i)*IDF(i)
变为
R(i)=Sigma TF(j)*IDF(j)*M(i,j)


下面碰到一个核心问题就是:关键词之间的相关度如何计算?
例如:学校和学生的相关度是多少?
计算方法:
假设一个文章集合 {C},总文章数目为N,其中含有单词A的文章总数为Na,含有单词B的文章总数是Nb,含有{A+B}的文章总数是 Nab,那么相关性这么计算

CorrAB= Nab/(Na+Nb-Nab)-(Na*Nb)/(N*N)

本计算中可能会得到负相关,如果考虑到Na,Nb都是小量,可以忽略,那么

CorrAB= Nab/(Na+Nb-Nab)

至此,要计算相关度之间的全部要素都获得了。

思考,那么到底 学校 和学生 之间的相关度是多少呢?
我们利用google来回答这个问题吧:

约有91,700,000项符合学校的查询结果
约有88,200,000项符合学生的查询结果
约有48,900,000项符合学生 学校的查询结果

Corr{学校,学生}=48,900,000/(91,700,000+88,200,000-48,900,000)=0.37

这个原理我以前应用在了计算【网页信噪比】上,和网页信噪比一起成为衡量一个网页的关键词的核心算法。
这也就是为什么6e的网页信噪比能够不依靠网页上现有的关键词而准确的判断网页的分类和相关度,是因为除了TF和IDF之外,我们能够从已有的文本集合里学到更多的“知识”。

那么百度和google的相关度应该不难计算了:

利用 google计算得到:2,950,000/(61,800,000+6,370,000-2,950,000)=0.03

利用 baidu计算得到:2,760,000/(21,700,000+12,200,000-2,760,000)=0.08

看来基本上相关度小于10%。

 
你遇到的错误是: ``` 段错误 (核心已储) ``` 这是一个典型的 **运行时访问非法内存地址** 导致的崩溃。对于你正在使用的 Protobuf-C 程序,常见原因包括: --- ### ✅ 常见原因及排查建议 #### ✅ 1. **未正确初始化 Protobuf-C 消息字段** Protobuf-C 的 `string` 字段不能直接赋 `NULL` 或未分配的字符串指针,否则在序列化/反序列化时会出错。 **错误示例:** ```c entry.gre_ip = NULL; // ❌ 不推荐 ``` **正确做法:** ```c entry.gre_ip = strdup("192.168.1.1"); // ✅ 正确 ``` 如果你字段可能为空,应使用 `has_gre_ip`(如果存在)或确保字段被正确初始化。 --- #### ✅ 2. **未动态分配 repeated 字段数组** Protobuf-C 的 `repeated string` 字段需要你手动分配数组内存。 **错误示例:** ```c entry.n_subnet = 3; entry.subnet = (char **)subnets; // 如果 subnets 是局部栈数组,可能已失效 ``` **正确做法:** ```c entry.n_subnet = 3; entry.subnet = malloc(3 * sizeof(char *)); entry.subnet[0] = strdup("10.0.0.0/24"); entry.subnet[1] = strdup("10.0.1.0/24"); entry.subnet[2] = strdup("10.0.2.0/24"); ``` 并在使用完后: ```c for (int i = 0; i < entry.n_subnet; i++) free(entry.subnet[i]); free(entry.subnet); ``` --- #### ✅ 3. **未初始化 `ProtobufCMessage` 基类字段** 虽然 `UPLOAD_SUBNET_ENTRY__INIT` 宏会初始化结构体,但在某些情况下仍需手动调用: ```c upload_subnet_entry__init(&entry); ``` 这是更推荐的方式。 --- ### ✅ 推荐修改后的代码片段 ```c UploadSubnetEntry entry; upload_subnet_entry__init(&entry); entry.gre_ip = strdup("192.168.1.1"); entry.n_subnet = 3; entry.subnet = malloc(3 * sizeof(char *)); entry.subnet[0] = strdup("10.0.0.0/24"); entry.subnet[1] = strdup("10.0.1.0/24"); entry.subnet[2] = strdup("10.0.2.0/24"); entry.n_neighbor_gre_ip = 2; entry.neighbor_gre_ip = malloc(2 * sizeof(char *)); entry.neighbor_gre_ip[0] = strdup("192.168.1.2"); entry.neighbor_gre_ip[1] = strdup("192.168.1.3"); ``` --- ### ✅ 使用 `valgrind` 调试内存问题(推荐) 你可以使用 `valgrind` 来检测内存访问错误: ```bash valgrind ./spoke_to_hub ``` 输出会指出具体哪一行访问了非法内存。 --- ### ✅ 总结修复步骤 | 步骤 | 内容 | |------|------| | 1 | 使用 `upload_subnet_entry__init()` 初始化结构体 | | 2 | 所有字符串字段使用 `strdup()` 分配新内存 | | 3 | `repeated string` 字段手动分配数组和每个字符串 | | 4 | 使用 `valgrind` 检查内存访问问题 | | 5 | 确保在程序退出前释放所有 `malloc` 和 `strdup` 分配的内存 | ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值