今天是清明节前的一天,我仔细思路了一下前一段研究日志模式处理时的方法。发现关于层次聚类时有一个
弊端我当时忽略了,就是关于距离度量的问题,我选择的方法会出现距离为无穷大的情况,这样显然是不合理的!
因此今天我就寻找了一天关于距离度量的论文和相关方法,看能不能找到合理的代替方式。最后找到了几个不错的
方式,周末要总结一下。
下午3点,办公室就放假了,不过此时外面下起了大雪。春寒到了,为了不让鞋子走湿,我晚上就去了所里
的食堂吃饭,然后就继续回办公室,想着呆到雪停了再走。因为最近在看微积分,因此就上网搜了一下可微可导
的概念,想复习一下,结果知乎上搜到了一个很好的答案,顺着他的答案,一路看下去,把微积分的发展史
给看了一遍……发现看完已经到了该锁门的时间了,于是我就离开了,但是外面的雪下的还是很大!我晕,回去鞋子
还是湿了!
文本相似度度量相关方法
下面内容主要出自wiki百科,从wiki百科里搜索的字符串比较例子如下:
| Name | Example |
|---|---|
| Hamming distance | "karolin" and "kathrin" is 3. |
| Levenshtein distance and Damerau–Levenshtein distance | kitten and sitting have a distance of 3.
|
| Jaro–Winkler distance | JaroWinklerDist("MARTHA","MARHTA") =
|
| Most frequent k characters | MostFreqKeySimilarity('research', 'seeking', 2) = 2 |
根据这个表格,我研究尝试了一下各个例子的运行。 其中,表格中的前三个距离算法,我直接调用了一个名叫jellyfish的库。 该库是包含的字符匹配算法有如下几种:
- Levenshtein Distance–>编辑距离
- Damerau-Levenshtein Distance
- Jaro Distance
- Jaro-Winkler Distance
- Match Rating Approach Comparison–>匹配评级方法比较
- Hamming Distance–>汉明距离
使用方法非常简单:
import jellyfish
jellyfish.levenshtein_distance(u'jellyfish', u'smellyfish')
即可,当然,传入的不是字符也行,只要是列表类型的数据即可。比如对于我的分类问题,可以传入: [1,2,34,3]和[1,2,11,3]这样算的编辑距离就是1,非常方便。
对于第四个距离的算法,我们直接在这个网页里面,就可以发现各种 语言的实现,直接复制粘贴即可。举个例子:
import collections
def MostFreqKHashing(inputString, K):
occuDict = collections.defaultdict(int)
for c in inputString:
occuDict[c] += 1
occuList = sorted(occuDict.items(), key = lambda x: x[1], reverse = True)
outputDict = collections.OrderedDict(occuList[:K])
#Return OrdredDict instead of string for faster lookup.
return outputDict
def MostFreqKSimilarity(inputStr1, inputStr2):
similarity = 0
for c, cnt1 in inputStr1.items():
#Reduce the time complexity of lookup operation to about O(1).
if c in inputStr2:
cnt2 = inputStr2[c]
similarity += cnt1 + cnt2
return similarity
def MostFreqKSDF(inputStr1, inputStr2, K, maxDistance):
return maxDistance - MostFreqKSimilarity(MostFreqKHashing(inputStr1,K), MostFreqKHashing(inputStr2,K))
str1 = "67676"
str2 = "76765"
K = 3
maxDistance = 100
dict1 = MostFreqKHashing(str1, K)
print("%s:"%dict1)
print(''.join(c + str(cnt) for c, cnt in dict1.items()))
dict2 = MostFreqKHashing(str2, K)
print("%s:"%dict2)
print(''.join(c + str(cnt) for c, cnt in dict2.items()))
print(MostFreqKSDF(str1, str2, K, maxDistance))