天天看點

python利用餘弦相似度聚類_使用python基于餘弦相似度探索人員相關性

課題1

畢業設計裡面涉及到人員相關度的計算,在這裡我提出了一個猜想,大緻如下:

現有資料:學生id、學生手機mac位址、時間戳、地點id

構想:通過學生mac位址某地點出現頻次,建構頻次矩陣,比如說現有六個地點,ABCDEF,某學生出現的頻次分别為1、5、2、4、7、3,則[1,5,2,4,7,3]即為該學生在矩陣中的表現形式。(總的來說就是講每個學生的出現頻次規律抽象成一個向量,該向量由n個Term組成,每個Term都有一個權重,不同的頻次根據學生在總矩陣中影響相關度的權重)

實作步驟:

1.資料預處理,建立空間向量模型,表現形式為:[[3,4,1,5,6,7],[6,4,5,5,2,1],......];

2.特征抽取完之後,對矩陣進行正則化處理。

3.計算餘弦相似度。

python利用餘弦相似度聚類_使用python基于餘弦相似度探索人員相關性

image.png

分子:兩個向量的點乘積

分母:兩個向量的模的乘積

知識點:

1.利用python進行矩陣的正則化

正則化的過程是将每個樣本縮放到機關範數(每個樣本的範數為1),如果後面要使用如二次型(點積)或者其它核方法計算兩個樣本之間的相似性這個方法會很有用。

Normalization主要思想是對每個樣本計算其p-範數,然後對該樣本中每個元素除以該範數,這樣處理的結果是使得每個處理後樣本的p-範數(l1-norm,l2-norm)等于1。

p-範數的計算公式:||X||p=(|x1|^p+|x2|^p+...+|xn|^p)^1/p

該方法主要應用于文本分類和聚類中。例如,對于兩個TF-IDF向量的l2-norm進行點積,就可以得到這兩個向量的餘弦相似性。

sklearn資料預處理函數:

from sklearn import preprocessing

2.python字典排序

知識點參照:python字典排序

python代碼

# -*- coding: UTF-8 -*-

__author__ = 'Suzibo'

import numpy as np

import pandas as pd

from sklearn import preprocessing

from sklearn import feature_extraction

#from sklearn.feature_extraction.text import TfidfTransformer

#from sklearn.feature_extraction.text import CountVectorizer

arr = np.array([[3,5,3,0,5,5],

[3,4,3,3,5,1],

[5,7,8,12,1,0],

[5,1,3,1,1,2],

[0,7,3,1,5,1],

[7,1,2,3,6,1],

[0,9,2,1,4,1],

[3,0,3,1,0,5]])

#模拟了ABCDEF六個感覺點,對應的八個人的頻次矩陣。TAT,因為遲遲拿不到資料,隻能靠自己模拟資料玩玩了,慘_(:з」∠)_

arr_normalized = preprocessing.normalize(arr)

#将原始矩陣正則化

result = np.zeros(((len(arr)-1),2))

n=0

#初始化結果矩陣(N行2列的0矩陣)

a=dict()

#初始化字典

for i in range(1,len(arr)):

#比較第一名同學跟其他同學的餘弦相似度

num = np.sum(arr_normalized[0]*arr_normalized[i])

#向量乘積

denom = np.linalg.norm(arr_normalized[0]) * np.linalg.norm(arr_normalized[i])

#向量模的乘積

cos = num/denom

sim = 0.5 + 0.5*cos

#結果歸一化

result[n][0]=i

result[n][1]=sim

n=n+1

#結果存入數組

a[i] = sim

#結果存入字典

print result

print sorted(a.iteritems(),key=lambda asd:asd[1],reverse=True)

#在這裡,用了字典對象a以及初始化了數組result分别存儲計算結果。其實兩種方法皆可,但是字典排序寫起來更加快速。

result:

[[ 1. 0.92443667]

[ 2. 0.7434795 ]

[ 3. 0.85627822]

[ 4. 0.91615085]

[ 5. 0.84737882]

[ 6. 0.88826077]

[ 7. 0.83610165]]

sorted(a.iteritems(),key=lambda asd:asd[1],reverse=True):

[(1, 0.9244366688881116), (4, 0.91615085086634984), (6, 0.88826076864678882), (3, 0.85627822353819516), (5, 0.84737881773469248), (7, 0.83610165222088828), (2, 0.74347950132065999)]