美文网首页Machine Learning & Recommendation & NLP & DL大数据 爬虫Python AI Sql
网易云音乐上的所有!全部!随便爬!(Python爬虫&基

网易云音乐上的所有!全部!随便爬!(Python爬虫&基

作者: 伪文艺boy | 来源:发表于2019-01-31 13:49 被阅读5次

    接上篇

    六、相似用户推荐(Python之Gensim版本)

    6.1 Gensim

    用Python做过文本挖掘的想必知道Gensim,首先我们看维基百科对gensim的解释:

    Gensim is a robust open-source vector space modeling and topic modeling toolkit implemented in Python. It uses NumPy, SciPy and optionally Cython for performance. Gensim is specifically designed to handle large text collections, using data streaming and efficient incremental algorithms, which differentiates it from most other scientific software packages that only target batch and in-memory processing.

    Gensim includes implementations of tf-idf, random projections, word2vec and document2vec algorithms,hierarchical Dirichlet processes (HDP), latent semantic analysis (LSA, LSI, SVD) and latent Dirichlet allocation (LDA), including distributedparallel versions.

    也就是说,gensim是一个python的函数包,gensim包含了TF-IDF、随机投影、word2vec和document2vec算法的实现,分层Dirchlet过程(HDP),潜在语义分析(LSA)和潜在Dirichlet分配即主题模型(LDA),包括分布式并行版本。主要是用来主题建模、文档索引以及使用大规模语料数据的相似性检索,是文本挖掘在NLP领域里处理相当有效、得力的一个函数包。

    6.2 数据预处理

    说明:为了更广泛地使大家熟悉多种语言,接下来我用R语言来处理。

    首先,以之前我们爬到的陈百强大哥的经典歌曲《偏偏喜欢你》的1024页的评论文本信息为例展开说明,R语言连接Mongodb数据库

    library(jsonlite)
    library(mongolite)
    library("openssl")
    con <- mongo(collection = "陈百强",db = "comments", url = "mongodb://localhost")
    mydata <- con$find()
    dim(mydata)
    

    得到了1025个文档,2列,第一是id,弃,第二列是comments,留。

    1025    2
    

    我们查看它的第二列即评论:

    lengths(mydata['comments'][3,])
    

    没错,一条评论信息下面有16个字段,但是R语言对这种json格式的数据处理不是很成熟,目前有rjson包,但是存在bug,其替代品RJSONIO也没有那么完善。这一阶段的数据处理我们改用Python。(这是我花费了一下午时间后的结论。多么痛的领悟。。。)

    import pymongo
    import pandas as pd
    import numpy as np
    client = pymongo.MongoClient(host='localhost', port=27017)
    db = client['comments']
    collection = db['陈百强']
    # 将数据库数据转为dataFrame
    data = pd.DataFrame(list(collection.find()))
    num=data['comments']
    result=pd.DataFrame(num.iloc[0])
    for i in range(1,1025):
        data2=pd.DataFrame(num.iloc[i])
        result=pd.concat([result,data2],ignore_index=True)
    

    查看其维度:

    print(result.shape)
    

    故有《偏偏喜欢你》下面有20500条评论,每条评论有16个字段。

    (20500, 16)
    

    我们选我们想要的文本字段和user字段下面的userID。

    text.rename(columns={'w':'userID', 'x':'context'}, inplace = True)
    text['context']=result['content']
    for i in range(0,20500):
        text.iloc[i,0]=result['user'].iloc[i]['userId']
    

    得到20500行2列的数据:

    userID                                            context
    0       328901978                                            都是有故事的人
    1      1724358802                                       每天都要听至爱Danny
    2       451250610                                 对呀,你就从来没喜欢过我。一点都煤油
    3       554348857                                            沁入心脾的温柔
    4      1296389446                                           最近好喜欢这首歌
    5       303721726                                             今日点歌③.
    6      1654009353                                          偏偏对你没有抵抗力
    7      1654009353  那一次我们擦肩而过,我害怕我们会像电影里的情景一样错过,所以我没有走,我一直看着你走,可是你...
    8       357343565                                “我喜欢你”珍贵,奈何听的人不珍惜……
    9       293896875                                         偏偏喜欢你  王雷雷
    10     1510414811                                         对啊,这是为什么呢。
    11     1574359988                                              对,好浪漫
    12     1333924430                            小时候有个小的收音机,好开心,睡觉都舍不得放下
    13       64188725                                                 好听
    14      482121141                                     这些歌曲都是经典作品[亲亲]
    15      427963594                                      偏偏喜欢你,我的翩翩夫人。
    16     1382017788                                  以爱情  以时光\n\n纪贯新~❤
    17       46656982  我和他来一家店吃饭,店里在放这首歌,他问我,你知道这首歌是什么吗?我听了一下说不知道,他说:...
    18      425557078                   幸福到疼……\r\r有一个人曾让我知道\r寄生于世原来是那么的好
    19      568096298                             超级喜欢的一首歌,偏偏喜欢你【大赞】[爱心]
    20      412381224                                         他可能会单手开法拉利
    21      301593622                            [多多大笑][多多大笑][多多大笑]笑着活下去
    22     1455906926                                             再见吧大渣男
    23     1670031755                                       [憨笑]我比你还俗 更穷
    24      301593622                                 现在一心只想搞钱,我比较俗,太穷了!
    25     1730181168                                         哈哈哈哈这个年代感哦
    26      279684331                                        偏偏喜欢的就是得不到!
    27      621542625                                               阿Lan
    28     1328014893                             曾经他为我唱过的歌,到如今听到都心里隐隐作痛
    29       51335946                                     爱,直至成伤;之后,就是永远
    ...           ...                                                ...
    20470    62338668                                               nice
    20471    62338668  愛上你永遠沒有結果 很好 我現在要放棄了 努力忘記你 不想讓自己為了一個沒結果的人那麼難受 ...
    20472    68320201  忽然想起和一个朋友的对话,她因为家庭原因极度缺乏安全感。\n我怕…\n你怕什么?\n怕他喜欢...
    20473   246752393                                                張國榮
    20474   134205876        还记得那时地方电视台点播的一些曲子吗?重点中间无广告,那才是乐趣。某某点歌给谁谁谁……
    20475   122104993  班固 《西都赋》“愿宾摅怀旧之蓄念,发思古之幽情。” 元稹 《赠吴渠州从姨兄士则》诗“泪因生...
    20476   100442347                中午广播无意听到这首歌,然后特意关注了聊大广播台微博找到歌单![大哭]
    20477   118207115                                               别咒王杰
    20478   116595775                      我爸只会唱一首歌,就这首歌把我妈娶到手了。[憨笑][憨笑]
    20479    60109810                                    2000年生却偏偏喜欢80年代
    20480    63357164                                    情爱 是什么 只有呵呵[大哭]
    20481    62338668                                               [可爱]
    20482    95087236                                         对啊,为何偏偏喜欢你
    20483    68320201                                               [大笑]
    20484    79282042                                       [皱眉][皱眉][皱眉]
    20485    83512955                             听过这首歌的人都是有故事的男人和女人[跳舞]
    20486    67061365    上班特别累的时候听到香港的经典感觉整个世界都属于我,要是来一杯纯正的香港奶茶就更好了。[大笑]
    20487    71401843                                     当年的录像厅前面就放的这首歌
    20488   103882075                                           他还没死[大哭]
    20489    62338668                                               我01的
    20490    62338668                                               nice
    20491    62338668  愛上你永遠沒有結果 很好 我現在要放棄了 努力忘記你 不想讓自己為了一個沒結果的人那麼難受 ...
    20492    68320201  忽然想起和一个朋友的对话,她因为家庭原因极度缺乏安全感。\n我怕…\n你怕什么?\n怕他喜欢...
    20493   246752393                                                張國榮
    20494   134205876        还记得那时地方电视台点播的一些曲子吗?重点中间无广告,那才是乐趣。某某点歌给谁谁谁……
    20495   122104993  班固 《西都赋》“愿宾摅怀旧之蓄念,发思古之幽情。” 元稹 《赠吴渠州从姨兄士则》诗“泪因生...
    20496   100442347                中午广播无意听到这首歌,然后特意关注了聊大广播台微博找到歌单![大哭]
    20497   118207115                                               别咒王杰
    20498   116595775                      我爸只会唱一首歌,就这首歌把我妈娶到手了。[憨笑][憨笑]
    20499    60109810                                    2000年生却偏偏喜欢80年代
    
    [20500 rows x 2 columns]
    

    将userID一列保存为列名,重命名行名、列名,并保存数据到文件“DealtedData.csv”中

    names=pd.DataFrame(data.iloc[:,0])
    data.rename(index=names.iloc[:,0],columns={2:'context'}, inplace = True)
    data.to_csv(r'DealtedData.csv',encoding='gbk',index=True,header=True)
    

    6.3 文本预处理

    导入数据:

    import os
    os.chdir('G:\\项目\\网易云音乐评论\\文本挖掘')  # 打印当前工作目录
    import pandas as pd
    data = pd.read_csv(r"DealtedData.csv",encoding='gbk', sep=',',index_col=0,header=0)
    data.head
    

    数据格式为下:

    <bound method NDFrame.head of                                                        context
    328901978                                              都是有故事的人
    1724358802                                        每天都要听至爱Danny
    451250610                                   对呀,你就从来没喜欢过我。一点都煤油
    554348857                                              沁入心脾的温柔
    1296389446                                            最近好喜欢这首歌
    303721726                                               今日点歌③.
    1654009353                                           偏偏对你没有抵抗力
    1654009353   那一次我们擦肩而过,我害怕我们会像电影里的情景一样错过,所以我没有走,我一直看着你走,可是你...
    357343565                                  “我喜欢你”珍贵,奈何听的人不珍惜……
    293896875                                           偏偏喜欢你  王雷雷
    1510414811                                          对啊,这是为什么呢。
    1574359988                                               对,好浪漫
    1333924430                             小时候有个小的收音机,好开心,睡觉都舍不得放下
    64188725                                                    好听
    482121141                                       这些歌曲都是经典作品[亲亲]
    427963594                                        偏偏喜欢你,我的翩翩夫人。
    1382017788                           以爱情  以时光\r\r\n\r\r\n纪贯新~?
    46656982     我和他来一家店吃饭,店里在放这首歌,他问我,你知道这首歌是什么吗?我听了一下说不知道,他说:...
    425557078                                               幸福到疼……
    有一个人曾让我知道                                                  NaN
    寄生于世原来是那么的好                                                NaN
    568096298                               超级喜欢的一首歌,偏偏喜欢你【大赞】[爱心]
    412381224                                           他可能会单手开法拉利
    301593622                              [多多大笑][多多大笑][多多大笑]笑着活下去
    1455906926                                              再见吧大渣男
    1670031755                                        [憨笑]我比你还俗 更穷
    301593622                                   现在一心只想搞钱,我比较俗,太穷了!
    1730181168                                          哈哈哈哈这个年代感哦
    279684331                                          偏偏喜欢的就是得不到!
    621542625                                                 阿Lan
    ...                                                        ...
    62338668                                                  nice
    62338668     愛上你永遠沒有結果 很好 我現在要放棄了 努力忘記你 不想讓自己為了一個沒結果的人那麼難受 ...
    68320201     忽然想起和一个朋友的对话,她因为家庭原因极度缺乏安全感。\r\r\n我怕…\r\r\n你怕什...
    246752393                                                  張國榮
    134205876          还记得那时地方电视台点播的一些曲子吗?重点中间无广告,那才是乐趣。某某点歌给谁谁谁……
    122104993    班固?《西都赋》“愿宾摅怀旧之蓄念,发思古之幽情。” 元稹?《赠吴渠州从姨兄士则》诗“泪因生...
    100442347                  中午广播无意听到这首歌,然后特意关注了聊大广播台微博找到歌单![大哭]
    118207115                                                 别咒王杰
    116595775                        我爸只会唱一首歌,就这首歌把我妈娶到手了。[憨笑][憨笑]
    60109810                                       2000年生却偏偏喜欢80年代
    63357164                                       情爱 是什么 只有呵呵[大哭]
    62338668                                                  [可爱]
    95087236                                            对啊,为何偏偏喜欢你
    68320201                                                  [大笑]
    79282042                                          [皱眉][皱眉][皱眉]
    83512955                                听过这首歌的人都是有故事的男人和女人[跳舞]
    67061365       上班特别累的时候听到香港的经典感觉整个世界都属于我,要是来一杯纯正的香港奶茶就更好了。[大笑]
    71401843                                        当年的录像厅前面就放的这首歌
    103882075                                             他还没死[大哭]
    62338668                                                  我01的
    62338668                                                  nice
    62338668     愛上你永遠沒有結果 很好 我現在要放棄了 努力忘記你 不想讓自己為了一個沒結果的人那麼難受 ...
    68320201     忽然想起和一个朋友的对话,她因为家庭原因极度缺乏安全感。\r\r\n我怕…\r\r\n你怕什...
    246752393                                                  張國榮
    134205876          还记得那时地方电视台点播的一些曲子吗?重点中间无广告,那才是乐趣。某某点歌给谁谁谁……
    122104993    班固?《西都赋》“愿宾摅怀旧之蓄念,发思古之幽情。” 元稹?《赠吴渠州从姨兄士则》诗“泪因生...
    100442347                  中午广播无意听到这首歌,然后特意关注了聊大广播台微博找到歌单![大哭]
    118207115                                                 别咒王杰
    116595775                        我爸只会唱一首歌,就这首歌把我妈娶到手了。[憨笑][憨笑]
    60109810                                       2000年生却偏偏喜欢80年代
    
    [20523 rows x 1 columns]>
    

    isnull检测是否含有NaN值,有就返回True。np.any()检测df数据中是否含有等于Ture的值

    import numpy as np
    print(np.any(data.isnull())== True)  
    False
    

    显示为TRUE,说明评论里有NAN值,用空str填充:

    data=data.fillna(' ')   
    

    设置训练集和测试集合

    from gensim import corpora, models, similarities
    import jieba
    # 文本集和搜索词
    trains = list(data['context'].iloc[0:20523])
    tests= '喜欢你'
    

    6.4 对训练集进行分词

    trains = [jieba.lcut(text) for text in trains]
    trains
    

    可以得到list形式的分词表:

    [['都', '是', '有', '故事', '的', '人'],
     ['每天', '都', '要', '听', '至爱', 'Danny'],
     ['对', '呀', ',', '你', '就', '从来', '没', '喜欢', '过', '我', '。', '一点', '都', '煤油'],
     ['沁入', '心脾', '的', '温柔'],
     ['最近', '好', '喜欢', '这', '首歌'],
     ['今日', '点歌', '③', '.'],
     ['偏偏', '对', '你', '没有', '抵抗力'],..
    

    6.5 提取词典特征数

    dictionary = corpora.Dictionary(trains)
    feature_cnt = len(dictionary.token2id)
    

    查看字典里面的词语:

    print(tfidf_vec.vocabulary_)
    

    可见有在《偏偏喜欢你》的评论文本里一个有13651个词语。
    即词典特征数为13651,feature_cnt的值。

    Dictionary(13651 unique tokens: ['人', '故事', '是', '有', '的']...)
    

    6.6 构建语料库

    corpus = [dictionary.doc2bow(text) for text in trains]
    corpus
    

    我们得到的语料库形式为下,其中第一行评论['都', '是', '有', '故事', '的', '人']转化为了稀疏向量[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]。当我们使用doc2bow函数时,每一个词语会对应一个id,如:‘都’对应0,'是'对应1,'有'对应2,'故事'对应3,'的'对应4,'人'对应5, 后面的1代表在本句评论中,‘都’出现了一次,‘是’一次,‘有’一次,‘故事一次’......

    [[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)],
     [(5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1)],
     [(5, 1),
      (11, 1),
      (12, 1),
      (13, 1),
      (14, 1),
      (15, 1),
      (16, 1),
      (17, 1),
      (18, 1),
      (19, 1),
      (20, 1),
      (21, 1),
      (22, 1),
      (23, 1)],
     [(4, 1), (24, 1), (25, 1), (26, 1)],
     [(16, 1), (27, 1), (28, 1), (29, 1), (30, 1)],...
    

    6.7 使用TF-IDF模型处理语料库

    tfidf = models.TfidfModel(corpus)
    for i in tfidf[corpus]:
        print(i)
    

    可以得到训练文本的TF-IDF值,以稀疏向量的形式保存:

    [(0, 0.32184672062922548), (1, 0.73766014971005966), (2, 0.29497170498614139), (3, 0.29304380441485145), (4, 0.13870813169109303), (5, 0.40018654163321249)]
    [(5, 0.19879141119607197), (6, 0.43291398548320181), (7, 0.1986860979407834), (8, 0.45262734719390507), (9, 0.68525962106956162), (10, 0.24318516977110011)]
    [(5, 0.16060211474573619), (11, 0.098574217529621325), (12, 0.36067639144364333), (13, 0.42534037149410231), (14, 0.063581328755947963), (15, 0.20711773583505186), (16, 0.074812488712874464), (17, 0.248665060688224), (18, 0.16081534912048612), (19, 0.077507465039391904), (20, 0.27324683263788124), (21, 0.59516351798480016), (22, 0.27437250176801881), (23, 0.055533166748108702)]
    [(4, 0.060614261626705232), (24, 0.64806776302591229), (25, 0.64806776302591229), (26, 0.39540139142475095)]
    [(16, 0.1603400740935198), (27, 0.3795919475458821), (28, 0.78372267212523294), (29, 0.31693482880130575), (30, 0.33990013458011531)]
    [(31, 0.22648623811135946), (32, 0.63332275807290517), (33, 0.50068929396716033), (34, 0.54490044866907528)]
    

    6.8 将测试集转换为稀疏向量

    kw_vector = dictionary.doc2bow(jieba.lcut(tests))
    print(tfidf[kw_vector])
    

    可以得到测试文本的TF-IDF值,以稀疏向量的形式保存:

    [(14, 0.64759350572190955), (16, 0.76198599156861602)]
    

    6.9 相似度计算

    index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=feature_cnt)
    similarity = index[tfidf[kw_vector]]
    for i in range(len(similarity)):
        print('tests 与 trains%d 相似度为:%.2f' % (i + 1, similarity[i]))
    

    得到相似度为下:

    tests 与 trains1 相似度为:0.00
    tests 与 trains2 相似度为:0.00
    tests 与 trains3 相似度为:0.10
    tests 与 trains4 相似度为:0.00
    tests 与 trains5 相似度为:0.12
    tests 与 trains6 相似度为:0.00
    tests 与 trains7 相似度为:0.06
    tests 与 trains8 相似度为:0.04
    tests 与 trains9 相似度为:0.09
    tests 与 trains10 相似度为:0.15
    tests 与 trains11 相似度为:0.00
    tests 与 trains12 相似度为:0.00
    tests 与 trains13 相似度为:0.00
    tests 与 trains14 相似度为:0.00
    tests 与 trains15 相似度为:0.00
    tests 与 trains16 相似度为:0.14
    tests 与 trains17 相似度为:0.00
    tests 与 trains18 相似度为:0.09
    tests 与 trains19 相似度为:0.00
    tests 与 trains20 相似度为:0.00
    

    将相似度保存到文件“sim.csv”中

    similarity = list(sim)
    sim_file = open("sim.csv",'w')
    for i in similarity:
        sim_file.write(str(i)+'\n')
    sim_file.close()
    print(similarity)
    

    将相似度转化为数据框,并降序排列:

    similarity=pd.DataFrame(similarity)
    similarity.iloc[np.argsort(-similarity.iloc[:,0]),:]
    

    得到相似度最高的前18个:

        0
    4536    1.000000
    1803    0.784898
    6485    0.784898
    6134    0.784898
    398     0.784898
    1614    0.784898
    8376    0.784898
    3948    0.784898
    1362    0.761986
    9629    0.761986
    5481    0.761986
    324     0.761986
    1632    0.761986
    6405    0.761986
    5091    0.761986
    986     0.642364
    9395    0.617391
    3679    0.600096
    

    查看相似度为1的评论:

    data['context'].iloc[4536]
    

    得到评论信息为:

    '喜欢你'
    

    同样,取得相似度为第2的评论信息:

    '我喜欢你'
    

    因此,我们得到与用户ID为76654704最相似的用户ID为380345546。

    七、相似用户推荐(Python之sklearn版本)

    7.1 sklearn

    Scikit-learn (formerly scikits.learn) is a free software machine learning library for the Python programming language.It features various classification, regression and clustering algorithms including support vector machines, random forests, gradient boosting, k-means and DBSCAN, and is designed to interoperate with the Python numerical and scientific libraries NumPy and SciPy.

    7.2 文本预处理

    导入之前处理过好的数据:

    import os
    os.chdir('G:\\项目\\网易云音乐评论\\文本挖掘')  
    import pandas as pd
    data = pd.read_csv(r"DealtedData.csv",encoding='gbk', sep=',',index_col=0,header=0)
    

    分词:

    import jieba
    def chinese_word_cut(mytext):
        return " ".join(jieba.cut(mytext))
    d=pd.DataFrame(data['context'].astype(str))
    d["title_cutted"] = d['context'].apply(chinese_word_cut)
    d.title_cutted.head()
    

    可得分析结果为:

    328901978                        都 是 有 故事 的 人
    1724358802                  每天 都 要 听 至爱 Danny
    451250610     对 呀 , 你 就 从来 没 喜欢 过 我 。 一点 都 煤油
    554348857                          沁入 心脾 的 温柔
    1296389446                       最近 好 喜欢 这 首歌
    Name: title_cutted, dtype: object
    

    接下来我们对这些本文做向量化,所谓文本向量化,指的就是形成一个28197(文档个数)*n(文本中所有词的数量)的0-1矩阵,特定词在这个文档出现记为1,否则为0。若选取所有词的话,这必然是一个很大的矩阵,因此在之前的操作中,本文从所有的词中选取了1000关键词。

    from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
    vectorizer = CountVectorizer()
    count = vectorizer.fit_transform(d.title_cutted)
    print(vectorizer.get_feature_names())  
    

    查看所有文本的关键字

    [...'不是', '不是故意', '不曾', '不會', '不會來', '不服', '不服输', '不期而遇', '不来', '不染', '不欠', '不欢', '不欢而散', '不止', '不正', '不死', '不死心', '不求', '不浮', '不溜提', '不满', '不潮', '不点', '不烦', '不然', '不燥', '不爱', '不理', '不甘', '不甘示弱', '不生', '不用', '不用谢', '不由得', '不由自主', '不留', '不疼', '不痛', '不相误', '不看', '不眠', '不知', '不知不觉', '不知好歹', '不知情', '不知所措', '不知所谓', '不禁', '不离', '不算', '不算什么', '不管', '不管怎样', '不纯', '不经意', '不绕', '不羁', '不老', '不耐烦', '不肯', '不胜枚举', '不能', '不能不', '不能不要', '不能治愈', '不能自已', '不能自拔', '不腻', '不至于', '不舍', '不苦', '不蓝', '不行', '不衰', '不要', '不要脸', '不见', '不論', '不计', '不让', '不记', '不讲道理', '不许', '不论', '不论什么', '不识抬举', '不识曲', '不该', '不说', '不谢', '不负', '不败', '不起', '不足', '不躁', '不输给', '不辞而别', '不过', '不远', '不远千里', '不适', '不通', '不配', '不错', '不长', '不问', '不间断', '不需', '不靠', '不须', '不顾', '不高', '与其', '与其说是', '与否', '与子偕老', '与我无关', '与生俱来', '丑小鸭', '专一', '专业', '专业课', '专场', '专注', '专用', '专辑', '专门', '世上', '世事', '世人', '世俗', '世情', '世無雙', '世界', '世界杯', '世界观', '世纪', '世荣', '世间', '业生', '东京', '东北', '东南亚', '东方', '东方人', '东方文化', '东流', '东渡', '东皇钟', '东西', '东邪西毒', '东风破', '丝滑', '丢失', '丢掉', '丢脸', '两三次', '两个', '两人', '两人同', '两件', '两伙', '两位', '两位数', '两分钟', '两千块', '两千多', '两口', '两句', '两只', '两周', '两场', '两块钱', '两天', '两岁半', '两年', '两情相悦', '两月', '两条', '两栋', '两次', '两段', '两点', '两百天', '两百斤', '两盒', '两码事', '两种', '两秒', '两级', '两行', '两遍', '两集', '两面', '两首', '两首歌', '严厉', '严肃', '严谨', '严重', '丧失', '个个', '个人', '个人感觉', '个人观点', '个别', '个头', '个子', '个币', '个性', '个赞', '丫头', '丫点', '中会', '中医', '中午', '中华', '中华文化', '中华民谣', '中国', '中国香港', '中央', '中央空调', '中学', '中学毕业', '中层', '中山', '中岛美雪', '中带', '中广核', '中庙', '中式', '中心', '中意', '中文', '中文系', '中曲', '中有', '中泪点', '中环', '中秋', '中秋节', '中老年人', '中考', '中过', '中途', '中间', '中高音', '丰城', '临窗', '临近', '丹丹', '丹妮', '丹尼', '为了', '为什么', '为何', '为先', '为君', '为啥', '为国争光', '为数不多', '为止', '为此', '为活', '为琦琦', '为罗琦琦', '为萝莉', '为难', '主任', '主动', '主叫', '主唱', '主持人', '主时', '主流'...]
    

    查看所有文本的关键字和其位置

    print(vectorizer.vocabulary_)
    {...'故事': 6694, '每天': 7759, '至爱': 10103, 'danny': 252, '从来': 1885, '喜欢': 3777, '一点': 803, '煤油': 8436, '沁入': 7880, '心脾': 5636, '温柔': 8233, '最近': 7194, '首歌': 11920, '今日': 1863, '点歌': 8383, '偏偏': 2226, '没有': 7941, '抵抗力': 6369, '一次': 787, '我们': 6052, '擦肩而过': 6630, '害怕': 4776, '电影': 8799, '情景': 5858, '一样': 779, '错过': 11479, '所以': 6182, '一直': 826, '看着': 9095, '可是': 3350, '回头': 3848, '一眼': 828, '珍贵': 8683, '奈何': 4376, '珍惜': 8680, '王雷雷': 8642, '这是': 11085, '为什么': 1453, '浪漫': 8115, '小时候': 4912, '有个': 7208, '收音机': 6650, '好开心': 4462, '睡觉': 9183, '舍不得': 10111, '放下': 6662, '好听': 4444, '这些': 11063, '歌曲': 7650, '经典作品': 9647, '亲亲': 1735, '翩翩': 9789, '夫人': 4345, '爱情': 8485, '时光': 6969, '纪贯': 9594, '一家': 716, '吃饭': 3397, '店里': 5259, '知道': 9202, '什么': 1842, '一下': 607, '爱心': 8482, '幸福': 5221, 'nan': 444, '超级': 10823, '一首歌': 907, '大赞': 4234, '可能': 3361, '单手': 3036, '法拉利': 7987, '多多': 4104, '大笑': 4222, '活下去': 8045, '再见': 2488, '大渣': 4213,...}
    

    查看词频矩阵的结果:

    [[0 0 0 ..., 0 0 0]
     [0 0 0 ..., 0 0 0]
     [0 0 0 ..., 0 0 0]
     ..., 
     [0 0 0 ..., 0 0 0]
     [0 0 0 ..., 0 0 0]
     [0 0 0 ..., 0 0 0]]
    

    0充斥了整个矩阵,查看其维度:

    count.shape
    (20523, 12111)
    

    20523行,12111列,指的是有20523个文档,即用户评论,语料库里一共有12111个词。查看其数据类型:

    type(count)
    scipy.sparse.csr.csr_matrix
    

    妥妥的稀疏矩阵。

    7.3 计算tf-idf值:

    利用TfidfTransformer函数统计CountVectorizer中每个词语的tf-idf权值:

    tfidf_vec = TfidfVectorizer() 
    tfidf_matrix = tfidf_vec.fit_transform(d.title_cutted)
    print(tfidf_matrix.toarray())
    

    得到tf-idf数组:

    [[ 0.  0.  0. ...,  0.  0.  0.]
     [ 0.  0.  0. ...,  0.  0.  0.]
     [ 0.  0.  0. ...,  0.  0.  0.]
     ..., 
     [ 0.  0.  0. ...,  0.  0.  0.]
     [ 0.  0.  0. ...,  0.  0.  0.]
     [ 0.  0.  0. ...,  0.  0.  0.]]
    

    剩余步骤类似于上,找对应函数,得到用户相似度。

    八、相似用户推荐(R语言版本)

    8.1 读取资料库

    设置工作目录,导入函数包:

    setwd("G:\\课程\\研一\\回归分析")
    library(xml2,lib="G:\\R语言\\R语言学习\\安装包")
    library(Rcpp,lib="G:\\R语言\\R语言学习\\安装包")
    library(slam,lib="G:\\R语言\\R语言学习\\安装包")
    library(NLP,lib="G:\\R语言\\R语言学习\\安装包")
    library(tm,lib="G:\\R语言\\R语言学习\\安装包")
    #只有RJava配置成功了,Rwordseg安装才可能成功,前者是后者的依赖包
    #install.packages("rJava",lib="G:\\R语言\\R语言学习\\安装包")
    library(rJava,lib="G:\\R语言\\R语言学习\\安装包")
    #手动下载安装包Rwordseg,然后本地安装
    library(Rwordseg,lib="G:\\R语言\\R语言学习\\安装包")
    

    导入数据,其中,clipboard指的是HuXiu.txt用notepad打开后复制,防止中文乱码

    csv <- read.table("clipboard",header=T, stringsAsFactors=F,quote = "",encoding="utf-8")
    mystopwords<-unlist(read.table("StopWords.txt",stringsAsFactors=F,quote = ""))
    head(csv)
    dim(csv)
    colnames(csv)<-c("text")
    

    8.2 定义数据预处理函数

    • 移除数字函数
    removeNumbers = function(x) { ret = gsub("[0-90123456789]","",x) }
    
    • segmentCN分词函数
      中文分词,也可以考虑使用 rmmseg4j、rsmartcn
    wordsegment<- function(x) { 
      library(Rwordseg) 
      segmentCN(x)
    } 
    
    • 去除停止词函数
    removeStopWords = function(x,words) {     
      ret = character(0) 
      index <- 1 
      it_max <- length(x) 
      while (index <= it_max) { 
        if (length(words[words==x[index]]) <1) ret <- c(ret,x[index]) 
        index <- index +1 
      } 
      ret 
    } 
    

    8.3移除数字

    sample.words <- lapply(data[,1], removeNumbers) 
    dim(as.matrix(sample.words))
    head(sample.words)
    

    8.4 中文分词

    sample.words <- lapply(sample.words, wordsegment) 
    dim(as.matrix(sample.words))
    sample.words[1:6]
    

    8.5 移除停止词

    先处理中文分词,再处理 stopwords,防止全局替换丢失信息,
    (下面这句运行时间较长 )

    sample.words <- lapply(sample.words, removeStopWords, mystopwords) 
    head(sample.words)
    text<-sample.words[,1]
    colnames(sample.words)<-c("text")
    write.csv(as.matrix(sample.words),"delateddata.csv")
    

    8.6 构建语料库

    corpus = Corpus(VectorSource(sample.words)) 
    meta(corpus,"cluster") <- csv$type 
    unique_type <- unique(csv$type) 
    corpus
    

    8.7建立文档-词条矩阵

    (sample.dtm <- DocumentTermMatrix(corpus, control = list(wordLengths = c(2, Inf))))
    

    接下来,就是计算tf-idf值,相似度,得到相似用户,完成用户推荐。

    九 网易云音乐年度总结

    9.1 说明

    灵感:新浪热搜#网易云音乐年度总结#,有这样的总结报告:

    image.png
    image.png
    image.png

    这份报告前些几日刷爆了我的朋友圈,我想的是,既然大家这么喜爱,那我就做一个呗。只要有数据,一切可行!

    但是,有绝大部分数据网易云官方并没有提供给用户本人,而是存放到网易云官方数据库里。还有一部分只有用户本人可以看到,属于隐私信息。文本对无限制权限的选项做一些统计分析,权限列举如下:

    • 某首歌听了多少次(用户本人)
    • 某一天听某首歌特别多次(网易云官方)
    • 2018年年度歌手(网易云官方)
    • 每首歌多少次显示出来(网易云官方)
    • 播放前100歌曲(无限制)
    • 2018年你在网易云听到的最多的歌词(无限制)
    • 晚上12点6点之前以后仍在听歌的记录(网易云官方)
    • 听歌天数最多的歌曲(网易云官方)
    • 曾经喜欢现在冷落的歌(网易云官方)
    • 听了多少首歌(无限制)
    • 花了多少时间(网易云官方)

    最后要做的也只能做的是图9.2:
    一个用户播放记录里面歌词出现次数最多的词语
    以及这个词语分别出现在哪首歌的哪句歌词中

    注:后台时间记录是使用了13位时间戳,需要转化。13位的时间戳的默认精度是毫秒,10位时间戳的精度是秒。 由于时间、精力关系,9.2、9.3暂且放在这里,留着以后做或者删掉。

    9.2 播放记录出现次数最多的词语

    9.3 词语所对应的歌曲歌词

    十、感想

    码代码时,有一个很重要的点就是,你需要有推倒重来的勇气。当前面你已经做了很多工作时,你发现有的方法不太适用、有些繁杂、有更好的、简洁的、可以替代的、功能更全的solutions时,要想到:upgrade,才能不断跨越。

    我很喜欢新鲜感,喜欢尝试一些有趣好玩的东西。潇潇洒洒一万五千余字,这篇文章花了我不少时间,暂停更。

    Written By LXP

    相关文章

      网友评论

        本文标题:网易云音乐上的所有!全部!随便爬!(Python爬虫&基

        本文链接:https://www.haomeiwen.com/subject/qxbksqtx.html