最近幫不少本科畢業生作文本數據分析,常常遇到的一個需求是計算文檔類似度。算法
思路:機器學習
抽取語料(全部文檔)中的詞語,構建詞典(詞語與數字對應起來)。ide
根據構建的詞典對每一個文檔進行從新編碼(將文檔轉化爲向量)。函數
下面的corpus是我在知乎live隨便找到的幾個評論,拿來當作測試的例子。好像數據不怎麼好玩,你們跟着一塊兒湊合湊合吧。學習
corpus = ['老師講的很好很全面乾貨不少', '講述的很好乾貨滿滿', '滿滿的乾貨很實用', '感謝老師無私的分享啦', '真水呵呵噠']
構建詞典-學習語料特徵
其實在機器學習裏,學習語料的全部詞語並將其轉化爲數字,這一步驟叫作特徵化。強烈推薦對數據科學感興趣的童鞋學學scikit-learn庫,人工智能我們小白可能還玩不轉,可是調用封裝好的機器學習算法,淺顯的玩玩機器學習仍是沒啥難度的。測試
在scikit-learn中,涉及到文本數據特徵化的類有sklearn.feature_extraction.text.CountVectorizer 和sklearn.feature_extraction.text.TfidfVectorizer 。咱們先以常見的詞頻統計做爲特徵抽取的方式開始探索,因爲scikit默認使用英文空格做爲分詞符號,因此處理中文數據前咱們要分詞並以空格間隔開來。編碼
from sklearn.feature_extraction.text import CountVectorizer import jieba corpus = [' '.join(jieba.lcut(doc)) for doc in corpus]corpus ['老師 講 的 很 好 很 全面 乾貨 不少', '講述 的 很 好 乾貨 滿滿', '滿滿的 乾貨 很 實用', '感謝 老師 無私 的 分享 啦', '真水 呵呵 噠'] wordcounter = CountVectorizer() #學習特徵(構建詞典)fit 並轉化爲特徵矩陣。 matrix=wordcounter.fit_transform(corpus) print(matrix.toarray()) #查看下特徵與詞語對應關係 print(wordcounter.get_feature_names()) [[1 0 0 0 1 1 0 0 0 0 0 1 0] [0 0 0 0 1 0 0 0 1 0 0 0 1] [0 0 0 1 1 0 0 0 0 1 0 0 0] [0 1 0 0 0 0 1 1 0 0 0 1 0] [0 0 1 0 0 0 0 0 0 0 1 0 0]] ['全面', '分享', '呵呵', '實用', '乾貨', '不少', '感謝', '無私', '滿滿', '滿滿的', '真水', '老師', '講述']
計算類似度
這裏使用scikit提供的cosine-similarity函數。人工智能
from sklearn.metrics.pairwise import cosine_similarity cosine_similarity(matrix) array([[1. , 0.28867513, 0.28867513, 0.25 , 0. ], [0.28867513, 1. , 0.33333333, 0. , 0. ], [0.28867513, 0.33333333, 1. , 0. , 0. ], [0.25 , 0. , 0. , 1. , 0. ], [0. , 0. , 0. , 0. , 1. ]]) 咱們看到這個矩陣是沿着對角線對稱的,因此咱們只須要看第一行。 第一個評論與第一個評論之間的類似度爲1 第一個評論與第二個評論的類似度爲0.28867513 第一個評論與第三個評論的類似度爲0.28867513 第一個評論與第四個評論的類似度爲0.25 第一個評論與第四個評論的類似度爲0
高中數學知識cos類似性計算公式
本覺得本身對這裏很熟悉,結果本身寫cos計算公式時竟然出錯了。粘貼到這裏,幫助你們回憶高中知識。(a和b是向量)code
#cos類似性計算orm
def cosVector(x,y): result1=0.0 result2=0.0 result3=0.0 for i in range(len(x)): result1 +=x[i]*y[i] #sum(a*b) result2 +=x[i]**2 #sum(a*a) result3 +=y[i]**2 #sum(b*b) return str(result1/((result2*result3)**0.5)) vect1 = [1,0,1] vect2 = [0,1,0] vect3 = [1,1,1] print("vect1與vect2類似度爲:", cosVector(vect1, vect2)) print("vect1與vect3類似度爲:", cosVector(vect1, vect3)) print("vect2與vect3類似度爲:", cosVector(vect2, vect3)) vect1與vect2類似度爲: 0.0 vect1與vect3類似度爲: 0.8164965809277261 vect2與vect3類似度爲: 0.5773502691896258