物以类聚人以群分,通过GensimLda文本聚类算法构建人工智能个性化推荐系统(Python3.10)

简介: 众所周知,个性化推荐系统能够根据用户的兴趣、偏好等信息向用户推荐相关内容,使得用户更感兴趣,从而提升用户体验,提高用户粘度,之前我们曾经使用[协同过滤算法构建过个性化推荐系统](https://v3u.cn/a_id_136),但基于显式反馈的算法就会有一定的局限性,本次我们使用无监督的Lda文本聚类方式来构建文本的个性化推荐系统。

众所周知,个性化推荐系统能够根据用户的兴趣、偏好等信息向用户推荐相关内容,使得用户更感兴趣,从而提升用户体验,提高用户粘度,之前我们曾经使用协同过滤算法构建过个性化推荐系统,但基于显式反馈的算法就会有一定的局限性,本次我们使用无监督的Lda文本聚类方式来构建文本的个性化推荐系统。

推荐算法:协同过滤/Lda聚类

我们知道,协同过滤算法是一种基于用户的历史行为来推荐物品的算法。协同过滤算法利用用户之间的相似性来推荐物品,如果两个用户对某些物品的评分相似,则协同过滤算法会将这两个用户视为相似的,并向其中一个用户推荐另一个用户喜欢的物品。

说白了,它基于用户的显式反馈,什么是显式反馈?举个例子,本如本篇文章,用户看了之后,可能会点赞,也可能会疯狂点踩,或者写一些关于文本的评论,当然评论内容可能是负面、正面或者中性,所有这些用户给出的行为,都是显式反馈,但如果用户没有反馈出这些行为,就只是看了看,协同过滤算法的效果就会变差。

LDA聚类是一种文本聚类算法,它通过对文本进行主题建模来聚类文本。LDA聚类算法在聚类文本时,不考虑用户的历史行为,而是根据文本的内容和主题来聚类。

说得通俗一点,协同过滤是一种主动推荐,系统根据用户历史行为来进行内容推荐,而LDA聚类则是一种被动推荐,在用户还没有产生用户行为时,就已经开始推荐动作。

LDA聚类的主要目的是将文本分为几类,使得每类文本的主题尽可能相似。

LDA聚类算法的工作流程大致如下:

1.对文本进行预处理,去除停用词等。

2.使用LDA模型对文本进行主题建模,得到文本的主题分布。

3.将文本按照主题分布相似性进行聚类。

4.将聚类结果作为类标签,对文本进行分类。

大体上,LDA聚类算法是一种自动将文本分类的算法,它通过对文本进行主题建模,将文本按照主题相似性进行聚类,最终实现文本的分类。

Python3.10实现

实际应用层面,我们需要做的是让主题模型能够识别在文本里的主题,并且挖掘文本信息中隐式信息,并且在主题聚合、从非结构化文本中提取信息。

首先安装分词以及聚类模型库:

pip3 install jieba  
pip3 install gensim

随后进行分词操作,这里以笔者的几篇文章为例子:

import jieba  
import pandas as pd  
import numpy as np  
title1="乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。"  
title2="Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现"  
title3="周而复始,往复循环,递归、尾递归算法与无限极层级结构的探究和使用(Golang1.18)"  
title4="彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07"  
content = [title1,title2, title3,title4]  
  
  
#分词  
content_S = []  
all_words = []  
for line in content:  
    current_segment = [w for w in jieba.cut(line) if len(w)>1]  
    for x in current_segment:  
        all_words.append(x)  
    if len(current_segment) > 1 and current_segment != '\r\t':  
        content_S.append(current_segment)  
#分词结果转为DataFrame  
df_content = pd.DataFrame({'content_S':content_S})  
  
print(all_words)

可以看到,这里通过四篇文章标题构建分词列表,最后打印分词结果:

['乾坤', '挪移', '如何', '同步', '阻塞', 'sync', '三方', '库包', '转换', '异步', '阻塞', 'async', '模式', 'Python3.10', '实现', 'Generator', '生成器', '入门', '初基', 'Coroutine', '原生', '协程', '登峰造极', 'Python3.10', '并发', '异步', '编程', 'async', '底层', '实现', '周而复始', '往复', '循环', '递归', '递归', '算法', '无限极', '层级', '结构', '探究', '使用', 'Golang1.18', '彩虹', '女神', '长空', 'Go', '语言', '进阶', 'Go', '语言', '高性能', 'Web', '框架', 'Iris', '项目', '实战', 'JWT', '中间件', 'Middleware', '使用', 'EP07']

接着就可以针对这些词进行聚类操作,我们可以先让ChatGPT帮我们进行聚类看看结果:

可以看到,ChatGPT已经帮我们将分词结果进行聚类操作,分为两大类:Python和Golang。

严谨起见,我们可以针对分词结果进行过滤操作,过滤内容是停用词,停用词是在文本分析、自然语言处理等应用中,用来过滤掉不需要的词的。通常来说,停用词是指在英文中的介词、代词、连接词等常用词,在中文中的助词、介词、连词等常用词:

———  
》),  
)÷(1-  
”,  
)、  
=(  
:  
→  
℃   
&  
*  
一一  


.

.一

./


=″

[*]
}>
[⑤]]
[①D]
c]
ng昉

