当前位置:   article > 正文

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

python 文本 lda 分析 gensim

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

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

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

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

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

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

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

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

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

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

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

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

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

Python3.10实现

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

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

pip3 install jieba  
pip3 install gensim
  • 1
  • 2

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

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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

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

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

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

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

———  
》),  
)÷(1-  
”,  
)、  
=(  
:  
→  
℃   
&  
*  
一一  
~~~~  
’  
.   
『  
.一  
./  
--   
』  
=″  
【  
[*]  
}>  
[⑤]]  
[①D]  
c]  
ng昉  
*  
//  
[  
]  
[②e]  
[②g]  
={  
}  
,也   
‘  
A  
[①⑥]  
[②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  
㈧   
[-  
......  
〉  
[③⑩]  
第二  
一番  
一直  
一个  
一些  
许多  
种  
有的是  
也就是说  
末##末  
啊  
阿  
哎  
哎呀  
哎哟  
唉  
俺  
俺们  
按  
按照  
吧  
吧哒  
把  
罢了  
被  
本  
本着  
比  
比方  
比如  
鄙人  
彼  
彼此  
边  
别  
别的  
别说  
并  
并且  
不比  
不成  
不单  
不但  
不独  
不管  
不光  
不过  
不仅  
不拘  
不论  
不怕  
不然  
不如  
不特  
不惟  
不问  
不只  
朝  
朝着  
趁  
趁着  
乘  
冲  
除  
除此之外  
除非  
除了  
此  
此间  
此外  
从  
从而  
打  
待  
但  
但是  
当  
当着  
到  
得  
的  
的话  
等  
等等  
地  
第  
叮咚  
对  
对于  
多  
多少  
而  
而况  
而且  
而是  
而外  
而言  
而已  
尔后  
反过来  
反过来说  
反之  
非但  
非徒  
否则  
嘎  
嘎登  
该  
赶  
个  
各  
各个  
各位  
各种  
各自  
给  
根据  
跟  
故  
故此  
固然  
关于  
管  
归  
果然  
果真  
过  
哈  
哈哈  
呵  
和  
何  
何处  
何况  
何时  
嘿  
哼  
哼唷  
呼哧  
乎  
哗  
还是  
还有  
换句话说  
换言之  
或  
或是  
或者  
极了  
及  
及其  
及至  
即  
即便  
即或  
即令  
即若  
即使  
几  
几时  
己  
既  
既然  
既是  
继而  
加之  
假如  
假若  
假使  
鉴于  
将  
较  
较之  
叫  
接着  
结果  
借  
紧接着  
进而  
尽  
尽管  
经  
经过  
就  
就是  
就是说  
据  
具体地说  
具体说来  
开始  
开外  
靠  
咳  
可  
可见  
可是  
可以  
况且  
啦  
来  
来着  
离  
例如  
哩  
连  
连同  
两者  
了  
临  
另  
另外  
另一方面  
论  
嘛  
吗  
慢说  
漫说  
冒  
么  
每  
每当  
们  
莫若  
某  
某个  
某些  
拿  
哪  
哪边  
哪儿  
哪个  
哪里  
哪年  
哪怕  
哪天  
哪些  
哪样  
那  
那边  
那儿  
那个  
那会儿  
那里  
那么  
那么些  
那么样  
那时  
那些  
那样  
乃  
乃至  
呢  
能  
你  
你们  
您  
宁  
宁可  
宁肯  
宁愿  
哦  
呕  
啪达  
旁人  
呸  
凭  
凭借  
其  
其次  
其二  
其他  
其它  
其一  
其余  
其中  
起  
起见  
起见  
岂但  
恰恰相反  
前后  
前者  
且  
然而  
然后  
然则  
让  
人家  
任  
任何  
任凭  
如  
如此  
如果  
如何  
如其  
如若  
如上所述  
若  
若非  
若是  
啥  
上下  
尚且  
设若  
设使  
甚而  
甚么  
甚至  
省得  
时候  
什么  
什么样  
使得  
是  
是的  
首先  
谁  
谁知  
顺  
顺着  
似的  
虽  
虽然  
虽说  
虽则  
随  
随着  
所  
所以  
他  
他们  
他人  
它  
它们  
她  
她们  
倘  
倘或  
倘然  
倘若  
倘使  
腾  
替  
通过  
同  
同时  
哇  
万一  
往  
望  
为  
为何  
为了  
为什么  
为着  
喂  
嗡嗡  
我  
我们  
呜  
呜呼  
乌乎  
无论  
无宁  
毋宁  
嘻  
吓  
相对而言  
像  
向  
向着  
嘘  
呀  
焉  
沿  
沿着  
要  
要不  
要不然  
要不是  
要么  
要是  
也  
也罢  
也好  
一  
一般  
一旦  
一方面  
一来  
一切  
一样  
一则  
依  
依照  
矣  
以  
以便  
以及  
以免  
以至  
以至于  
以致  
抑或  
因  
因此  
因而  
因为  
哟  
用  
由  
由此可见  
由于  
有  
有的  
有关  
有些  
又  
于  
于是  
于是乎  
与  
与此同时  
与否  
与其  
越是  
云云  
哉  
再说  
再者  
在  
在下  
咱  
咱们  
则  
怎  
怎么  
怎么办  
怎么样  
怎样  
咋  
照  
照着  
者  
这  
这边  
这儿  
这个  
这会儿  
这就是说  
这里  
这么  
这么点儿  
这么些  
这么样  
这时  
这些  
这样  
正如  
吱  
之  
之类  
之所以  
之一  
只是  
只限  
只要  
只有  
至  
至于  
诸位  
着  
着呢  
自  
自从  
自个儿  
自各儿  
自己  
自家  
自身  
综上所述  
总的来看  
总的来说  
总的说来  
总而言之  
总之  
纵  
纵令  
纵然  
纵使  
遵照  
作为  
兮  
呃  
呗  
咚  
咦  
喏  
啐  
喔唷  
嗬  
嗯  
嗳
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662
  • 663
  • 664
  • 665
  • 666
  • 667
  • 668
  • 669
  • 670
  • 671
  • 672
  • 673
  • 674
  • 675
  • 676
  • 677
  • 678
  • 679
  • 680
  • 681
  • 682
  • 683
  • 684
  • 685
  • 686
  • 687
  • 688
  • 689
  • 690
  • 691
  • 692
  • 693
  • 694
  • 695
  • 696
  • 697
  • 698
  • 699
  • 700
  • 701
  • 702
  • 703
  • 704
  • 705
  • 706
  • 707
  • 708
  • 709
  • 710
  • 711
  • 712
  • 713
  • 714
  • 715
  • 716
  • 717
  • 718
  • 719
  • 720
  • 721
  • 722
  • 723
  • 724
  • 725
  • 726
  • 727
  • 728
  • 729
  • 730
  • 731
  • 732
  • 733
  • 734
  • 735
  • 736
  • 737
  • 738
  • 739
  • 740
  • 741
  • 742
  • 743
  • 744
  • 745
  • 746
  • 747
  • 748
  • 749
  • 750
  • 751
  • 752
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
  • 766
  • 767

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

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

#去除停用词  
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

接着交给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))


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这里使用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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

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

lda.save('mymodel.model')
  • 1

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

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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

程序返回:

➜  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)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里显示文章推断结果为分类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)")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

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

结语

金无足赤,LDA聚类算法也不是万能的,LDA聚类算法有许多超参数,包括主题个数、学习率、迭代次数等,这些参数的设置对结果有很大影响,但是很难确定最优参数,同时聚类算法的时间复杂度是O(n^2)级别的,在处理大规模文本数据时,计算速度较慢,反之,在样本数据较少的情况下,模型的泛化能力较差。最后,奉上项目地址,与君共觞:https://github.com/zcxey2911/Lda-Gensim-Recommended-System-Python310

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/289978
推荐阅读
相关标签
  

闽ICP备14008679号