similarity += (re1 * re2 + im1 * im2) / (sqrt(re1 * re1 + im1 * im1) * sqrt(re2 * re2 + im2 * im2));如果分母为0时会有问题吧?请问怎么修改?
时间: 2024-01-17 09:17:51 浏览: 30
当分母为0时,会导致除法运算错误。为了避免这种情况,可以在计算之前先判断分母是否为0,如果为0则进行特殊处理。
以下是一种可能的修改方法:
```python
if (sqrt(re1 * re1 + im1 * im1) * sqrt(re2 * re2 + im2 * im2)) == 0:
similarity = 0
else:
similarity += (re1 * re2 + im1 * im2) / (sqrt(re1 * re1 + im1 * im1) * sqrt(re2 * re2 + im2 * im2))
```
这样,当分母为0时,similarity的值将被设置为0,避免了除以0的错误。
相关问题
“@Override public double itemSimilarity(long itemID1, long itemID2) throws Exception{ PreferenceArray xPrefs = dataModel.getPreferencesForItem(itemID1); PreferenceArray yPrefs = dataModel.getPreferencesForItem(itemID2); int xLength = xPrefs.length(); int yLength = yPrefs.length(); if (xLength == 0 || yLength == 0) { return Double.NaN; } long xIndex = xPrefs.getUserID(0); long yIndex = yPrefs.getUserID(0); int xPrefIndex = 0; int yPrefIndex = 0; double sumX = 0.0; double sumX2 = 0.0; double sumY = 0.0; double sumY2 = 0.0; double sumXY = 0.0; double sumXYdiff2 = 0.0; int count = 0; while (true) { int compare = Long.compare(xIndex, yIndex); if (compare == 0) { double x = xPrefs.getValue(xPrefIndex); double y = yPrefs.getValue(yPrefIndex); sumXY += x * y; sumX += x; sumX2 += x * x; sumY += y; sumY2 += y * y; double diff = x - y; sumXYdiff2 += diff * diff; count++; } if (compare <= 0) { if (++xPrefIndex == xLength) { break; } xIndex = xPrefs.getUserID(xPrefIndex); } if (compare >= 0) { if (++yPrefIndex == yLength) { break; } yIndex = yPrefs.getUserID(yPrefIndex); } } double meanX = sumX / count; double meanY = sumY / count; double numerator = sumXY - sumX * sumY / count; double denominator = Math.sqrt((sumX2 - sumX * meanX) * (sumY2 - sumY * meanY)); if (denominator == 0.0) { return Double.NaN; } double result = numerator / denominator; if (!Double.isNaN(result)) { result = normalizeWeightResult(result, count, cachedNumUsers); } return result; }” 解释代码
这段代码是一个实现了ItemSimilarity接口的类中的itemSimilarity方法。该方法用于计算两个物品的相似度,并返回相似度值。
具体实现过程如下:
1. 获取两个物品的PreferenceArray,PreferenceArray是用于存储用户对物品评分的数据结构。
2. 判断两个PreferenceArray的长度是否为0,如果有一个为0则返回Double.NaN(表示无法计算相似度)。
3. 初始化一些变量用于计算相似度,包括sumX、sumX2、sumY、sumY2、sumXY、sumXYdiff2和count。
4. 通过while循环遍历两个PreferenceArray,将相同用户对两个物品的评分进行相似度计算。
5. 计算相似度的分子和分母。
6. 如果分母为0,则返回Double.NaN。
7. 对相似度进行归一化处理,并返回结果。
其中,normalizeWeightResult方法是对计算结果进行归一化的方法。cachedNumUsers是用于缓存用户数量的变量。
import sys import re import jieba import codecs import gensim import numpy as np import pandas as pd def segment(doc: str): stop_words = pd.read_csv('data/stopwords.txt', index_col=False, quoting=3, names=['stopword'], sep='\n', encoding='utf-8') stop_words = list(stop_words.stopword) reg_html = re.compile(r'<[^>]+>', re.S) # 去掉html标签数字等 doc = reg_html.sub('', doc) doc = re.sub('[0-9]', '', doc) doc = re.sub('\s', '', doc) word_list = list(jieba.cut(doc)) out_str = '' for word in word_list: if word not in stop_words: out_str += word out_str += ' ' segments = out_str.split(sep=' ') return segments def doc2vec(file_name, model): start_alpha = 0.01 infer_epoch = 1000 doc = segment(codecs.open(file_name, 'r', 'utf-8').read()) vector = model.docvecs[doc_id] return model.infer_vector(doc) # 计算两个向量余弦值 def similarity(a_vect, b_vect): dot_val = 0.0 a_norm = 0.0 b_norm = 0.0 cos = None for a, b in zip(a_vect, b_vect): dot_val += a * b a_norm += a ** 2 b_norm += b ** 2 if a_norm == 0.0 or b_norm == 0.0: cos = -1 else: cos = dot_val / ((a_norm * b_norm) ** 0.5) return cos def test_model(file1, file2): print('导入模型') model_path = 'tmp/zhwk_news.doc2vec' model = gensim.models.Doc2Vec.load(model_path) vect1 = doc2vec(file1, model) # 转成句子向量 vect2 = doc2vec(file2, model) print(sys.getsizeof(vect1)) # 查看变量占用空间大小 print(sys.getsizeof(vect2)) cos = similarity(vect1, vect2) print('相似度:%0.2f%%' % (cos * 100)) if __name__ == '__main__': file1 = 'data/corpus_test/t1.txt' file2 = 'data/corpus_test/t2.txt' test_model(file1, file2) 有什么问题 ,怎么解决
在 `doc2vec()` 函数中,你在尝试访问 `doc_id` 变量,但是该变量未定义,这会导致 `NameError` 错误。你需要将该变量定义为函数的参数,并在调用函数时传递文档的标识符。
另外,在 `doc2vec()` 函数中,你在尝试将 `Doc2Vec` 模型返回的向量赋值给 `vector` 变量,但是该变量没有使用,这会导致不必要的计算和内存占用。你应该直接返回模型返回的向量。
最后,在 `test_model()` 函数中,你在尝试打印向量的内存占用大小,但是你应该打印向量本身的大小,而不是指向向量的变量的大小。你可以使用 `np.ndarray.nbytes` 属性来获取向量的大小。
下面是修改后的代码:
```
import sys
import re
import jieba
import codecs
import gensim
import numpy as np
import pandas as pd
def segment(doc: str):
stop_words = pd.read_csv('data/stopwords.txt', index_col=False, quoting=3,
names=['stopword'], sep='\n', encoding='utf-8')
stop_words = list(stop_words.stopword)
reg_html = re.compile(r'<[^>]+>', re.S) # 去掉html标签数字等
doc = reg_html.sub('', doc)
doc = re.sub('[0-9]', '', doc)
doc = re.sub('\s', '', doc)
word_list = list(jieba.cut(doc))
out_str = ''
for word in word_list:
if word not in stop_words:
out_str += word
out_str += ' '
segments = out_str.split(sep=' ')
return segments
def doc2vec(file_name, model, doc_id):
start_alpha = 0.01
infer_epoch = 1000
doc = segment(codecs.open(file_name, 'r', 'utf-8').read())
return model.infer_vector(doc, alpha=start_alpha, steps=infer_epoch)
# 计算两个向量余弦值
def similarity(a_vect, b_vect):
dot_val = 0.0
a_norm = 0.0
b_norm = 0.0
cos = None
for a, b in zip(a_vect, b_vect):
dot_val += a * b
a_norm += a ** 2
b_norm += b ** 2
if a_norm == 0.0 or b_norm == 0.0:
cos = -1
else:
cos = dot_val / ((a_norm * b_norm) ** 0.5)
return cos
def test_model(file1, file2):
print('导入模型')
model_path = 'tmp/zhwk_news.doc2vec'
model = gensim.models.Doc2Vec.load(model_path)
vect1 = doc2vec(file1, model, doc_id=0) # 转成句子向量
vect2 = doc2vec(file2, model, doc_id=1)
print(vect1.nbytes) # 查看向量大小
print(vect2.nbytes)
cos = similarity(vect1, vect2)
print('相似度:%0.2f%%' % (cos * 100))
if __name__ == '__main__':
file1 = 'data/corpus_test/t1.txt'
file2 = 'data/corpus_test/t2.txt'
test_model(file1, file2)
```
相关推荐
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)