//


[②e]
[②g]
={
}
,也


[①⑥]
[②B]
[①a]
[④a]
[①③]
[③h]
③]
1.
--
[②b]
’‘
×××
[①⑧]
0:2
=[
[⑤b]
[②c]
[④b]
[②③]
[③a]
[④c]
[①⑤]
[①⑦]
[①g]
∈[
[①⑨]
[①④]
[①c]
[②f]
[②⑧]
[②①]
[①C]
[③c]
[③g]
[②⑤]
[②②]
一.
[①h]
.数
[]
[①B]
数/
[①i]
[③e]
[①①]
[④d]
[④e]
[③b]
[⑤a]
[①A]
[②⑧]
[②⑦]
[①d]
[②j]
〕〔
][
://
′∈
[②④
[⑤e]
12%
b]
...
...................
…………………………………………………③
ZXFITL
[③F]

[①o]
]∧′=[
∪φ∈
′|
{-
②c

[③①]
R.L.
[①E]
Ψ
-[*]-

.日
[②d]
[②
[②⑦]
[②②]
[③e]
[①i]
[①B]
[①h]
[①d]
[①g]
[①②]
[②a]
f]
[⑩]
a]
[①e]
[②h]
[②⑥]
[③d]
[②⑩]
e]


元/吨
[②⑩]
2.3%
5:0
[①]
::
[②]
[③]
[④]
[⑤]
[⑥]
[⑦]
[⑧]
[⑨]
……
——
?












,

'
?
·
———
──
?

<





[
]
(
)


×

/











В
"
;

@
γ
μ
φ
φ.
×
Δ


sub
exp
sup
sub
Lex





+ξ
++

-β

<±
<Δ
<λ
<φ
<<
=

=☆
=-

>λ
_
~±
~+
[⑤f]
[⑤d]
[②i]

[②G]
[①f]
LI

[-
......

[③⑩]
第二
一番
一直
一个
一些
许多

有的是
也就是说
末##末



哎呀
哎哟


俺们

按照

吧哒

罢了


本着

比方
比如
鄙人

彼此


别的
别说

并且
不比
不成
不单
不但
不独
不管
不光
不过
不仅
不拘
不论
不怕
不然
不如
不特
不惟
不问
不只

朝着

趁着



除此之外
除非
除了

此间
此外

从而



但是

当着



的话

等等


叮咚

对于

多少

而况
而且
而是
而外
而言
而已
尔后
反过来
反过来说
反之
非但
非徒
否则

嘎登




各个
各位
各种
各自

根据


故此
固然
关于


果然
果真


哈哈



何处
何况
何时


哼唷
呼哧


还是
还有
换句话说
换言之

或是
或者
极了

及其
及至

即便
即或
即令
即若
即使

几时


既然
既是
继而
加之
假如
假若
假使
鉴于


较之

接着
结果

紧接着
进而

尽管

经过

就是
就是说

具体地说
具体说来
开始
开外



可见
可是
可以
况且


来着

例如


连同
两者



另外
另一方面



慢说
漫说



每当

莫若

某个
某些


哪边
哪儿
哪个
哪里
哪年
哪怕
哪天
哪些
哪样

那边
那儿
那个
那会儿
那里
那么
那么些
那么样
那时
那些
那样

乃至



你们


宁可
宁肯
宁愿


啪达
旁人


凭借

其次
其二
其他
其它
其一
其余
其中

起见
起见
岂但
恰恰相反
前后
前者

然而
然后
然则

人家

任何
任凭

如此
如果
如何
如其
如若
如上所述

若非
若是

上下
尚且
设若
设使
甚而
甚么
甚至
省得
时候
什么
什么样
使得

是的
首先

谁知

顺着
似的

虽然
虽说
虽则

随着

所以

他们
他人

它们

她们

倘或
倘然
倘若
倘使


通过

同时

万一



为何
为了
为什么
为着

嗡嗡

我们

呜呼
乌乎
无论
无宁
毋宁


相对而言


向着



沿
沿着

要不
要不然
要不是
要么
要是

也罢
也好

一般
一旦
一方面
一来
一切
一样
一则

依照


以便
以及
以免
以至
以至于
以致
抑或

因此
因而
因为



由此可见
由于

有的
有关
有些


于是
于是乎

与此同时
与否
与其
越是
云云

再说
再者

在下

咱们


怎么
怎么办
怎么样
怎样


照着


这边
这儿
这个
这会儿
这就是说
这里
这么
这么点儿
这么些
这么样
这时
这些
这样
正如


之类
之所以
之一
只是
只限
只要
只有

至于
诸位

着呢

自从
自个儿
自各儿
自己
自家
自身
综上所述
总的来看
总的来说
总的说来
总而言之
总之

纵令
纵然
纵使
遵照
作为







喔唷



这里使用哈工大的停用词列表。

首先加载停用词列表,然后进行过滤操作:

去除停用词

def drop_stopwords(contents,stopwords):

contents_clean = []  
all_words = []  
for line in contents:  
    line_clean = []  
    for word in line:  
        if word in stopwords:  
            continue  
        line_clean.append(word)  
        all_words.append(word)  
    contents_clean.append(line_clean)  
return contents_clean,all_words  

停用词加载

stopwords = pd.read_table('stop_words.txt',names = ['stopword'],quoting = 3)
contents = df_content.content_S.values.tolist()

contents_clean,all_words = drop_stopwords(contents,stopwords)


接着交给Gensim进行聚类操作:  

from gensim import corpora,models,similarities
import gensim

dictionary = corpora.Dictionary(contents_clean)
corpus = [dictionary.doc2bow(sentence) for sentence in contents_clean]
lda = gensim.models.ldamodel.LdaModel(corpus=corpus,id2word=dictionary,num_topics=2,random_state=3)

print(lda.print_topics(num_topics=2, num_words=4))

for e, values in enumerate(lda.inference(corpus)[0]):

print(content[e])  
for ee, value in enumerate(values):  
    print('\t分类%d推断值%.2f' % (ee, value))


这里使用LdaModel模型进行训练,分类设置(num\_topics)为2种,随机种子(random\_state)为3,在训练机器学习模型时,很多模型的训练过程都会涉及到随机数的生成,例如随机梯度下降法(SGD)就是一种随机梯度下降的优化算法。在训练过程中,如果不设置random\_state参数,则每次训练结果可能都不同。而设置random\_state参数后,每次训练结果都会相同,这就方便了我们在调参时对比模型的效果。如果想要让每次训练的结果都随机,可以将random\_state参数设置为None。

程序返回:  

[['乾坤', '挪移', '同步', '阻塞', 'sync', '三方', '库包', '转换', '异步', '阻塞', 'async', '模式', 'Python3.10', '实现'], ['Generator', '生成器', '入门', '初基', 'Coroutine', '原生', '协程', '登峰造极', 'Python3.10', '并发', '异步', '编程', 'async', '底层', '实现'], ['周而复始', '往复', '循环', '递归', '递归', '算法', '无限极', '层级', '结构', '探究', '使用', 'Golang1.18'], ['彩虹', '女神', '长空', 'Go', '语言', '进阶', 'Go', '语言', '高性能', 'Web', '框架', 'Iris', '项目', '实战', 'JWT', '中间件', 'Middleware', '使用', 'EP07']]
乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。

    分类0推断值0.57  
    分类1推断值14.43  

Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现

    分类0推断值0.58  
    分类1推断值15.42  

周而复始,往复循环,递归、尾递归算法与无限极层级结构的探究和使用(Golang1.18)

    分类0推断值12.38  
    分类1推断值0.62  

彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07

    分类0推断值19.19  
    分类1推断值0.81

可以看到,结果和ChatGPT聚类结果一致,前两篇为一种分类,后两篇为另外一种分类。  

随后可以将聚类结果保存为模型文件:  

lda.save('mymodel.model')


以后有新的文章发布,直接对新的文章进行分类推测即可:  

from gensim.models import ldamodel
import pandas as pd
import jieba
from gensim import corpora

doc0="巧如范金,精比琢玉,一分钟高效打造精美详实的Go语言技术简历(Golang1.18)"

加载模型

lda = ldamodel.LdaModel.load('mymodel.model')

content = [doc0]

分词

content_S = []
for line in content:

current_segment = [w for w in jieba.cut(line) if len(w)>1]  
if len(current_segment) > 1 and current_segment != '\r\t':  
    content_S.append(current_segment)  

分词结果转为DataFrame

df_content = pd.DataFrame({'content_S':content_S})

去除停用词

def drop_stopwords(contents,stopwords):

contents_clean = []  
all_words = []  
for line in contents:  
    line_clean = []  
    for word in line:  
        if word in stopwords:  
            continue  
        line_clean.append(word)  
        all_words.append(word)  
    contents_clean.append(line_clean)  
return contents_clean,all_words  

停用词加载

stopwords = pd.read_table('stop_words.txt',names = ['stopword'],quoting = 3)
contents = df_content.content_S.values.tolist()

contents_clean,all_words = drop_stopwords(contents,stopwords)

dictionary = corpora.Dictionary(contents_clean)

word = [w for w in jieba.cut(doc0)]

bow = dictionary.doc2bow(word)
print(lda.get_document_topics(bow))


程序返回:  

➜ nlp_chinese /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/nlp_chinese/new_text.py"
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/5x/gpftd0654bv7zvzyv39449rc0000gp/T/jieba.cache
Loading model cost 0.264 seconds.
Prefix dict has been built successfully.
[(0, 0.038379338), (1, 0.9616206)]


这里显示文章推断结果为分类2,也就是Golang类型的文章。  

完整调用逻辑:  

import jieba
import pandas as pd
import numpy as np
from gensim.models import ldamodel
from gensim import corpora,models,similarities
import gensim

class LdaRec:

def __init__(self,cotent:list) -> None:  
      
    self.content = content  
    self.contents_clean = []  
    self.lda = None  

def test_text(self,content:str):  

    self.lda = ldamodel.LdaModel.load('mymodel.model')  
    self.content = [content]  

    #分词  
    content_S = []  
    for line in self.content:  
        current_segment = [w for w in jieba.cut(line) if len(w)>1]  
        if len(current_segment) > 1 and current_segment != '\r\t':  
            content_S.append(current_segment)  
    #分词结果转为DataFrame  
    df_content = pd.DataFrame({'content_S':content_S})  

    contents = df_content.content_S.values.tolist()  

    dictionary = corpora.Dictionary(contents)  

    word = [w for w in jieba.cut(content)]  

    bow = dictionary.doc2bow(word)  
    print(self.lda.get_document_topics(bow))  


# 训练  
def train(self,num_topics=2,random_state=3):  

    dictionary = corpora.Dictionary(self.contents_clean)  
    corpus = [dictionary.doc2bow(sentence) for sentence in self.contents_clean]  
    self.lda = gensim.models.ldamodel.LdaModel(corpus=corpus,id2word=dictionary,num_topics=num_topics,random_state=random_state)  

    for e, values in enumerate(self.lda.inference(corpus)[0]):  
        print(self.content[e])  
        for ee, value in enumerate(values):  
            print('\t分类%d推断值%.2f' % (ee, value))  


# 过滤停用词  
def drop_stopwords(self,contents,stopwords):  
    contents_clean = []  
    for line in contents:  
        line_clean = []  
        for word in line:  
            if word in stopwords:  
                continue  
            line_clean.append(word)  
        contents_clean.append(line_clean)  
    return contents_clean  

def cut_word(self) -> list:  
    #分词  
    content_S = []  
    for line in self.content:  
        current_segment = [w for w in jieba.cut(line) if len(w)>1]  
        if len(current_segment) > 1 and current_segment != '\r\t':  
            content_S.append(current_segment)  

    #分词结果转为DataFrame  
    df_content = pd.DataFrame({'content_S':content_S})  

    # 停用词列表  
    stopwords = pd.read_table('stop_words.txt',names = ['stopword'],quoting = 3)  

    contents = df_content.content_S.values.tolist()  
    stopwords = stopwords.stopword.values.tolist()  

    self.contents_clean = self.drop_stopwords(contents,stopwords)  

if name == '__main__':

  
title1="乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。"  
title2="Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现"  
title3="周而复始,往复循环,递归、尾递归算法与无限极层级结构的探究和使用(Golang1.18)"  
title4="彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-JWT和中间件(Middleware)的使用EP07"  
content = [title1,title2, title3,title4]  

lr = LdaRec(content)  

lr.cut_word()  

lr.train()  

lr.lda.save('mymodel.model')  

lr.test_text("巧如范金,精比琢玉,一分钟高效打造精美详实的Go语言技术简历(Golang1.18)")

至此,基于聚类的推荐系统构建完毕,每一篇文章只需要通过既有分类模型进行训练,推断分类之后,给用户推送同一分类下的文章即可,截止本文发布,该分类模型已经在本站进行落地实践:  

![](https://v3u.cn/v3u/Public/js/editor/attached/20230109140153_99420.webp)  

结语
--
相关文章
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
134 5
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
6天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
蘑菇识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了9种常见的蘑菇种类数据集【"香菇(Agaricus)", "毒鹅膏菌(Amanita)", "牛肝菌(Boletus)", "网状菌(Cortinarius)", "毒镰孢(Entoloma)", "湿孢菌(Hygrocybe)", "乳菇(Lactarius)", "红菇(Russula)", "松茸(Suillus)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,
48 11
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
|
3天前
|
算法
基于电导增量MPPT控制算法的光伏发电系统simulink建模与仿真
本课题基于电导增量MPPT控制算法,使用MATLAB2022a的Simulink进行光伏发电系统的建模与仿真,输出系统电流、电压及功率。电导增量调制(IC)算法通过检测电压和电流变化率,实时调整光伏阵列工作点,确保其在不同光照和温度条件下始终处于最大功率输出状态。仿真结果展示了该算法的有效性,并结合PWM技术调节逆变流器占空比,提高系统效率和稳定性。
|
1天前
|
存储 监控 算法
员工屏幕监控系统之 C++ 图像差分算法
在现代企业管理中,员工屏幕监控系统至关重要。本文探讨了其中常用的图像差分算法,该算法通过比较相邻两帧图像的像素差异,检测屏幕内容变化,如应用程序切换等。文中提供了C++实现代码,并介绍了其在实时监控、异常行为检测和数据压缩等方面的应用,展示了其实现简单、效率高的特点。
27 15
|
22天前
|
人工智能 开发者 Python
Chainlit:一个开源的异步Python框架,快速构建生产级对话式 AI 应用
Chainlit 是一个开源的异步 Python 框架,帮助开发者在几分钟内构建可扩展的对话式 AI 或代理应用,支持多种工具和服务集成。
136 9
|
26天前
|
存储 监控 算法
内网监控系统之 Go 语言布隆过滤器算法深度剖析
在数字化时代,内网监控系统对企业和组织的信息安全至关重要。布隆过滤器(Bloom Filter)作为一种高效的数据结构,能够快速判断元素是否存在于集合中,适用于内网监控中的恶意IP和违规域名筛选。本文介绍其原理、优势及Go语言实现,提升系统性能与响应速度,保障信息安全。
28 5
|
1月前
|
Shell 程序员 开发者
轻松搞定在Python中构建虚拟环境
本教程教你如何使用业界公认的最佳实践,创建一个完全工作的Python开发环境。虚拟环境通过隔离依赖项,避免项目间的冲突,并允许你轻松管理包版本。我们将使用Python 3的内置`venv`模块来创建和激活虚拟环境,确保不同项目能独立运行,不会相互干扰。此外,还将介绍如何检查Python版本、激活和停用虚拟环境,以及使用`requirements.txt`文件共享依赖项。 通过本教程,你将学会: - 创建和管理虚拟环境 - 避免依赖性冲突 - 部署Python应用到服务器 适合新手和希望提升开发环境管理能力的开发者。
107 2
|
1月前
|
算法
基于爬山法MPPT最大功率跟踪算法的光伏发电系统simulink建模与仿真
本课题基于爬山法MPPT算法,对光伏发电系统进行Simulink建模与仿真。使用MATLAB2022a版本,通过调整光伏电池的工作状态以实现最大功率输出。爬山法通过逐步优化工作点,确保光伏系统在不同条件下均能接近最大功率点。仿真结果显示该方法的有效性,验证了模型的正确性和可行性。
|
6月前
|
前端开发 JavaScript 关系型数据库
基于Python+Vue开发的电影订票管理系统
该项目是基于Python+Vue开发的电影订票管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Python的电影订票管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
43 1
|
6月前
|
数据采集 数据可视化 关系型数据库
【优秀python web设计】基于Python flask的猫眼电影可视化系统,可视化用echart,前端Layui,数据库用MySQL,包括爬虫
本文介绍了一个基于Python Flask框架、MySQL数据库和Layui前端框架的猫眼电影数据采集分析与可视化系统,该系统通过爬虫技术采集电影数据,利用数据分析库进行处理,并使用Echart进行数据的可视化展示,以提供全面、准确的电影市场分析结果。
190 4

热门文章

最新文章

推荐镜像

更多