開發(fā)環(huán)境
系統(tǒng): macOS Sierra骚揍; 開發(fā)軟件: PyChram CE信不; 運行環(huán)境: Python3.6
需求分析
在用戶閱讀某篇文章的時候,為用戶推薦更多與在讀文章內(nèi)容相似的文章
概念
<b>相似推薦</b>:當用戶表現(xiàn)出對某人或某物感興趣時硫戈,為他/她推薦相似的人或物丁逝,核心思想:人以類聚梭姓,物以群分誉尖;
<b>協(xié)同過濾推薦</b>:指利用用戶過去的行為或意見萝衩,預測當前用戶最喜歡哪些東西或對哪些東西感興趣
采用余弦相似度原理來實現(xiàn)相似文章推薦
<b>原理:</b>
將每篇文章的詞頻統(tǒng)計結果當作一個向量猩谊,如果兩篇文章向量的夾角越小即余弦值越接近1牌捷,那么我們說這兩篇文章越相似
原理.png
假如有如下兩篇文章
文章A - '放假我喜歡彈吉他暗甥,看書'
文章B - '放假我不喜歡看書撤防,喜歡打球'
這兩篇文章的詞頻統(tǒng)計結果如下:
放假 我 喜歡 彈 吉他 看書 不 打球
文章A 1 1 1 1 1 1 0 0
文章B 1 1 2 0 0 1 1 1
則根據(jù)余弦計算公式寄月,文章A和文章B兩個向量間的余弦值計算如下:
math.png
若余弦值越接近1漾肮, 則說明文章A和B越相似
-
導入需要用到的包
import os
import codecs
import re
import jieba
import pandas
import numpy
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import pairwise_distances
-
創(chuàng)建語料庫
# 創(chuàng)建語料庫
filePaths = []
fileContents = []
for root, dirs, files in os.walk(
'data/SogouC.mini/Sample'
):
for name in files:
filePath = os.path.join(root, name)
f = codecs.open(filePath, 'r', 'utf-8')
fileContent = f.read()
f.close()
filePaths.append(filePath)
fileContents.append(fileContent)
corpus = pandas.DataFrame({
'filePath': filePaths,
'fileContent': fileContents
})
語料庫中的文章是從搜狗實驗室下載的,內(nèi)容如下:
目錄結構.png
創(chuàng)建的語料庫如下:
語料庫.png
-
對文章進行分詞
# 匹配中文分詞
zhPattern = re.compile(u'[\u4e00-\u9fa5]+')
# 對每篇文章進行分詞處理
for index, row in corpus.iterrows():
fileContent = row['fileContent']
segments = []
segs = jieba.cut(fileContent) # 分詞默認以','分隔
for seg in segs:
if zhPattern.search(seg):
segments.append(seg)
row['fileContent'] = ' '.join(segments) # 將分詞以空格分隔
分詞后結果如下:
分詞.png
-
統(tǒng)計詞頻,將詞頻向量化
# 讀取停用詞文件
stopWords = pandas.read_csv(
'data/StopwordsCN.txt',
encoding='utf-8',
index_col=False,
quoting=3,
sep='\t'
)
# 詞頻統(tǒng)計 & 文檔向量化
countVectorizer = CountVectorizer(
stop_words=list(stopWords['stopword'].values),
min_df=0,
token_pattern=r"\b\w+\b"
)
textVector = countVectorizer.fit_transform(corpus['fileContent'])
詞頻矩陣如下:
vector.png
-
統(tǒng)計詞頻矩陣的余弦相似度計算
# 統(tǒng)計詞頻矩陣的余弦相似度計算
distance_matrix = pairwise_distances(
textVector,
metric='cosine'
)
運行結果如下:
cosine.png
上面的矩陣代表的意思是兩個文章(即兩個向量)之間的夾角值,這里我用x代替上面矩陣中的數(shù)值扔亥。 為什么斜對角的數(shù)值都為0呢旅挤?因為文章跟本身是完全相同的伞鲫,所以兩個向量相同,夾角值為0
文章1 文章2 文章3 ... 文章n
文章1 0 x x ... x
文章2 x 0 x ... x
文章3 x x 0 ... x
... ... ... ... ... ...
文章n x x x ... 0
-
獲取與該文章最相似的3篇文章(即矩陣中值最小的前三個)
# 獲取與本篇文章相似度最高的三篇文章
sort_matrix = numpy.argsort(distance_matrix, axis=1)[:, 1:4] # argsort為升序排列,取第1列到第3列的值儒搭,第0列為自己本身
similarity = pandas.Index(filePaths)[sort_matrix].values
similarityDF = pandas.DataFrame({
'filePath': filePaths,
's1': similarity[:, 0],
's2': similarity[:, 1],
's3': similarity[:, 2],
})
最后結果如下:
result.png
-
參考
小蚊子數(shù)據(jù)分析