Rocchio 算法

该算法(Rocchio,1971)是20 世纪70 年代左右在Salton 的SMART 系统中引入并广泛流传的一种相关反馈算法。

(1)Rocchio算法应用于文本分类

基本的思路是把一个类别里的样本文档各项取个平均值(例如把所有 “体育”类文档中词汇“篮球”出现的次数取个平均值,再把“裁判”取个平均值,依次做下去),可以得到一个新的向量,形象的称之为“质心”,质心就成了这个类别最具代表性的向量表示。

有新文档需要判断的时候,比较新文档和质心有多么相像(八股点说,判断他们之间的距离)就可以确定新文档属不属于这个类。

稍微改进一点的Rocchio算法不仅考虑属于这个类别的文档(称为正样本),也考虑不属于这个类别的文档数据(称为负样本),计算出来的质心尽量靠近正样本同时尽量远离负样本。

       Rocchio算法做了两个很致命的假设:

       一:它认为一个类别的文档仅仅聚集在一个质心的周围,实际情况往往不是如此(这样的数据称为线性不可分的);

       二:它假设训练数据是绝对正确的,因为它没有任何定量衡量样本是否含有噪声的机制,因而也就对错误数据毫无抵抗力。

常常被用来做科研中比较不同算法优劣的基线系统(Base Line)

(2)Rocchio算法应用于查询扩展

Rocchio 算法是相关反馈实现中的一个经典算法,它提供了一种将相关反馈信息融到向量空间模型的方法。基本理论:假定我们要找一个最优查询向量q ,它与相关文档之间的相似度最大且同时又和不相关文档之间的相似度最小。若Cr表示相关文档集,Cnr表示不相关文档集,那么我们希望找到的最优的q 是:


 sim 函数用于计算相似度。采用余弦相似度计算时,能够将相关文档与不相关文档区分开的最优查询向量为:


这就是说,最优的查询向量等于相关文档的质心向量和不相关文档的质心向量的差。然而,这个发现并没有什么意义,因为检索本来的目的就是要找相关文档,而所有的相关文档集事先却是未知的。


在一个真实的信息检索场景中,假定我们有一个用户查询,并知道部分相关文档和不相关文档的信息,则可以通过如下公式得到修改后的查询向量q:


其中, q 是原始的查询向量,Dr 和Dnr 是已知的相关和不相关文档集合。α、β 及γ 是上述三者的权重。这些权重能够控制判定结果和原始查询向量之间的平衡:如果存在大量已判断的文档,那么会给β 及γ 赋予较高的权重。修改后的新查询从q0 开始,向着相关文档的质心向量靠近了一段距离,而同时又与不相关文档的质心向量远离了一段距离。

新查询可以采用常规的向量空间模型进行检索。通过减去不相关文档的向量,我们很容易保留向量空间的正值分量。在Rocchio 算法中,文档向量中的权重分量如果为负值,那么该分量将会被忽略,也就是说,此时会将该分量权重设为0。下图给出了应用相关反馈技术的效果示意图。


相关反馈可以同时提高召回率和正确率。然而,实际表明该技术在一些重召回率的场景下对于提高召回率非常有用。这其中的部分原因在于它对查询进行了扩展,另一个原因是应用的场景所带来的结果:在期望高召回率的情况下,可以预计用户可能会花更多时间来浏览结果并进行反复搜索。正反馈往往比负反馈更有价值,因此在很多IR系统中,会将参数设置成γ < β。一个合理的取值是α = 1、β = 0.75 及γ = 0.15。实际上,很多系统,都只允许进行正反馈,即相当于设置γ = 0。还有一种做法是,只取检索系统返回结果中排名最高的标记为不相关的文档进行负反馈,此时,公式中的|Dnr| = 1。尽管上述相关反馈方法存在各种变形,并且很多比较实验也没有取得一致性的结论,但是一些研究却认为一种称为Ide dec-hi 的公式最有效或至少在性能上表现最稳定。Ide dec-hi 的公式如下:




  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Rocchio算法是一种基于向量空间模型的文本分类算法,其思想是将测试文档的向量表示与已知类别的训练文档的向量表示进行比较,根据最相似的训练文档的类别来预测测试文档的类别。以下是一个基于Rocchio算法的测试文档分类的Python代码示例: ```python import numpy as np class RocchioClassifier: def __init__(self, alpha=1, beta=0.75, threshold=0): self.alpha = alpha # 加权因子 self.beta = beta # 减权因子 self.threshold = threshold # 判断阈值 def fit(self, X, y): # 计算各个类别的文档向量的平均值 self.class_means = {} for label in np.unique(y): self.class_means[label] = np.mean(X[y == label], axis=0) def predict(self, X): y_pred = [] for x in X: # 计算测试文档向量与各个类别的文档向量的余弦相似度 similarities = {} for label, mean in self.class_means.items(): similarities[label] = np.dot(x, mean) / (np.linalg.norm(x) * np.linalg.norm(mean)) # 根据余弦相似度最大的类别来预测测试文档的类别 max_label = max(similarities, key=similarities.get) if similarities[max_label] >= self.threshold: y_pred.append(max_label) else: y_pred.append(None) return y_pred def fit_predict(self, X_train, y_train, X_test): self.fit(X_train, y_train) return self.predict(X_test) ``` 使用示例: ```python from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 加载数据集 newsgroups = fetch_20newsgroups(subset='all') # 特征提取 vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(newsgroups.data) y = newsgroups.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 训练并预测 clf = RocchioClassifier() y_pred = clf.fit_predict(X_train, y_train, X_test) # 评估分类器性能 print(classification_report(y_test, y_pred, target_names=newsgroups.target_names)) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值