数据分析实战45讲
陈旸
清华大学计算机博士
立即订阅
17333 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 你为什么需要数据分析能力?
免费
第一模块:数据分析基础篇 (16讲)
01丨数据分析全景图及修炼指南
02丨学习数据挖掘的最佳路径是什么?
03丨Python基础语法:开始你的Python之旅
04丨Python科学计算:用NumPy快速处理数据
05丨Python科学计算:Pandas
06 | 学数据分析要掌握哪些基本概念?
07 | 用户画像:标签化就是数据的抽象能力
08 | 数据采集:如何自动化采集数据?
09丨数据采集:如何用八爪鱼采集微博上的“D&G”评论
10丨Python爬虫:如何自动化下载王祖贤海报?
11 | 数据科学家80%时间都花费在了这些清洗任务上?
免费
12 | 数据集成:这些大号一共20亿粉丝?
13 | 数据变换:考试成绩要求正态分布合理么?
14丨数据可视化:掌握数据领域的万金油技能
15丨一次学会Python数据可视化的10种技能
16丨数据分析基础篇答疑
第二模块:数据分析算法篇 (20讲)
17 丨决策树(上):要不要去打篮球?决策树来告诉你
18丨决策树(中):CART,一棵是回归树,另一棵是分类树
19丨决策树(下):泰坦尼克乘客生存预测
20丨朴素贝叶斯分类(上):如何让机器判断男女?
21丨朴素贝叶斯分类(下):如何对文档进行分类?
22丨SVM(上):如何用一根棍子将蓝红两色球分开?
23丨SVM(下):如何进行乳腺癌检测?
24丨KNN(上):如何根据打斗和接吻次数来划分电影类型?
25丨KNN(下):如何对手写数字进行识别?
26丨K-Means(上):如何给20支亚洲球队做聚类?
27丨K-Means(下):如何使用K-Means对图像进行分割?
28丨EM聚类(上):如何将一份菜等分给两个人?
29丨EM聚类(下):用EM算法对王者荣耀英雄进行划分
30丨关联规则挖掘(上):如何用Apriori发现用户购物规则?
31丨关联规则挖掘(下):导演如何选择演员?
32丨PageRank(上):搞懂Google的PageRank算法
33丨PageRank(下):分析希拉里邮件中的人物关系
34丨AdaBoost(上):如何使用AdaBoost提升分类器性能?
35丨AdaBoost(下):如何使用AdaBoost对房价进行预测?
36丨数据分析算法篇答疑
第三模块:数据分析实战篇 (7讲)
37丨数据采集实战:如何自动化运营微博?
38丨数据可视化实战:如何给毛不易的歌曲做词云展示?
39丨数据挖掘实战(1):信用卡违约率分析
40丨数据挖掘实战(2):信用卡诈骗分析
41丨数据挖掘实战(3):如何对比特币走势进行预测?
42丨当我们谈深度学习的时候,我们都在谈什么?
43丨深度学习(下):如何用Keras搭建深度学习网络做手写数字识别?
第四模块:数据分析工作篇 (2讲)
44丨如何培养你的数据分析思维?
45丨求职简历中没有相关项目经验,怎么办?
加餐 (1讲)
加餐丨在社交网络上刷粉刷量,技术上是如何实现的?
结束语 (1讲)
结束语丨当大家都在讲知识和工具的时候,我更希望你重视思维和实战
数据分析实战45讲
登录|注册

38丨数据可视化实战:如何给毛不易的歌曲做词云展示?

陈旸 2019-03-11
今天我们做一个数据可视化的项目。
我们经常需要对分析的数据提取常用词,做词云展示。比如一些互联网公司会抓取用户的画像,或者每日讨论话题的关键词,形成词云并进行展示。再或者,假如你喜欢某个歌手,想了解这个歌手创作的歌曲中经常用到哪些词语,词云就是个很好的工具。最后,只需要将词云生成一张图片就可以直观地看到结果。
那么在今天的实战项目里,有 3 个目标需要掌握:
掌握词云分析工具,并进行可视化呈现;
掌握 Python 爬虫,对网页的数据进行爬取;
掌握 XPath 工具,分析提取想要的元素 。

如何制作词云

首先我们需要了解什么是词云。词云也叫文字云,它帮助我们统计文本中高频出现的词,过滤掉某些常用词(比如“作曲”“作词”),将文本中的重要关键词进行可视化,方便分析者更好更快地了解文本的重点,同时还具有一定的美观度。
Python 提供了词云工具 WordCloud,使用 pip install wordcloud 安装后,就可以创建一个词云,构造方法如下:
wc = WordCloud(
background_color='white',# 设置背景颜色
mask=backgroud_Image,# 设置背景图片
font_path='./SimHei.ttf', # 设置字体,针对中文的情况需要设置中文字体,否则显示乱码
max_words=100, # 设置最大的字数
stopwords=STOPWORDS,# 设置停用词
max_font_size=150,# 设置字体最大值
width=2000,# 设置画布的宽度
height=1200,# 设置画布的高度
random_state=30# 设置多少种随机状态,即多少种颜色
)
实际上 WordCloud 还有更多的构造参数,代码里展示的是一些主要参数,我在代码中都有注释,你可以自己看下。
创建好 WordCloud 类之后,就可以使用 wordcloud=generate(text) 方法生成词云,传入的参数 text 代表你要分析的文本,最后使用 wordcloud.tofile(“a.jpg”) 函数,将得到的词云图像直接保存为图片格式文件。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《数据分析实战45讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(13)

  • third
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt
    import requests

    headers = {
        'Referer': 'http://music.163.com',
        'Host': 'music.163.com',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'User-Agent': 'Chrome/10'
    }


    def getsong(headers):
        url = 'http://music.163.com/api/playlist/detail?id=753776811'
        res = requests.request('GET', url, headers=headers)
        page = res.json()
        tracks=page['result']['tracks']
        list = []
        for i in range(len(tracks)):
            Name = tracks[i]["name"]
            list.append(Name)
        return list


    def create_WordCloud(list):
        print("根源词频计算词云")

        wc = WordCloud(
            font_path="simhei.ttf",
            max_words=100, # 设置最大字数
            width=2000, # 设置画布宽度
            height=1200, # 设置画布高度
            random_state=100
        )
        wordcloud = wc.generate(list)
        # 写词云图片
        wordcloud.to_file("作业.jpg")
        # 显示词云文件
        plt.imshow(wordcloud)
        # 不需要显示X/Y轴,用off将坐标轴关闭
        plt.axis("off")
        plt.show()


    # 去掉停用词以及中英文混合的词
    def remove_stop_words(f):
        stop_words = ['(伴奏)', '(Demo版)', '(必胜客新春版)']
        mixed_words = ['Bonus Track:一荤一素', 'Bonus Track:给你给我']
        for stop_word in stop_words:
            f = f.replace(stop_word, '')
        for mixed_word in mixed_words:
            f = f.replace(mixed_word, mixed_word[12:])
        return f

    gerlists = getsong(headers)
    # 获取歌单是list类型直接转化为转换为str
    lists_str = " ".join(gerlists)

    lists = remove_stop_words(lists_str)
    create_WordCloud(lists)
    2019-03-20
    1
  • 王彬成

    (2)将歌单的歌曲对应的歌词作词云展示
    import requests
    import jieba
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt


    #得到指定歌单页面的 全部歌曲的歌曲ID,歌曲名
    def get_songs(playlist_id):
        page_url='http://music.163.com/api/playlist/detail?id='+playlist_id
        #获取网页HTML
        res=requests.request('GET',page_url,headers=headers)
        # 输出歌单中歌曲数量
        print(len(res.json()['result']['tracks']))

        # 设置热门歌曲的ID,歌曲名称
        song_ids=[]
        song_names=[]

        for i in range(len(res.json()['result']['tracks'])):
            names=res.json()['result']['tracks'][i]['name']
            ids=res.json()['result']['tracks'][i]['id']
            song_names.append(names)
            song_ids.append(ids)
            print(names,' ',ids)
        return song_names,song_ids
     
    # 得到某一首歌的歌词
    def get_song_lyric(headers,lyric_url):
        res = requests.request('GET', lyric_url, headers=headers)
        if 'lrc' in res.json():
           lyric = res.json()['lrc']['lyric']
           new_lyric = re.sub(r'[\d:.[\]]','',lyric)
           return new_lyric
        else:
           return ''
           print(res.json())



    #生成词云
    def create_word_cloud(f):
        print('根据词频 生成词云')
        f=remove_stop_words(f)
        cut_text=' '.join(jieba.cut(f,cut_all=False,HMM=True))
        wc = WordCloud(
           font_path="./wc.ttf",
           max_words=100,
           width=2000,
           height=1200,
        )
        print(cut_text)
        wordcloud = wc.generate(cut_text)
        # 写词云图片
        wordcloud.to_file("wordcloud.jpg")
        # 显示词云文件
        plt.imshow(wordcloud)
        plt.axis("off")
        plt.show()
        

    # 设置歌单ID,【毛不易 | 不善言辞的深情】为753776811
    playlist_id='753776811'
    [song_names,song_ids]=get_songs(playlist_id)

    #所有歌词
    all_word=''
    # 获取每首歌歌词
    for (song_id, song_name) in zip(song_ids, song_names):
        # 歌词 API URL
        lyric_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + str(song_id) + '&lv=-1&kv=-1&tv=-1'
        lyric = get_song_lyric(headers, lyric_url)
        all_word = all_word + ' ' + lyric
        print(song_name)

    #根据词频,生成词云
    create_word_cloud(all_word)
    2019-03-13
    1
  • 一语中的
    以http://music.163.com/api/playlist/detail?id=753776811中歌单为例做词云展示
    #-*- coding:utf-8 -*-
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt
    import requests

    def getSonglists(url, headers):
        #根据歌单API获取歌曲列表
    #将页面信息转换为json格式便于通过字典取值
        r = requests.get(url, headers=headers)
        page_json = r.json()
        tracks = page_json["result"]["tracks"]
        lists = []
        for i in range(len(tracks)):
            listName = tracks[i]["name"]
            lists.append(listName)
        return lists

    #生成词云
    def create_WordCloud(lists):
        print("根源词频计算词云")
     
        wc = WordCloud(
            font_path = "C:\Windows\Fonts\simhei.ttf", #设置中文字体
            max_words = 100, #设置最大字数
            width = 2000, #设置画布宽度
            height = 1200, #设置画布高度
            random_state = 100
        )
        wordcloud = wc.generate(lists)
        #写词云图片
        wordcloud.to_file("wordcloud.jpg")
        #显示词云文件
        plt.imshow(wordcloud)
        #不需要显示X/Y轴,用off将坐标轴关闭
        plt.axis("off")
        plt.show()

    #去掉停用词以及中英文混合的词
    def remove_stop_words(f):
        stop_words = ['(伴奏)', '(Demo版)', '(必胜客新春版)']
        mixed_words = ['Bonus Track:一荤一素', 'Bonus Track:给你给我']
        for stop_word in stop_words:
            f = f.replace(stop_word, '')
        for mixed_word in mixed_words:
            f = f.replace(mixed_word, mixed_word[12:])
        return f

    if __name__ == "__main__":

        headers = {
            'Referer': 'http://music.163.com',
            'Host': 'music.163.com',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'User-Agent': 'Chrome/10'
        }
        url = "http://music.163.com/api/playlist/detail?id=753776811"
        gerLists = getSonglists(url, headers)
    #获取歌单是list类型,转换为str,那么就不再需要用jieba分词
        lists_str = " ".join(gerLists)

        lists = remove_stop_words(lists_str)
        create_WordCloud(lists)
    2019-03-11
    1
  • #Yema
    lyric_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + str(song_id) + '&lv=-1&kv=-1
    老师能解释一下这个url是从哪找到的吗?为什么在浏览器抓包里面没有找到这个api,我找到的api是一个异步需要向api传csrf_token才能拿到歌词
    2019-12-12
  • Kyle
    # -*- coding:utf-8 -*-
    # 网易云音乐 通过歌手ID,生成该歌手的词云
    import requests
    import os
    import re
    import sys
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt
    from PIL import Image
    import numpy as np
    import jieba
    from lxml import etree

    headers = {
        'Referer': 'http://music.163.com',
        'Host': 'music.163.com',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'User-Agent': 'Chrome/10'
    }

    # 获取到歌单的信息
    def get_song_list(headers,song_list_url):
        res = requests.request("GET",song_list_url,headers=headers)
        if 'result' in res.json():
            all_song_list = ""
            for song_list in res.json()['result']['tracks']:
                all_song_list = all_song_list + song_list['name']
                print(all_song_list)
            return all_song_list
        else:
            return ''

    # 创建词云展示
    def wordcloud(f):
        print("根据词频结果进行词云展示!")
        cut_text = " ".join(jieba.cut(f,cut_all=False,HMM=True))
        wc = WordCloud(
            font_path="./wc.ttf",
            max_words=100,
            width=2000,
            height=1200,
        )
        wordcloud = wc.generate(cut_text)
        wordcloud.to_file("song_list_wordcloud.jpg")
        # 词云展示
        plt.imshow(wordcloud)
        plt.axis("off")
        plt.show()

    # 获取歌单
    song_list_id = '753776811'
    song_list_url = 'http://music.163.com/api/playlist/detail?id=' + song_list_id
    all_song_list_new = get_song_list(headers,song_list_url)
    wordcloud(all_song_list_new)
    2019-09-22
  • 挠头侠
    老師 這個歌曲頁面不是动态加载的吗,怎么可以直接用requests呀
    2019-05-23
  • 挠头侠
    老师可以介绍一下jieba中HMM参数的作用吗
    2019-05-23
  • 课后作业:语言Python3.6
    import requests
    import matplotlib.pyplot as plt
    from wordcloud import WordCloud

    #创建请求头
    headers = {
        'Referer':'http://music.163.com',
        'Host':'music.163.com',
        'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/Webp,image/apng,*/*;q=0.8',
        'User-Agent':'Chrome/10'
    }

    #获取歌单
    def get_song_name(req_url):
        res = requests.request('GET',req_url,headers=headers)
        if 'tracks' in res.json()['result']:
            tracks = res.json()['result']['tracks']
            names = []
            for i in range(len(tracks)):
                name = tracks[i]['name']
                names.append(name)
            return names
        else:
            return ''

    #过滤停用词
    def remove_stop_words(text):
        stop_words = ['(伴奏)','Bonus Track:','(Demo版)']
        for stop_word in stop_words:
            text = text.replace(stop_word,'')
        return text

    path = '/Users/apple/Desktop/GitHubProject/Read mark/数据分析/geekTime/data/'
    #获得词云
    def create_wordcloud(text):
        #移除过滤词
        text = remove_stop_words(text)
        wc = WordCloud(
            font_path = "/Library/Fonts/Arial Unicode.ttf",
            max_words = 100,
            width = 2000,
            height = 1200
        )
        wordcloud = wc.generate(text)
        wordcloud.to_file(path + 'wordcloud_homework.jpg')
        plt.imshow(wordcloud)
        plt.axis('off')
        plt.show()

    #处理歌单,形成词云
    request_url = 'http://music.163.com/api/playlist/detail?id=753776811'
    content_list = get_song_name(request_url)
    content = " ".join(content_list)
    print('歌单信息---',content)
    create_wordcloud(content)

    --------------
    歌单信息--- 别再闹了 在无风时 那时的我们 从无到有 一江水 借 消愁 不染 盛夏 哎哟 无问 一荤一素 南一道街 芬芳一生 请记住我 项羽虞姬 给你给我 想你想你 意料之中 平凡的一天 像我这样的人 感觉自己是巨星 如果有一天我变得很有钱 借 (伴奏) 消愁 (伴奏) 盛夏 (伴奏) 哎哟 (伴奏) 想你想你 (伴奏) 南一道街 (伴奏) 给你给我 (伴奏) 芬芳一生 (伴奏) 一荤一素 (伴奏) 平凡的一天 (伴奏) 像我这样的人 (伴奏) 如果有一天我变得很有钱 (伴奏) 如果有一天我变得很有钱 (必胜客新春版) Bonus Track:一荤一素 (Demo版) Bonus Track:给你给我 (Demo版)
    ---------------
    图片无法展示,希望极客实践的PM能提出改进方案,前端和后台实现一下(😂😂),祝专栏越做越好
    2019-04-24
  • 上官
    Traceback (most recent call last):
      File "/Users/shangguan/PycharmProjects/LicenseRecognition/geci.py", line 85, in <module>
        [song_ids, song_names] = get_songs(artist_id)
    TypeError: 'NoneType' object is not iterable

    为什么报nonetype?
    2019-03-25
  • 王彬成
    题目理解(1):将歌单的歌曲名称作词云展示
    -------
    import requests
    import jieba
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt

    headers = {
           'Referer' :'http://music.163.com',
           'Host' :'music.163.com',
           'Accept' :'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
           'User-Agent':'Chrome/10'
        }

    #得到指定歌单页面的 全部歌曲的歌曲ID,歌曲名
    def get_songs(playlist_id):
        page_url='http://music.163.com/api/playlist/detail?id='+playlist_id
        #获取网页HTML
        res=requests.request('GET',page_url,headers=headers)
        # 输出歌单中歌曲数量
        print(len(res.json()['result']['tracks']))

        # 设置热门歌曲的ID,歌曲名称
        song_ids=[]
        song_names=[]

        for i in range(len(res.json()['result']['tracks'])):
            names=res.json()['result']['tracks'][i]['name']
            ids=res.json()['result']['tracks'][i]['id']
            song_names.append(names)
            song_ids.append(ids)
            print(names,' ',ids)
        return song_names,song_ids

    #去掉停用词
    def remove_stop_words(f):
        stop_words=['Demo','伴奏','版','必胜客','Bonus','Track']
        for stop_word in stop_words:
            f=f.replace(stop_word,'')
        return f

    #生成词云
    def create_word_cloud(f):
        print('根据词频 生成词云')
        f=remove_stop_words(f)
        cut_text=' '.join(jieba.cut(f,cut_all=False,HMM=True))
        wc = WordCloud(
           font_path="./wc.ttf",
           max_words=100,
           width=2000,
           height=1200,
        )
        print(cut_text)
        wordcloud = wc.generate(cut_text)
        # 写词云图片
        wordcloud.to_file("wordcloud.jpg")
        # 显示词云文件
        plt.imshow(wordcloud)
        plt.axis("off")
        plt.show()
        

    # 设置歌单ID,【毛不易 | 不善言辞的深情】为753776811
    playlist_id='753776811'
    [song_names,song_ids]=get_songs(playlist_id)

    # 将列表song_names生成字符串
    song_names_text=" ".join(song_names)

    #根据词频,生成词云
    create_word_cloud(song_names_text)
    2019-03-13
  • 跳跳
    #需要注意的有两点
    #1.歌单返回的是json文件,get_songs需要参考get_songs_lyri获取
    #2.list_url中间是str类型,注意类型转换
    #emmm,代码太长放不下了,删除了一部分和老师一样的函数
    # -*- coding:utf-8 -*-
    # 网易云音乐 通过歌单ID,生成该歌单的词云
    import requests
    import sys
    import re
    import os
    from wordcloud import WordCloud
    import matplotlib.pyplot as plt
    import jieba
    from PIL import Image
    import numpy as np
    from lxml import etree
    def get_songs(songlist):
        list_url='https://music.163.com/api/playlist/detail?id='+songlist
        res = requests.request('GET', list_url, headers=headers)
        if 'result' in res.json():
            for item in res.json()['result']['tracks']: # 读取json数据中的每一个ID和name
                song_ids.append(item['id'])
                song_names.append(item['name'])
                print(item['id']," ",item['name'])
                time.sleep(1) # 设置停留时间,防止“bad handshake”
            return song_ids,song_names
        else:
            return ''
            print(res.json())
    # 设置歌单
    songlist = '753776811'
    [song_ids, song_names] = get_songs(songlist)
    # 所有歌词
    all_word = ''
    # 获取每首歌歌词
    for (song_id, song_name) in zip(song_ids, song_names):
        # 歌词 API URL
        list_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + str(song_id) + '&lv=-1&kv=-1&tv=-1'
        lyric = get_song_lyric(headers, list_url)
        all_word = all_word + ' ' + lyric
        print(song_name)
    # 根据词频 生成词云
    create_word_cloud(all_word)
    2019-03-13
  • 思考题关键代码部分:

    import time
    id_list = []
    name_list = []
    # 得到某一歌单里的每一首歌ID和歌名
    def get_song_list(headers,list_url):
        res = requests.request('GET', list_url, headers=headers)
        if 'result' in res.json():
            for item in res.json()['result']['tracks']: # 读取json数据中的每一个ID和name
                id_list.append(item['id'])
                name_list.append(item['name'])
                print(item['id']," ",item['name'])
                time.sleep(1) # 设置停留时间,防止“bad handshake”
            return id_list,name_list
        else:
            return ''
            print(res.json())
            
    # 设置歌单链接
    list_url = 'https://music.163.com/api/playlist/detail?id=753776811'
    # 获得歌单每一首歌的ID和name
    get_song_list(headers,list_url)
         
    all_word_list = ''
    # 获取每首歌歌词
    for (song_id, song_name) in zip(id_list, name_list):
        # 歌词 API URL
        lyric_url = 'http://music.163.com/api/song/lyric?os=pc&id=' + str(song_id) + '&lv=-1&kv=-1&tv=-1'
        lyric = get_song_lyric(headers, lyric_url)
        all_word_list = all_word_list + ' ' + lyric
        print(song_name)
        
    # 去掉停用词
    remove_stop_words(all_word_list)

    # 根据词频 生成词云
    create_word_cloud(all_word_list)
    2019-03-11
  • 上善若水
    Traceback (most recent call last):
      File "C:\Program Files\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
        exec(code_obj, self.user_global_ns, self.user_ns)
      File "<ipython-input-2-d883ef070907>", line 1, in <module>
    运行报错,请问是什么原因?
    2019-03-11
收起评论
13
返回
顶部