Sparkify is a digital music service similar to Netease Cloud Music or QQ Music. Many of the users stream their favorite songs in Sparkify service everyday, either using free tier that places advertisements in between the songs, or using the premium subscription model where they stream music as free, but pay a monthly flat rate. User can upgrade, downgrade or cancel their service at anytime.
This is a Customer Churn Prediction Problem
, there are so many similar projects, such as WSDM - KKBox’s Churn Prediction Challenge competition from Kaggle, and a few helpful links are follows:
So, our job is deep mining the customers’ data and implement appropriate model to predict customer churn as follow steps:
f1 score
as a metrics to measure models’ performance.A mini subset of size 125 MB of the original 12 GB customer log json data file will be used for creating the prediction model. The small dataset has 286’500 log entries with 18 unique columns.
The schema and info of dataset is given below:
1 | root |
Column’s Name | Description |
---|---|
artist | The artist being listened to |
auth | Whether or not the user is logged in |
firstName/lastName | Name of the user |
gender | Gender of the user |
itemInSession | Item number in session |
length | Length of time for current row of specific log |
level | Free or Paid user |
location | Physical location of user, including City and State |
method | Get or Put requests |
page | Which page are user on in current row |
registration | Users registration number |
sessionId | Session ID |
song | Song currently being played |
status | Web status |
ts | Timestamp of current row |
userAgent | Useragent of post or get in browser of users |
userId | User ID |
We use the Cancellation Confirmation
events of page
column to define the customer churn, and perform some exploratory data analysis to observe the behavior for users who stayed vs users who churned.
So, there are 52 users have churned events in the dataset, it’s about 23.1% churned rate. The rate of churn and not churn is roughly 1:3, so this is an unbalanced dataset.
Can we say the gender has effect on Churn or not ? We calculate the p-value and result is 0.20 over 0.05, so, we can’t say like that.
We count each item in page
column of different group and normalized data.
Obviously, NextSong
has accounted for most of customers’ events. Thumbs Up
,Thumbs Down
, Home
and Add to Playlist
have effect on churn too.
We extract the browser and platform of customers from userAgent
column.
Customers using safari and iPad have more proportion in churn.
We extract day-of-month, day-of-week and hour from ts
column.
Customers from churn group have more events after 15th in one month, and have less events in weekend.
On the basis of the above EDA, we can create features as follows:
We implement label encoding on categorical features and standard scaler on numerical features.
We split the full dataset into train and test sets. Test out the baseline of four machine learning methods: Logistic Regression, Linear SVC, Decision Tree Classifier and Random Forest Classifier.
Though the LinearSVC
spent more training time, but it can get the highest f1 score 0.702. And the LogisticRegression
has a medium training time and f1 score, maybe I can tuning it to get a higher
score. So I’ll choose LinearSVC
and LogisticRegression
to tuning in next section, the result is as follows:
Training time:
F-1 Score:
Training time:
F-1 Score:
As we can see in above, the logistic regression (0.7021) can get a nearly f1 score as the linear svm classifier(0.7045). But the logistic regression saves 83.3% time spending than the latter, considering this is only a quit mini dataset and our purpose is scaling this up to the total 12G dataset, so, the logistic regression is the best model from now on in this project.
In this project I set out to predict customers’ churn problem with the dataset of a music streaming service named Sparkify. This is a binary classification problem , so I choose four supervised learning algorithm to found a model. After evaluated and tuning, I find out the logistic regression is the suitable model for this project because of its balanced and high f1-score (0.7021) and time spending.
By the way, I once fell into the trap of data leakage ,so that all of the models can achieve a performance that seems too good (1 for f1-score) to be true. I had to go back to check my feature engineering, and found I put the cancellation confirmation
which is the flag of churn in the features, what a awkward thing! And that teach us you must be careful and patient when you are working.
There are only about 76 samples in the mini dataset above, so the model could be improved by being trained on a bigger dataset and tuning hyper parameters based on it.
Another improvement could be to try out more features or deep learning models.
Hope you find this interesting and for further details on this analysis like code and process followed would be available here.
]]>当处理一些较为灵活的数据时,团队内不同角色的同事会有自己对数据的关注点,所以,这就要求数据分析师不能只出一个“死”报告了事儿,而需要的是一个可以让同事们去探索,去解决自己关注问题的”活“报告——Dashboard。本文就一起来探讨下,利用Flask和Pyecharts搭建局域网内Dashboard的方法,其中Flask用来提供Web应用框架,Pyecharts用来解决交互式可视化的需求。
如上图所示,我们依据数据的流向确定了Dashboard的框架,并列出了在不同过程中的所需知识:
这在Pyecharts的官方文档中写的非常详细,可以戳Flask 模板渲染查看示例。
为了快速搭建Dashboard,免去一些前端配色、布局等烦恼,我们一般会挑选一个HTML模板,而Jinja2就是一个模板渲染引擎,它的语法中,使用一对双大括号标记变量,这与JavaScript的语法标记会有冲突,所以,如果你使用Jinja2进行模板渲染的同时使用了JavaScript,就要进行语法冲突处理。
Github链接:Flask+Pyecharts定制Dashboard
除以上两点之外,在源码中,还实现了以下功能:
希望能对有相同需求的你有所帮助,欢迎留言,一起讨论!
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
]]>在处理字符串时,有时需要从字符串中提取出第n次出现某字符的位置,比如说想在字符串'abcdabdcsas'
中找到第2次出现'ab'
的索引,但Python String
提供的find
函数只能Return the lowest index in S where substring sub is found
,所以,自己动手,丰衣足食:joy:
本文分为两部分:
先用find
函数查找得到第一次出现的索引,然后将字符串在该索引处做切片,再进行查找,以此类推,直到查询到第n次。
1 | def finding_nemo_1(String,Substr,times): |
split
切分和列表将String按照Substr切分times次,代码如下所示,计算很简单。
1 | def finding_nemo_2(String,Substr,times): |
我们对以上两种方法进行了对比,如下图所示,第二种方法的优势随着字符串长度的增长而更加明显。
第二种方法,巧就巧在将运行效率低的for
循环替换成了split
,在对长度为250e6的字符串进行查找时,运算时间缩短了近77%。
很容易将以上两种方法改写成获取某字符出现的全部索引
函数。
1 | #方法一 |
那获取某字符串最后一次出现的位置,有没有更便捷的方法呢?
所以,我们将字符串反转,再用find就可以很容易求得索引了。
1 | last_index = -(String[::-1].find(Substr) + 1) |
如果你也有其他的方法,欢迎留言,一起讨论~
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
]]>上一篇博客中,我们把图片中的水印去除掉,并且加深了字体的颜色,之后我对图片的大小进行了统一,甚至我还专门给他们都加上了参照字段,分别尝试了百度AIP的表格识别服务和Face++的自定义模板文字识别服务,可能是因为图片的分辨率较低,而且文字较密集的缘故,最终得到的结果都不尽如人意,错误率非常高,所以准备尝试下先将图片按照行列进行分割,之后再逐个去识别的方法,结果却出乎我的意料。
要想对图片中的表格进行精准切分,就必须要先对表格进行识别,然后再根据行列相交点的位置进行切分。
1 | def cv_imread(filepath): |
因为后续的
膨胀
是对高亮部分(白色)进行处理,所以就需要把我们感兴趣的部分——表格线转为白色
1 | #转为二值图,矩阵中只有0和255 |
1 | cv2.imshow("Image",img_thresh) |
1 | rows,cols=img_thresh.shape |
识别的关键就在于腐蚀
与膨胀
函数。腐蚀即为让卷积核在二值化的图片上滑动并进行卷积计算,只有在卷积核范围内图片中的所有值均为255时才会得到255的结果,其余情况均得到0;而膨胀刚好相反,在卷积核范围内只要有一个值为255,那么就会得到255的结果。
所以,在我们进行表格中的行识别时,就需要选择尽可能长(很多列)和矮(一行)这种形状的卷积核,才能契合长长的横线,然后把比较短的文字腐蚀掉。看下面的示例:
示例图片的shape为(369,1000)
precision=20
时,卷积核的shape为(50,1),识别得到的结果:
这时候已经把所有行都识别出来了,因为不会有任何一个字的长度可以超过50个像素,那么现在我们把卷积核的shape调整到(5,1)再来看下效果。
precision=200
时,识别得到的结果:
可以发现,很多字中的横
都没有被腐蚀掉。
我们筛选出那些在行和列都等于255的点,就可以得到所有交点了。
1 | intersections = cv2.bitwise_and(row_lines,col_lines) |
1 | #筛选出白点的索引(坐标) |
这样我们就把所有交点的坐标都筛选出来了。
按照交点坐标截取单元格后,再转换为jpg或者是png格式的二进制编码,利用百度aip的通用文字识别API进行识别,获取结果。
1 | #按照交点坐标截取单元格 |
最后再利用Pandas将得到的结果以此储存到DataFrame中,导出Excel,收工!
下一步尝试:
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
]]>今年阳光高考公示的自主招生名单变成了图片格式,还加了水印,(洪主编说“今年阳光高考变坏了”:joy:),确实是变坏了,无形中给我增添了不少工作:angry:,那么要转为Excel,就要进行文字识别,就需要先把烦人的水印去除掉。
本文分为两部分:
先放原图:
观察上图,可以得到如下结论:
图片本身就是灰度图,也就是各个像素的RGB是相等的;
水印的位置并不固定,没办法针对某一位置单独处理;
水印颜色统一;
水印颜色与文字颜色相差较多,水印颜色要比文字颜色浅;
让我做PS是不可能的,因为还有上百张这样的图片。
所以,我们可以从颜色上入手,直接用OpenCV中的Image Thresholding函数,选择介于文字与水印灰度中间的某一值作为阈值,然后将大于该阈值的值替换为255(白色),小于该阈值的值替换为0(黑色),这样便可以把图片中所有水印(包括表头的阴影)都去除掉了。
为了选择阈值,我们得先看一下文字和水印的RGB,我是用的Colors Pro(随便下一个颜色识别器或者用Office/PS等都可以)。
识别结果如上:
文字的灰度介于50~140之间;水印及阴影的灰度介于220-240之间,所以我们可以选择200作为阈值。
1 | cv2.threshold(img, 200, 255, cv2.THRESH_BINARY)[1] |
去除水印后的效果:
去水印的速度非常快(不到一秒一张图),效果也很不错,不仅去除了水印,还把原来偏灰色的文字变成了黑色,更方便下一步的文字识别工作。
但,同事也有这种需求,就索性封装一个可执行文件exe给他备用,本来以为很简单的事儿,折腾了我一整个晚上:joy:,下面分享下我封装python脚本时踩的坑。
参考stackoverflow上a-good-python-to-exe-compiler的答案,大家都在推荐Pyinstaller,所以就是它了。
Pyinstaller的使用方法非常简单,只需
1 | #安装 |
然后在命令行中进入到目标脚本的文件夹下,输入
1 | #-F为附加的参数,效果为只输出单个的exe文件,拷给基友用更方便 |
就可以在生成的hist
文件夹下找到封装好的exe文件了:smile:。
然而事情的真相是,各种Permission Denied
,网上的解决方法是用管理员模式运行
,对于我这电脑来说然并卵。折腾了一晚上,终于通过安装了下面两个库解决了:
这个去水印小工具,只能针对类似文中的这种灰度图进行水印处理,如果你想去除彩色图片的水印,请打开PS,然后用Shift+F5盘它!
最后附上这个去水印小工具:链接, 密码:r38ev8
使用方法:
自行搜索安装vc++2018运行库合集
把exe复制到你要处理图片的文件夹
打开,输入阈值灰度
回车,处理好的图片会自动储存在removed
文件夹下
运行效果:
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
]]>Shortly after moving to San Francisco in October 2007, roommates and former schoolmates Brian Chesky and Joe Gebbia could not afford the rent for their loft apartment. Chesky and Gebbia came up with the idea of putting an air mattress in their living room and turning it into a bed and breakfast. The goal at first was just “to make a few bucks”.
—— Airbnb Wiki
Airbnb, Inc., is an online marketplace and hospitality service brokerage company, It has a cool brand story, with hosts sharing their extra living space, guests living for a fee, and allowing guests to experience real local life instead of booking a hotel. It sounds really cool, but what is the real situation in Beijing? Let’s check it out from two parts:
In this blog, the data is provided by Inside Airbnb, and it contains all informations of 25921 listings in Beijing.
In this part ,we will focus on prices and numbers of listings in different times and different locations to learn about Airbnb’s development in Beijing.
In this part , we will focus on host introduction ,type and service to look deep inside the hosts of Airbnb in Beijing.
I made a word cloud with host_about
. As we can see, most hosts like to put a label “like to make friends” ,” welcome friends all over the word” or “like to travel” on themselves. It seems to be a good match for Airbnb’s slogan.
Now that the hosts are describing themselves so enthusiastic, what are they actually like?
In the box plot, I set outliers when it’s over 1.5 times of IQR.
Almost a half of hosts have more than 2 listings, some of them are apartment companies, some of them are sublessors , so we can see that there are some people investing or starting a business in Airbnb with listings.
Maybe we should call hosts with 2-5 listings sublessors, and more than 5 listings should be called professional hosts, and the others are called personal host.
There are 56% of hosts are personal hosts, but they only account for 19.5% of listings. Conversely, 14.5% of hosts are professional hosts, but they account for nearly 55% of listings. I have no idea what is the difference between this kind of listings and hotels, except for not safe maybe.
We chose
Proportion of within an hour
,Host Response Rate
andAverage Score
to judge the pros and cons of service.
As shown in the plot above, the personal host has the lowest Proportion of within an hour
and Host Response Rate
, but has the highest Average Score
. Meanwhile, the professional hosts has the exact opposite characteristics.
Maybe a personal host need to work or do something else which makes he doesn’t have enough time to response guests timely, but he can help guests experience a real local life which makes he get a high review score.
I made some attempts, but the results were not satisfactory. Although the following characteristics have the greatest impact on the price.
Top five importances of features are shown in the plot above, and we can say the more guests a listing can accommodate, the higher price it can be.(It’s like crap.)
If you have any plans to travel to Beijing recently and you want to book a listing through Airbnb, please note these suggestions:
Finally, I hope you’ll be welcomed home by Airbnb :).
]]>最近在处理自主招生的数据,对于某一个确定的高校来说,录取的人数远远小于未录取的人数,换言之,就是录取类的数据量远小于未录取类的数据量,这就是不平衡数据,虽然在机器学习中不平衡数据的处理不是难点,但这也是我们不得不去考虑的问题,那在本篇文章中,我们便来一起探讨下有哪些处理不平衡数据的技巧。
不平衡数据,顾名思义,就是指在收集到的数据中各个分类之比并非为1:1
,在对不平衡数据的研究中,普遍认为不平衡意味着少数类所占比例在10%到20%之间,但实际上,这种现象可能会更严重,比如说:
对于这种不平衡的数据来说,如果不进行数据预处理就应用机器学习算法进行训练,那么得到的模型只需要把所有的结果都预测为多数类那边,就能获得很高的准确率(比如说,对所有的学生都判定为审核未通过,那么准确率会达到1-0.2%=99.8%),但是这其实一点用都没有。
平衡数据大概像是这样:
不平衡数据大概像是这样:
处理不平衡数据的思路比较简单,那就是想办法让数据平衡,我们可以简单得分为以下几类:
更多更详细研究范畴的分类可以查看这篇论文A Survey of Predictive Modelling under Imbalanced Distributions
那接下来,我们分别看一下各个方法在python中的具体实施。
采样就是通过减少多数类数量的下采样(Undersampling)或增加少数类数量的上采样(Oversampling)方式,实现各类别平衡。针对两种采样方式,依赖不同的方法,比如说 随机、模型融合等,就会生成很多解决方案,可以看这篇综述Learning from Imbalanced Data的总结。
有一个叫做imbalanced-learn
的库,是专门针对不平衡数据设计的,其中包含很多上采样和下采样的函数,官方文档在这里。
示例:
1 | from collections import Counter |
Original dataset shape Counter({1: 900, 0: 100})
1 | #随机下采样 |
Resampled dataset shape Counter({0: 100, 1: 100})
1 | #随机上采样 |
Resampled dataset shape Counter({0: 900, 1: 900})
随机上采样会反复出现一些样本,而导致过拟合;随机下采样则会造成一定程度的特征丢失,虽然这种方式比较简单,但现在计算机的计算能力越来越高,可接受的算法复杂度也越来越高,所以我们应该主要考虑模型训练的效果。
数据合成则是利用已有样本生成更多样本,其中常用的包括:
SMOTE
,利用KNN生成新数据;
SMOTEC
,可以合成分类数据,但数据集中至少要包含一条连续数据;
如果数据集中全是分类数据的话,可以增加一列全为1的intercept列作为连续数据,合成数据之后,再将该列删除即可。
BorderlineSMOTE
,与SMOTE的区别是,只为那些周围大部分是大众样本的小众样本生成新样本(因为这些样本往往是边界样本);
1 | from imblearn.over_sampling import SMOTE |
Resampled dataset shape Counter({0: 900, 1: 900})
更改权重就是针对不同类别的数据设置不同的分错代价,即提高少数类分错的代价或降低多数类分错的代价,最终使各类别平衡。
常用的机器学习训练方法中,很多都提供了权重设置参数class_weight
,可以手动设置该参数,但一般情况下只需要将其设置为balanced
即可,模型会自动按照如下公式更新权重:
1 | from sklearn.linear_model import LogisticRegression |
这种方法比较适合极不平衡数据,或数据量比较小的数据集。
主要方法为OneClassSVM
,官方文档在这里
1 | from sklearn import svm |
异常检测我没怎么用过,所以就不赘述了,感兴趣可以戳这个链接Novelty and Outlier Detection
我们可以依据数据量的大小和是否平衡将数据集分为四类,即平衡的大数据集,不平衡的大数据集,平衡的小数据集,不平衡的小数据集。最简单的就是平衡的大数据集,能达到非常高的准确率,最难的就是不平衡的小数据集,除了在平衡上下功夫之外,还需要很多诸如收集数据、特征工程之类的工作,但这并不是本篇文章的重点。
下面根据个人经验谈下针对如上几种数据集,如何选择文中涉及的这些方法:
具体数据量的大小可以参考下图:
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
littlecodersh的ItChat
可以获取公众号的名称、功能描述以及地区,但并没有把公众号的ID以及认证公司等信息集成进去,而且必须要本人关注之后才能处理;
搜狗微信的信息倒是齐全,完全可以满足要求,但是尝试了request+BeatifulSoup还有Selenium之后发现,这个网址真的太小气了,我加了延时,用了代理,依然各种被封,或者是要求输入验证码;
只能获取已经收录的公众号信息,好在收录的数量也很多,用request会出现搜索失败,但是用Selenium还是稳的,加了延时,顺利获取了几千条数据。而且,这里还可以查到各个行业时下最热文章、阅读量等等信息。
用selenium爬取代码如下:
1 | from selenium import webdriver |
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
最近单位需要批量输出报告,好在这些报告的整体模板相同,只有一些跟用户相关的信息需要替换。几千份的重复工作,还是交给Python去处理吧。
本文的技术路径为:利用docxtpl
对word模板文件进行变量替换,然后利用
将word转换为pdf。
本文代码应用环境如下:
1 | * Windows 7 |
主要用docxtpl
库实现。官方文档
直接pip install docxtpl
即可,会自动安装依赖库:docx
和jinja2
。
如下所示,将需要进行变量替换的位置用两对大括号括起来,并在其中添加变量名
,这是后续能通过python识别替换的关键。
表格的变量设置比较麻烦,可以查看官方github,里面有很多示例代码,随用随取。
设置表格变量的时候,有两个关键,一个是行
,一个是列
,其中行用字段tr
(row)表示,列用字段tc
(column)表示。
如下表中所示,我们通过构建列表循环 和 调用字典key的方式,对表格中的各个项进行填充。
1 | from docxtpl import DocxTemplate,InlineImage |
通过Windows Com组件(win32com),调用Word服务(Word.Application),实现Word到PDF文件的转换。因此,要求该Python程序需要在有Word服务(可能至少要求2007版本)的Windows机器上运行。
1 | import win32com.client |
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
A positive attitude causes a chain reaction of positive thoughts,events and outcomes.
Hi,同学们,上周我们主要对python的基础知识进行了学习,从完全不懂到写出第一段代码,从畏惧发怵到解决第一个代码问题,大家已经从小白迈出了python入门的第一步!你们都是最棒的!那请继续保持着这样的学习动力,趁热打铁,继续我们的课程吧!
本周开始,我们就进入到了项目二(P2)阶段的第二周,需要针对数据分析来学习两个重要的第三方库Numpy和Pandas,它们是python实现科学计算和数据处理的重要库,在以后的数据分析路上会经常用到,所以一定要掌握,并且还要熟练!
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | Python基础内容 | 数据类型和运算符、控制流、函数、脚本编写 |
第2周 | Python数据处理内容 | Numpy & Pandas |
第3周 | 完成项目 | 项目:探索美国共享单车数据 |
第4周 | 项目修改与通过 | 修改项目、查缺补漏、休息调整 |
对于非小白同学来说,本阶段内容不是很难,希望你们能在三周内完成并通过项目;
对于小白来说,本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
NumPy 是 Numerical Python 的简称,它是 Python 中的科学计算基本软件包。NumPy 为 Python 提供了大量数学库,使我们能够高效地进行数字计算。更多可点击Numpy官网查看。
关于Numpy需要知道的几点:
所以,Numpy 的核心是ndarray
对象,这个对象封装了同质数据类型的n维数组。起名 ndarray
的原因就是因为是 n-dimension-array
的简写。接下来本节所有的课程都是围绕着ndarray来讲的,理论知识较少,代码量较多,所以大家在学习的时候,多自己动动手,尝试自己去运行一下代码。
课程中所说的,创建一个秩为2的ndarray,实际上指的是创建一个2维的ndarray,并不是矩阵的秩。
1 | a = np.array([1, 2, 3]) # 1维数组 |
1 | a = np.zeros((2,2)) # 创建2x2的全0数组 |
这里主要是提供了一些访问、更改或增加ndarray中某一元素的基础方法。
类似于访问python list中元素的方式,按照元素的index进行访问或更改。
1 | #访问某一元素,这里可以自己多尝试,摸索 |
可使用np.delete(ndarray, elements, axis)
函数进行删除操作。
这里需要注意的是axis
这个参数,课程中只讲到了2维数据中,axis = 0
表示选择行
,axis = 1
表示选择列
,但不能机械的认为0就表示行,1就表示列,注意前提2维数据中。
在三维数据中,axis = 0表示组,1表示行,2表示列。这是为什么呢?提示一下,三位数组的shape中组、行和列是怎样排序的?
所以,axis的赋值一定要考虑数组的shape。
1 | a = np.arange(12).reshape(2,2,3) |
再有一点需要注意的是,如果你想让原数据保留删除后的结果,需要重新替换一下才可以。
1 | a = np.arange(6).reshape(2,3) |
往ndarray中增加元素的办法跟python list也很类似,常用的有两种:
一种是添加(append),就是将新增的元素添加到ndarray的尾部
np.append(ndarray, elements, axis)
一种是插入(insert),可以让新增元素插入到指定位置
np.insert(ndarray, index, elements, axis)
index
,指示的是插入新元素的位置。这里值得注意的是,不论是append还是insert,在往多维数组中插入元素时,一定要注意对应axis上的shape要一致。再一个就是,和delete一样,如果你想要更改原数据,需要用a = np.append(a,elements,axis)
。
前面学了选择ndarray中的某个元素的方法,这里我们学习选择ndarray子集的方法——切片。
对于切片大家并不陌生,在list里面我们也接触过切片,一维的ndarray切片与list无异。需要注意的是,就是理解2维及多维ndarray切片。
1 | a = np.arange(4*4).reshape(4,4) |
这里可以看出,我们筛选了a矩阵中前三列的所有行,这是如何实现的呢?
切片的第一个元素:
表示的是选择所有行,第二个元素:-1
表示的是从第0列至最后一列(不包含),所以结果如上所示。
再看一个例子:
1 | a[1:3,:] |
筛选的是第2-3行的所有列。
以列的形式获取最后一列数据:
1 | a[:,3:] |
以一维数组的形式获取最后一列数据:
1 | a[:,-1] |
上面两种方法经常会用到,前者的shape为(4,1),后者为(4,)。
所用函数为np.diag(ndarray, k=N)
,其中参数k的取值决定了按照哪一条对角线选择数据。
默认k = 0,取主对角线;
k = 1时,取主对角线上面1行的元素;
k = -1时,取主对角线下面1行的元素。
思考:这个函数只能选择主对角线上的元素,那如果想要获取副对角线上的元素呢?
尝试自己搜索一下关键词numpy opposite diagonal
寻找答案。
不建议你直接点getting the opposite diagonal of a numpy array。
所用函数为np.unique(ndarray)
,注意unique也可以添加参数axis来控制评判唯一值的轴方向,不好理解可以看示例:
1 | a = [[0,1,2], |
这里在中括号中添加筛选条件,当该条件的结果为True时(即满足条件时),返回该值。
1 | X[X > 10] #筛选数组X中大于10的数据 |
这里需要注意的是,当输入多个筛选条件时,&
表示与,|
表示或,~
表示非。
1 | np.intersect1d(x,y) #取x与y的交集 |
我们可以通过+
、-
、*
、/
或np.add
、np.substract
、 np.multiply
、np.divide
来对两个矩阵进行元素级的加减乘除运算,因为是元素级的运算,所以两个矩阵的shape必须要严格一致。
上面涉及到的乘法是元素对应相乘,也就是点乘,那矩阵的叉乘呢?可以了解下numpy.matmul函数。
这里需要注意的是,课程中讲的“可广播”,其实指的就是A和B两个矩阵shape可能不一致,但是A可以拆分为整数个与B具有相同shape的矩阵,这样在进行元素级别的运算时,就会先将A进行拆分,然后与B进行运算,结果再组合一起就可以。这里的A就是“可广播”矩阵。
我们使用np.sort()
和ndarray.sort()
来对ndarray进行排序。
相同的是:
二者都可以使用参数axis
来决定依照哪个轴进行排序,axis = 0时按照列排序,axis = 1时按照行排序;
不同的是:
np.sort()
不会更改原数组;ndarray.sort()
会更改原数组。
这里涉及到一个概念,叫做数据标准化。
数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。
有很多种对数据进行标准化处理的方法,我们课程中选择的是利用数据均值和标准差进行标准化:
对某一列中某一值进行标准化就是将该值减去该列的平均值,然后除以该列的标准差。标准化后的序列,均值为0,标准差为1,且无量纲。
标准化后的数据,没有量纲,方便计算和比较,在机器学习中的很多算法都需要将数据进行标准化。
但是基于本章的要求,我们主要是学习numpy的基本操作即可,具体的数据标准化还有算法可以之后在机器学习课程中学习。
这里需要注意的是:
np.random.permutation()
np.random.permutation(N)
函数会创建一个从 0 到 N - 1
的随机排列的整数集。这个整数集也是ndarray类型。
1 | np.random.permutation(5) |
这里的切分有两点隐形要求:
1.随机性,三个数据集中的数据必须是随机分配的;
2.三个数据集的合集必须为数据集。
考虑到上面学到的`np.random.permutation()` 函数,所以我们的思路可以是这样的:1. 使用`permutation()`函数,将数据集的行数当作N,这样就可以得到一个随机排列的行索引序列;2. 使用切片,将刚才的随机行索引序列,按照训练集、测试集和交叉集的比例`6:2:2`进行切分;3. 使用索引访问,获取切分后的数据,即`ndarray[index]`的方式。
Pandas 是 Python 中的数据操纵和分析软件包,它是基于Numpy去开发的,所以Pandas的数据处理速度也很快,而且Numpy中的有些函数在Pandas中也能使用,方法也类似。
Pandas 为 Python 带来了两个新的数据结构,即 Pandas Series(可类比于表格中的某一列)和 Pandas DataFrame(可类比于表格)。借助这两个数据结构,我们能够轻松直观地处理带标签数据和关系数据。
Series中各个元素的数据类型可以不一致,DataFrame也是如此,这与numpy的ndarray不同。
可以使用 pd.Series(data, index)
命令创建 Pandas Series,其中data
表示输入数据, index
为对应数据的索引,除此之外,我们还可以添加参数dtype
来设置该列的数据类型。
示例:
1 | import pandas as pd |
data
除了可以输入列表之外,还可以输入字典,或者是直接一个标量。
1 | #data输入字典 |
访问Series中的元素有两种方法:
一种类似于从列表中按照索引访问数据,一种类似于从字典中按照key来访问value。
下面看示例:
从上面代码里也能发现,Pandas提供的iloc
与loc
分别对应着按索引访问和按key访问。
因为Series是可更改类型,若想更改其中某一项,只需访问它然后重新赋值即可。
可以使用 .drop()
方法删除 Pandas Series 中的条目。Series.drop(label)
方法会从给定 Series
中删除给定的 label
。这个label
可以是单个label或这是label组成的list。
但需要注意的是,.drop()
函数并不会修改原来的数据,如果你想要修改原数据的话,可以选择添加参数inplace = True
或者是用原数据替换s = s.drop(label)
和ndarray一样,Series也可以进行元素级的算术运算,也可以使用np中提供的各种运算函数,如sqrt()
等等。
这里可以想一下,如果Series中包含字符串,然后再进行乘法会是什么结果?
可以回想下字符串的知识'*'*10
的结果是什么?
我们使用pd.DataFrame(data, index, columns)
来创建一个DataFrame。
其中:
data
是数据,可以输入ndarray,或者是字典(字典中可以包含Series或arrays或),或者是DataFrame;
index
是索引,输入列表,如果没有设置该参数,会默认以0开始往下计数;
columns
是列名,输入列表,如果没有设置该参数,会默认以0开始往右计数;
示例:
从上述代码中可以看出,字典d
中的key
被当作列名,value
被当作dataframe中的数据。
思考:如果在上述代码中添加一个columns列,如df = pd.DataFrame(data=d,index = ['a','b'],columns = ['col_1','col_2'])
,会返回什么结果呢?
与访问Series中的元素类似,我们可以通过列表式索引访问,也可以通过字典式Key值访问。
使用df.iloc[:,0:2]这种方法只能筛选出连续的列,那如果想要筛选的列分别在1,3,5,10:17怎么办呢?可以搜一下
np.r_
的用法。
我们使用.drop
函数删除元素,默认为删除行,添加参数axis = 1
来删除列。
值得注意的是,drop
函数不会修改原数据,如果想直接对原数据进行修改的话,可以选择添加参数inplace = True
或用原变量名重新赋值替换。
这里介绍了两种方法,一种是append()
,另外一种是insert()
,这两种方法都比较简单,可类比于python list中的两种方法进行学习。
此外,Pandas还提供了其他更为复杂的做DataFrame融合的函数,比如说concat()
、merge()
、join()
等等,相对难理解一些,我会单独出一份导学详细介绍这几个数据融合函数。
使用函数rename()
即可。具体用法如下:
除此之外,还可以使用隐匿函数lambda来对行列标签进行统一处理,比如:
需要注意的是,rename()
函数同样不会更改原数据,如果想直接对原数据进行修改的话,可以选择添加参数inplace = True
或用原变量名重新赋值替换。
可以使用函数set_index(index_label)
,将数据集的index设置为index_label
。
除此之外,还可以使用函数reset_index()
重置数据集的index为0开始计数的数列。
NaN
就是Not a Number的缩写,表示这里有数据缺失。
我们可以使用isnull()
和notnull()
函数来查看数据集中是否存在缺失数据,在该函数后面添加sum()
函数来对缺失数量进行统计。除此之外,还可以使用count()
函数对非NaN数据进行统计计数。
使用dropna(axis)
函数可以删除包含NaN的行或列。
dropna()
函数还有一个参数是how
,当how = all
时,只会删除全部数据都为NaN的列或行。
同样,该函数也不会修改原数据集。
使用fillna()
函数可以替换NaN为某一值。其参数如下:
ffill
前向填充,一种是backfill
后向填充一般来说,我们常用均值去替换NaN。
还可以使用interpolate()
函数按照某一方法来替换NaN,课程中介绍了method为linear
时的用法,即忽略索引并将值视为相等间距,这是该函数的默认方法。更多method及解读请戳pandas.DataFrame.interpolate
1 | df = pd.read_csv(filename) #读取csv文件 |
本首是Python项目的第2周,主要还是理解项目和准备项目文件,请大家做到以下几点:
Project2/week1的项目要求:(应该已经做完)
Project2/week2的项目要求 (本周要求和,做完了画第二个勾勾)
点击下载链接,先选择你的操作系统,然后选择Python 3.7 version
版本下载。
安装过程中,记得这里的两个框,都勾选上。
安装完Anaconda之后,Windows用户可以通过开始
-所有程序
找到Anaconda
的文件夹,在文件夹下有三个程序是你经常会用到的,分别是:
Anaconda Prompt:这里就是Anaconda的控制台,你进行第三方包的管理和编程环境的管理都是在这里进行。但是现阶段用不到。
Jupyter Notebook:使用非常非常频繁的web文档,在项目三和项目四中都会用到。
Spyder:python的IDE(集成开发环境),在项目二中会用到。
notebook的使用技巧在教室内说得很详细了,这里只补充一点,那就是如何在你工作的文件夹下使用notebook。
Shift
键,然后右击,选择“在此处打开命令窗口”注意:不要关掉弹出notebook的命令窗口,这是将notebook与你电脑内的python链接的纽带。
我们将会在项目二中用到Spyder这个软件,这个软件也没什么操作难度,所以课程内没有讲解。
我在这里给大家具体讲一下吧。
Windows用户依次点击开始
-所有程序
-Anaconda
-Spyder
即可。
如上,我们可以把Spyder的界面划分为5个部分,分别为:
菜单栏:就是一些新建、打开、运行、终止等等操作,自行摸索
选择工作区:这里可以选择工作区路径
代码编辑区:这里就是你写代码的地方
程序变量/文件路径查看区:通过选择箭头标注的选项卡,可以显示代码中的变量,或者是当前路径下的文件
控制台:这里就是显示你代码运行结果的地方,如果代码运行卡住了,可以通过点该区域右上角的■
终止运行。
先确定工作路径,然后新建脚本,开始编写代码、运行(快捷键F5)、调试。
做完项目二,大家就能熟练操作啦,不要担心~
]]>Mini-Batch Gradient Descent是介于batch gradient descent(BGD)和stochastic gradient descent(SGD)之间的一种线性回归优化算法,它是将数据分为多个小的数据集(batches),每个数据集具有大致相同的点数,然后在每个数据集中应用Absolute Trick或者是Square Trick算法,来更新回归系数。
它的运算速度比BSD快,比SGD慢;精度比BSD低,比SGD高。
1 | import numpy as np |
在结果中,颜色最浅的是最开始的回归线,最深的则为最终的回归线。
理论知识参见Linear Regression 总结,这里只对代码中出现的新函数或新用法进行讲解。
该函数用来计算两个arrays的乘积。
需要注意的是,由于a和b维度的不同,会使得函数的结果计算方式不同,一共三种:
如果a和b都是2维的,则做普通矩阵乘法
1 | a = [[1, 0], [0, 1]] |
1 | out: |
如果a和b中有一个是大于2维的,则会将其理解为多个矩阵stack后的结果,进行计算时也会进行相应的拆分运算
1 | a = np.arange(2*2*4).reshape((2,2,4)) |
1 | out: |
a被理解为2个2x4矩阵的stack
1 | array([[[ 0, 1, 2, 3], |
b被理解为2个4x2矩阵的stack
1 | array([[[ 0, 1], |
np.matmul(a,b)
会将a中的两个矩阵与b中的两个矩阵对应相乘,每对相乘的结果都是一个2x2的矩阵,所以结果就是一个2x2x2的矩阵。
如果a或b有一个是一维的,那么就会为该一维数组补充1列或1行,进而提升为二维矩阵,然后用非补充行或列去和另外一个二维矩阵进行运算,得到的结果再将补充的1去掉。(这个是最难理解的,可以多测试下,用代码结果理解)
1 | a = [[1, 0], [0, 1]] |
1 | out: |
a是一个2x2的矩阵,b是一个shape为(2,)的一维数组,那么matmul的计算步骤如下:
我们试着将a与b的顺序对调,看一下matmul是怎么计算的:
我们先来看看numpy.stack()
函数。
这个函数中的axis有些抽象,我们看具体示例:
结果的排版有点问题,为了方便后面对照,把结果对齐如下:
1 | [ |
axis = 0,则按照第0个维度组
进行堆叠,即:
结果为:
axis = 1,则按照第1个维度行
进行堆叠,即:
结果为:
axis = 2,则按照第二个维度列
进行堆叠,即:
结果为:
这个基本很少用到。
**numpy.hstack()**函数就是horizontal(水平)方向的堆叠,示例:
**numpy.vstack()**函数就是在垂直方向堆叠。
一维ndarray的切片方式和list无异,这里主要讲一下二维矩阵的切片方法。
1 | a = np.arange(4*4).reshape(4,4) |
1 | out: |
1 | a[:,:-1] |
1 | out: |
这里可以看出,我们筛选了a矩阵中前三列的所有行,这是如何实现的呢?
切片的第一个元素:
表示的是选择所有行,第二个元素:-1
表示的是从第0列至最后一列(不包含),所以结果如上所示。
再看一个例子:
1 | a[1:3,:] |
1 | out: |
筛选的是第2-3行的所有列。
以列的形式获取最后一列数据:
1 | a[:,3:] |
1 | out: |
以一维数组的形式获取最后一列数据:
1 | a[:,-1] |
1 | out: |
上面两种方法经常会用到,前者的shape为(4,1),后者为(4,)。
color
代码中涉及到的语句为:
1 | color = [1 - 0.92 ** counter for _ in range(3)] |
matplotlib中的color可以输入RGB格式,即[R,G,B],这里值得注意的是它们的取值范围都在0到1之间,其中[0,0,0]为黑色,[1,1,1]为白色。
在如上语句中,列表由三个相等的数值元素组成,保证了颜色为白-灰-黑,数值随着counter的减小,由1趋近于0,反映在可视化上就是颜色由白逐渐变黑。
这真是一个画渐变过程的好方法呀!!!
plot([x_1,x_2],[y_1,y_2])
这里就是两点式绘图,根据点(x_1,y_1)和点(x_2,y_2)画一条直线。
zorder
也就是z-order,类似于PS里面的图层顺序,下面的图层会被上面的图层遮挡。
参考Zorder Demo中队zorder的介绍,可以知道,zorder越大,图层越靠上,所以在上面的代码中,我们在scatter中设定zorder为3,也就是最上层,这样就可以保证渐变的回归线不会压在散点图上面了。
If you want your life to be a magnificent story, then begin by realising that you are the author.
本文就Udacity数据分析入门课程中的SQL入门(P1阶段)和SQL进阶(P3阶段)的知识点进行总结。SQL的主要功能不外乎增、删、改、查四个,对于数据分析师来说,只需要掌握查就可以了。(因为增删改往往超出了数据分析师的职能范围)
注意:本文是总结性质的,只能提供复习或者速查的功能,讲解得不会很详细,若想学习,还是要在教室内逐章学习。
SQL是Structured Query Language的简写,也就是结构化查询语言。SQL 最受欢迎的功能是与数据库交互。
使用传统关系数据库与 SQL 交互有一些主要优点。最明显的 5 个优点是:
为什么企业喜欢使用数据库
SQL 与 NoSQL
你可能听说过 NoSQL,它表示 Not only SQL(不仅仅是 SQL)。使用 NoSQL 的数据库时,你编写的数据交互代码会与本节课所介绍的方式有所不同。NoSQL 更适用于基于网络数据的环境,而不太适用于我们现在要介绍的基于电子表格的数据分析。最常用的 NoSQL 语言之一是 MongoDB。
_
替代。;
行内注释
使用两个连字符-,添加注释。
1 | SELECT col_name -- 这是一条注释 |
多行注释
多行注释以/*
起始,以*/
结尾。
1 | /*SELECT col_name |
检索数据主要用的语句为:SELECT。
1 | SELECT col_name |
从table_name表中检索col_name列。
1 | SELECT col_1,col_2,col_3 |
从table_name表中检索col_1,col_2和col_3列。
1 | SELECT * |
使用通配符*
,返回table_name表中的所有列;
1 | SELECT DISTINCT col_1 |
检索col_1中具有唯一性的行,即唯一值。
使用LIMIT语句可以限制返回的行数。
1 | SELECT col_1 |
返回前10行(即第0-第9行)。
也可以添加OFFSET语句,设置返回数据的起始行:
1 | SELECT col_1 |
从第五行之后,返回十行数据(即第5-第14行)。
ORDER BY 语句用于根据指定的单列或多列对结果集进行排序。
ORDER BY 语句默认按照升序对记录进行排序。(从小到大,从a到z)
如果您希望按照降序对记录进行排序,可以使用 DESC 关键字。
在指定一条ORDER BY子句时,应该保证它是SELECT语句中的最后一条子句。
1 | SELECT col_name |
返回的数据会按照col_name列进行升序排序,这里col_name可以是单列也可以是多列,当然也可以使用非检索的列进行排序。
1 | SELECT col_1,col_2 |
返回的数据会按照col_2列降序,col_3列升序对col_1和col_2两列进行排序。
这里可以看出,DESC关键字的用法:只对跟在语句前面的变量有效。所以,想要对多列进行降序排序时,需要对每一列都指定DESC关键字。
WHERE子句应该在表名(即FROM子句)之后给出。
WHERE子句应在ORDER BY子句之前。
在过滤条件中的value是区分大小写的。
1 | SELECT col_1 |
运算符 | 描述 |
---|---|
= | 等于 |
<> | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN…AND… | 在指定的两值之间 |
IS NULL | 为NULL值 |
AND | 逻辑运算符:与 |
OR | 逻辑运算符:或 |
IN | 制定条件范围筛选,可以简化OR的工作 |
NOT | 逻辑运算符:非 |
注意:
- SQL的版本不同,可能导致某些运算符不同(如不等于可以用!=表示),具体要查阅数据库文档。
- 在同时输入AND和OR时,SQL会优先处理AND语句,你可以使用小括号来进行分组操作。
通配符是用来匹配值的一部分的特殊字符,跟在LIKE关键字后面进行数据过滤
通配符 | 描述 |
---|---|
% | 表示任何字符出现任意次数 |
_ | 表示任何字符出现一次 |
[] | 指定一个字符集,它必须匹配该位置的一个字符 |
^ | 在[]中使用,表示否定 |
示例:
1 | SELECT col_1 |
如上筛选出的是,第二个字符为非J或M的数据。
其实就是在检索数据的同时进行计算,并使用关键字AS将结果保存为某一列。
1 | SELECT prod_id,quantity,item_price,quantity*item_price AS expanded_price |
输出:
1 | prod_id quantity item_price expanded_price |
这里实现的就是使用quantity*item_price创建一个名为expanded_price的计算字段,也就是一个新列。
同样适用于计算的操作符有+
(加),-
(减)和/
(除)。
1 | SELECT RTRIM(col_name) + '('+RTRIM(col_country)+')' AS col_title |
输出:
1 | col_title |
这里实现的就是将col_name列与col_country列进行了拼接,新列的名字叫做col_title。
RTRIM()函数是去掉右边的所有空格,LTRIM()是去掉左边的所有空格,TRIM()是去掉两边的所有空格。
在上一节中我们使用AS来为变量设置别名,你可能也见过如下所示的语句:
1 | SELECT col1 + col2 AS total, col3 |
当然没有 AS 的语句也可以实现使用别名:
1 | FROM tablename t1 |
以及
1 | SELECT col1 + col2 total, col3 |
将col1+col2的结果设置名为total的列。
语句 | 使用方法 | 其他详细信息 |
---|---|---|
SELECT | SELECT Col1, Col2, … | 提供你需要的列 |
FROM | FROM Table | 提供列所在的表格 |
LIMIT | LIMIT 10 | 限制返回的行数 |
ORDER BY | ORDER BY Col | 根据列命令表格。与 DESC 一起使用。 |
WHERE | WHERE Col > 5 | 用于过滤结果的一个条件语句 |
LIKE | WHERE Col LIKE ‘%me%’ | 仅提取出列文本中具有 ‘me’ 的行 |
IN | WHERE Col IN (‘Y’, ‘N’) | 仅过滤行对应的列为 ‘Y’ 或 ‘N’ |
NOT | WHERE Col NOT IN (‘Y’, “N’) | NOT 经常与 LIKE 和 IN 一起使用。 |
AND | WHERE Col1 > 5 AND Col2 < 3 | 过滤两个或多个条件必须为真的行 |
OR | WHERE Col1 > 5 OR Col2 < 3 | 过滤一个条件必须为真的行 |
BETWEEN | WHERE Col BETWEEN 3 AND 5 | 一般情况下,语法比使用 AND 简单一些 |
SQL最强大的功能之一就是能在数据查询的执行中进行表的链接(JOIN)。
在关系数据库中,将数据分解为多个表能更有效地存储,更方便地处理,但这些数据储存在多个表中,怎样用一条SELECT语句就检索出数据呢?那就要使用链接。
创建链接的方式很简单,如下便是使用WHERE创建链接:
1 | SELECT col_1,col_2,col_3 |
如上,col_1和col_2属于table_1表中,col_3属于table_2表中,而这两个表使用相同的id列进行匹配。这种方法被称为等值链接,也就是内链接,我们可以使用如下的语句,更直观地实现内连接:
1 | SELECT col_1,col_2,col_3 |
当然你也可以使用别名,简化输入,并且标明各列与表的隶属关系:
1 | SELECT t1.col_1,t1.col_2,t2.col_3 |
如上代码同样适用于左链接、右链接和外链接:
LEFT JOIN - 用于获取 FROM 中的表格中的所有行,即使它们不存在于 JOIN 语句中。
RIGHT JOIN - 用于获取 JOIN 中的表格中的所有行,即使它们不存在于 FROM 语句中。
FULL JOIN: 只要其中一个表中存在匹配,就返回行。
自链接经常用于对子查询的简化,如下示例:
假如要给Jim同一公司的所有顾客发送一封邮件,需要你先筛选出Jim的公司,然后再根据该公司筛选出所有的顾客。使用子查询的方式如下:
1 | SELECT cust_id,cust_name,cust_contact |
如果改为自链接的方式如下:
1 | SELECT c1.cust_id,c1.cust_name,c1.cust_contact |
结果是一样的,但是使用自链接的处理速度比子查询要快得多。
UNION 操作符用于合并两个或多个 SELECT 语句的结果集,使用方法也很简单,只要在多条SELECT语句中添加UNION关键字即可。
多数情况下,组合相同表的多个查询所完成的任务与具有多个WHERE子句的一个查询是一样的。
注意:UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。而且UNION返回的结果只会选取不同的值(即唯一值)。
使用UNION的场合情况:
示例:如下三个语句的结果是一致的。
1 | -- 查询一 |
1 | SELECT cust_name,cust_email |
在最后添加了ORDER BY对所有SELECT语句进行排序,这里只是为了示例在使用UNION时如何进行排序。
1 | SELECT cust_name,cust_email |
这里看起来使用UNION比WHERE更复杂,但对于较复杂的筛选条件,或者从多个表中检索数据时,使用UNION更简单一些。
有时候我们只是需要获取数据的汇总信息,比如说行数啊、平均值啊这种,并不需要吧所有数据都检索出来,为此,SQL提供了专门的函数,这也是SQL最强大功能之一。
SQL的聚合函数如下所示:
函数 | 说明 |
---|---|
AVG() | 返回某列的均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列的和 |
使用示例:
1 | SELECT AVG(col_1) AS avg_col_1 |
注意:聚合函数都会忽略列中的NULL值,但是COUNT(*)也就是统计全部数据的行数时,不会忽略NULL值。
当添加DISTINCT参数时,就可以只对不同值(也就是某列中的唯一值)进行函数操作。
使用示例:
1 | SELECT AVG(DISTINCT col_1) AS avg_col_1 |
前面的函数操作都是基于整个表去进行的,那如果想要依据某列中的不同类别(比如说不同品牌 不同性别等等)进行分类统计时,就要用到数据分组,在SQL中数据分组是使用GROUP BY子句建立的。
在使用GROUP BY时需要注意的几点:
使用示例:
1 | SELECT col_1,COUNT(*) AS num_col |
以上即可实现按col_1列中的不同类目进行行数统计。
在SQL入门中我们学过WHERE,它是对行数据进行筛选过滤的,那么,如果我想对创建的分组数据进行筛选过滤呢?这时候,你就要用到HAVING子句了,它与WHERE的操作符一致,只是换了关键字而已。
使用示例:
1 | SELECT col_1,COUNT(*) AS num_col |
这里我们就筛选出了具有两个以上类别的分组。
注意:使用HAVING时应该结合GROUP BY子句。
在SQL中有一套专门的内置函数,用来处理时间序列,那就是DATE函数。
先了解一下在不同的数据库中的时间序列的表示。(了解即可)
MySQL 使用下列数据类型在数据库中存储日期或日期/时间值:
SQL Server 使用下列数据类型在数据库中存储日期或日期/时间值:
DATE_TRUNC 使你能够将日期截取到日期时间列的特定部分。常见的截取依据包括日期
、月份
和 年份
。
语法:
1 | DATE_TRUNC('datepart', timestamp) |
其中datepart
即为你的截取依据,后面的timestamp类型可以参考上面的Date数据类型。
我总结了一份SQL的
datepart
速查表放在了下面。
使用示例:
1 | SELECT DATE_TRUNC('y',col_date) col_year |
如上,我们将col_date列按照年(’y’)进行了分组,并按由大至小的顺序排序,取前10组数据。
DATE_PART 可以用来获取日期的特定部分,如获取日期2018-10-6的月份,只会获得一个结果6,这是它与DATE_TRUNC的最大区别。
语法:
1 | DATE_PART ('datepart', date或timestamp) |
其中datepart
即为你的截取依据,后面的timestamp类型可以参考上面的Date数据类型。
使用示例:
1 | SELECT DATE_PART('y',col_date) col_year |
如上,我们筛选了col_date列的年份,并依据它做了分组。
想了解更多DATE函数,可以戳SQL日期和时间函数参考
如下给了很多的缩写,只记住最简单的即可。
日期部分或时间部分 | 缩写 |
---|---|
世纪 | c、cent、cents |
十年 | dec、decs |
年 | y、yr、yrs |
季度 | qtr、qtrs |
月 | mon、mons |
周 | w,与 DATE_TRUNC一起使用时将返回离时间戳最近的一个星期一的日期。 |
一周中的日 ( DATE_PART支持) | dayofweek、dow、dw、weekday 返回 0–6 的整数(星期日是0,星期六是6)。 |
一年中的日 ( DATE_PART支持) | dayofyear、doy、dy、yearday |
日 | d |
小时 | h、hr、hrs |
分钟 | m、min、mins |
秒 | s、sec、secs |
毫秒 | ms、msec、msecs、msecond、mseconds、millisec、millisecs、millisecon |
CASE语句其实就相当于python中的if语句,是用来做条件的。
需要注意的几点:
使用示例:
1 | SELECT account_id, CASE WHEN standard_qty = 0 OR standard_qty IS NULL THEN 0 |
如上,我们使用CASE WHEN.(条件一).THEN.(条件一的结果).ELSE.(其他不符合条件一的结果).END语句,设立的两个条件,即当standard_qty为0或者不存在时我们返回0,当standard_qty不为0时进行计算,并储存为新列unit_price。
我们之前所涉及到的都是从数据库表中检索数据的单条语句,但当我们想要检索的数据并不能直接从数据库表中获取,而是需要从筛选后的表格中再度去查询时,就要用到子查询和临时表格了。
子查询与临时表格所完成的任务是一致的,只不过子查询是通过嵌套查询完成,而另一种是通过WITH创建临时表格进行查询。
构建子查询十分简单,只需将被查询的语句放在小括号里,进行嵌套即可,但在使用时一定要注意格式要清晰。
使用示例:
1 | SELECT * |
如上,我们创建了一个子查询,放在小括号里,并将其命名为sub。在子查询中也注意到了各个子句上下对齐,这样条例更清晰。
这种方法,就是使用WITH将子查询的部分创建为一个临时表格,然后再进行查询即可。
我们还是使用上面子查询的例子,这次用临时表格的形式实现:
1 | WITH sub AS( |
如上,我们将被嵌套的子查询单独拎出来,用WITH创建了一个临时表格,再之后又使用SELECT根据该表格进行查询。
这一节主要针对数据清理讲解了几个SQL中的常用函数,一般来说,也都是用在筛选阶段,更详尽的数据清理还是要放在python中去进行。
LEFT和RIGHT相当于是字符串截取,LEFT 是从左侧起点开始,从特定列中的每行获取一定数量的字符,而RIGHT是从右侧。
LENGTH就是获取字符串的长度,相当于python中的len()。
语法:
1 | LEFT(phone_number, 3) -- 返回从左侧数,前三个字符 |
这三个函数都是与位置相关的函数。
POSITION 和STRPOS 可以获取某一字符在字符串中的位置,这个位置是从左开始计数,最左侧第一个字符位置为1,但他俩的语法稍有不同。
SUBSTR可以筛选出指定位置后指定数量的字符。
语法:
1 | POSITION(',' IN city_state) |
顾名思义,就是将两个字符串进行拼接。
语法:
1 | CONCAT(first_name, ' ', last_name) -- 结果为:first_name last_name |
TO_DATE函数可以将某列转为DATE格式,主要是将单独的月份或者年份等等转换为SQL可以读懂的DATE类型数据。
语法:
1 | TO_DATE(col_name,'datepart') |
这里是将col_name这列按照datepart转化为DATE类型的数据,datepart可以参考之前的总结。
CAST函数是SQL中进行数据类型转换的函数,但经常用于将字符串类型转换为时间类型。
语法:
1 | CAST(date_column AS DATE) |
这里是将date_column转换为DATE格式的数据,其他时间相关的数据类型与样式对照可以参考上面写过的SQL Date数据类型,确保你想转换的数据样式与数据类型对应。
之前有提到过如何筛选出缺失值,即使用WHERE加上IS NULL或者IS NOT NULL。
那么如何对缺失值进行处理呢?(其实这里可以直接无视,筛选出来后在python中再进行处理)
SQL中提供了一个替换NULL值的函数COALESCE。
使用示例:
1 | COALESCE(col_1,0) -- 将col_1中的NULL值替换为0 |
好啦,至此课程中的所有SQL知识点已经总结完了,并且也给大家做了适当的补充,希望大家能够用得上。未来的数据分析师之路,还要继续加油呀!
下表中列出了全文中涉及到的子句,在进行使用时,应严格遵循下表中从上至下的顺序。
子句 | 说明 | 是否必须使用 |
---|---|---|
SELECT | 要返回的列或表达式 | 是 |
FROM | 用于检索数据的表 | 仅在从表中选择数据时使用 |
JOIN…ON… | 用于链接表 | 仅在需要链接表时使用 |
WHERE | 过滤行数据 | 否 |
GROUP BY | 分组数据 | 仅在按组计算时使用 |
HAVING | 过滤分组 | 否 |
ORDER BY | 对输出进行排序 | 否 |
LIMIT | 限制输出的行数 | 否 |
Better together . —— Udacity
Hi,同学们,经过前两周的学习,我们掌握了描述统计学基础、概率论基础、推论统计学中的置信区间、假设检验以及机器学习入门知识——回归,本章的内容偏理论性更多一些,需要更多得去实操来加强自己的理解能力,这周呢我们就来个实打实的项目来检验前两周的所学。项目为分析A/B测试结果,在开始项目前,请一定要把前面的几个小测试做了,这样做项目更好上手一些。大家加油!通过这个项目,就可以拿到入门的毕业证啦!!!
项目四(P4)阶段总共包含三周,在这三周内,我们要对统计学进行学习,掌握基础的描述统计学理论、基本的概率知识、二项分布和贝叶斯公式,并学会使用 Python 来实践;学习正态分布、抽样分布、置信区间以及假设检验的概念和计算方式;学习线性回归以及逻辑回归,在真实场景中应用,比如分析 A/B 测试结果,搭建简单的监督机器学习模型。可谓是时间紧任务重,但是也别怕,统计学的基础知识还是非常简单的,跟着课程内容一步步来,自己多做笔记多查资料,一定没问题的!
那么我们的课程安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 统计学基础 | 描述统计学 - 抽样分布与中心极限定理 |
第2周 | 统计学进阶 | 置信区间 - 逻辑回归 |
第3周 | 完成项目 | 项目:分析A/B测试结果 |
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
完成并通过项目四!
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 项目四 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
数据分析师和数据学家经常使用 A/B 测试。在这个项目中,你将会理解电子商务网站运营 A/B 测试的结果。你的目标是通过课程中给的Jupyter Notebook,帮助公司理解他们是否应该设计新页面、保留原有网页或延长测试时间以便做出决定。
项目前面的几个小测试,需要大家针对项目提供的数据进行操作并回答,你可以打开两个网页,也可以在本地进行操作。
当然还是建议大家下载到本地进行操作,如果文件下载失败,请微信联系我。
关于A/B-test:
AB 测试就是为了验证在先验条件的存在的情况下,进行新的变更是否合理和可行以达到优化的目的。使用 AB 测试的方式能能够度量变更对某些指标的变化,是变更更具有合理性依据更充分。
AB 测试也存在 不适用的场景:1)对没有明确参照的试验,AB 测试是基于先验条件的优化,如果没有一个参照对比是无法进行测试。2)数据获取时间长,AB 测试一般都是进行小规模快速的试验,所以对于数据获取的单周期较长的试验不太适用。
影响测试效果的因素:1)新奇效应:即
Novelty Effect
指老用户可能会觉得变化很新鲜,受变化吸引而偏爱新版本,哪怕从长远看来新版本并无益处。2)抗拒改变心理:即Change Aversion
老用户可能会因为纯粹不喜欢改变而偏爱旧版本,哪怕从长远来看新版本更好。
在课程项目中,我们分成了三块涵盖了本章的所有知识点,这三块分别为:
如果在项目进行中,有知识点遗漏或忘记的地方,可以去查看相关课程视频或者导学,之后,记在你的小本本上。
本节的问题都相对比较简单,所以在导学中不过多赘述了。
这里没什么难度,基本的pandas知识,如果这节有什么问题的话,请查看第六周导学并面壁十分钟-。-
如果非要提醒一下的话,那就是在问题e.
new_page
与treatment
不一致的次数中,不要忘了也看看old_page与control的不一致次数,二者相加才是结果。
这里只说一点,就是如何在Jupyter Notebook中使用公式的问题,其实也就是如何在Markdown中使用公式的问题,你只需要按照如下步骤即可:
打开Latex公式在线转换,输入好公式后,复制代码
将你想要输入公式的代码框,转为Markdown格式;
输入两个美元符号,即$$;
将刚复制的公式代码粘贴到两个美元符号中间,然后运行该代码框即可。
录了一个gif在下面,可以参考下:
注意题干中给的要求是:假定在零假设中,不管是新页面还是旧页面, pnew 和 pold 都具有等于 转化 成功率的“真”成功率,也就是说, pnew 与 pold是相等的。此外,假设它们都等于ab_data.csv 中的 转化 率,新旧页面都是如此。
也就是:p_new = p_old = p_ab_data
注意:这并不意味着零假设就是p_new = p_old,可以从后续的c-g步骤能看出,零假设为p_new - p_old ≤ 0
这里的n_new与n_old就是对ab_data中使用新旧页面的用户数量进行统计。
使用numpy.random.choice函数,将零假设中的p_new与p_old作为抽样概率,n_new与n_old作为抽样次数,用1表示‘转化成功’,0表示‘未转化成功’,并将结果储存在一个新变量当中。
示例:
1 | new_page_converted = np.random.choice([0,1],n_new,p = [1-p_new,p_new]) |
以上获得的这个新变量,就是我们按照零假设中的n_new抽样n_new次的转化与否的分布模拟,那如何看模拟后的转化率呢?很简单,一个函数就搞定了,这里自己想。
这三步是使用for循环,将上面的过程不断重复10000次,获得一个抽样分布直方图,这个图会是正态分布吗?
关于实际观测值,即为你利用ab_data.csv直接计算得来的new_page与old_page转化率之差。
j中得到的值是什么呢?是不是在零假设的条件下,观察到实际观测值甚至更极端(更支持备择假设)的概率?那这个值的学名叫什么?
【这里实际上进行的是单尾检验,也就是对备择假设为p_new - p_old > 0来进行的】
使用了statsmodels中的proportions_ztest函数进行检验。实现的功能和上述a-j是一致的。
为什么要选择这个函数,以及这个函数的用法可以参考课程中给的链接proportions_ztest。
不过值得注意的是,在链接的列子中,使用的是双尾检验,也就是针对备择假设为p_new ≠ p_old去做的;但是在课程项目中,我们的备择假设为p_new > p_old,也就是单尾检验,所以函数中的某个参数要改一下。
使用内置函数方法获得的p值应该与前面获得的p值相近,如果差太多,那肯定是有地方需要再琢磨琢磨。
要想知道执行哪种类型的回归,就应该先看变量是属于数值变量还是分类变量,那题设中的变量是什么类型的变量呢?
要求是:创建一个 ab_page 列,当用户接收 treatment 时为1, control 时为0。所以在对group列使用get_dummies函数时,应该把生成的treatment列保存为ab_page列,而control列则应该被删掉。
注意的一点是:不要忘了添加截距。在进行结果解释的时候,我们并不关注截距,只是关注变量的coef系数和p值,先看p值是否具有显著性,若有再看coef系数,若没有,则该变量对因变量没有影响。
在思考零假设与备择假设之前,注意看结果中标红框的位置,想想这是什么意思,这说明在回归计算中,采用的是单尾检验还是双尾?单尾和双尾又分别对应的假设是什么?
数据集融合问题,之前单独出过一篇导学,如果忘了,请戳:Pandas数据融合,提醒下,合并时采用内连接,可以省去一些麻烦;
get_dummies,注意该函数生成数据的顺序是按照字典顺序来的,所以,你在进行操作时,为了确保顺序不乱,最好能先看一下生成的结果,再进行重命名。
大家能坚持到最后一个项目,十分不易,不过对于数据分析生涯来说,这只是你的开始,请继续保持这段时间的学习状态,如果非要给这个保持加一个期限的话,我希望是一辈子!大家加油!等你们的好消息!!
]]>Everything is difficult until you know how to do it.
Hi,同学们,上周我们学习了统计学基础知识,包括概率基础、描述统计学和推论统计学的基础知识,本周我们将会进一步学习推论统计学——置信区间&假设检验以及它们的应用之一A/B-test,在这之后,我们还会讲解一部分机器学习入门——线性回归&逻辑回归,与上周相比,这周我们会接触较深的理论知识,更多的代码,你可能会觉得学起来有些吃力,但请一定保持信心,你可以多次暂停观看课程中的讲解视频,跟着一起多动手,或者你也可以按照下面我给出的额外资料去查漏补缺,相信你们一定可以的!
项目四(P4)阶段总共包含三周,在这三周内,我们要对统计学进行学习,掌握基础的描述统计学理论、基本的概率知识、二项分布和贝叶斯公式,并学会使用 Python 来实践;学习正态分布、抽样分布、置信区间以及假设检验的概念和计算方式;学习线性回归以及逻辑回归,在真实场景中应用,比如分析 A/B 测试结果,搭建简单的监督机器学习模型。可谓是时间紧任务重,但是也别怕,统计学的基础知识还是非常简单的,跟着课程内容一步步来,自己多做笔记多查资料,一定没问题的!
那么我们的课程安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 统计学基础 | 描述统计学 - 抽样分布与中心极限定理 |
第2周 | 统计学进阶 | 置信区间 - 逻辑回归 |
第3周 | 完成项目 | 项目:分析A/B测试结果 |
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
学习课程中的置信区间 - 逻辑回归课程,掌握统计学进阶知识。
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 置信区间 - 逻辑回归 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
学习之前可以先回顾一下正态分布、抽样分布和中心极限定理的相关知识。
还记得上周用到的优达学生喝咖啡的数据吗?我们同样以此为例来探讨下置信区间是什么。
假设,优达的学生有数十万个(总体),而我们能获得的学生数据只有几百个(样本),我们通过做样本均值进行抽样分布,得到了一个近似正态分布的图形,但这也仅仅是样本的均值分布,也就是样本统计量。我们利用样本统计量的分布去构造总体均值(总体参数)的估计区间,就叫做置信区间。
置信区间的两种应用
刚才的举例中我们用得是“均值”,这算是利用抽样分布建立单个参数的置信区间,可以应用在单变量估计等方面;
你还可以计算两种分类之间均值的差,这就是两个参数的置信区间,可以用在两变量的对比(A/B-Test)上,比如说医学上不同药物的治疗效果,不同广告的吸金率,不同网页的点击率等等。
置信区间的显著性
统计显著性:即我们通过理论分析得到的结果。在统计学上用α表示,叫做显著性水平,它表达的是区间估计的不可靠概率。比如说,我们获取了95%的置信区间,那么显著性水平α = 1 - P = 5%。
一般的,显著性水平都要求达到5%即可,这在之后的假设检验中会学习到。
实际显著性:即我们除了理论分析得到的结果外,还要考虑实际情况,比如说你能有多少资金用于投资,或者你的网站承载力能达到多少等。
与传统置信区间方法的对比
传统的置信区间/假设检验方法有很多,比如说t-检验、双边t-检验等等,但是我们所掌握的自助取样法可以代替他们全部,当然有一个前提条件,那就是你的样本容量一定要足够大,如果你的样本容量实在是少,那就只能选择传统方法去处理了。
获取传统方法python代码的方法,请自行去Stackoverflow搜索。
准确性&可靠性
这里课程中翻译的有点儿晦涩,这里着重讲一下,我们以候选人A为例(在95%可靠性下具有34%±3%的支持率),大概分布可以如下所示:字丑就将就着点看吧。。。
课程中已经给出了很好的示例、问题及解答,在这里只是拎出一些面生的代码进行讲解。
1 | #设置随机种子,能保证结果之后可以复现 |
注意:置信区间和假设检验只关注的是总体参数,而不能对某一个体下结论。
刚才我们讲解了什么是置信区间——为了得到总体指标,使用样本统计量去估计总体参数——这是一个从样本出发去研究总体的过程。
我们现在换一个角度,在实际分析问题中,能否去假定总体参数,然后根据样本数据,去检验这种假定是否正确,从而实现对总体指标的分析?其实这种从总体出发,用样本尺度去检验实现对总体参数分析的过程,就叫做假设检验。
置信区间与假设检验的关系:从上面的表述可以看出,假设检验和置信区间在本质上是一致的。如果使用样本数据对总体参数进行估计,在一定的置信区间下,总体参数就应该落在这个区间,如果假设的总体参数不在该区间中,则就有理由拒绝该假设,这其实就是从置信区间的角度去完成了假设检验的工作内容。
名词解释
在实际工作中,我们不可能要求一个检验方法永远不出错,但可以要求尽可能地减少犯错误的概率。但在样本容量给定的条件下,两种错误发生的概率必是此消彼长,因此,我们通常是控制第一类错误的概率,使它不超过某一给定的值(一般的取0.05),这样加以控制第一类错误,以此来制约犯第二类错误的概率。
p值:当零假设为真时,我们以零假设的参数建立正态分布(根据中心极限定理,当样本数量和抽样次数足够大时,抽样分布趋于正态分布),在该正态分布中观察到样本统计量甚至是更极端值(也就是偏向备则假设)的概率。
若这个概率很大,比如说p = 1,那么就表示样本统计量在按照零假设模拟的正态分布内,我们就不能拒绝零假设;
若这个概率很小,比如说 p < 0.05,那么在我们模拟的正态分布中观察到样本统计量的概率就是一个小概率事件,我们就可以拒绝零假设;
若p值等于0.05,可增加样本容量,重新进行抽样检验。
假设检验的基本思想
假设检验的基本思想可以归纳为:我们把不想要的结果(即零假设H0)假设成立,然后利用样本计算出该假设成立时的概率(即支持该假设的概率,也就是p-value),如果这个概率小于显著性水平α(一般的为0.05),那么就可以说明零假设是小概率事件,可以拒绝,就证明了我们想要的结果(即备择假设H1)成立,可以表述为:在显著性水平α下拒绝原假设。
试着理解一下上面这段话,如果理解不了,可以看看怎么用,会有详细的分步讲解。
进行多次假设检验的校正
$$
H_0:\mu \leqslant 7
$$
$$
H_1:\mu > 7
$$
1 | #从原数据集中取样,样本容量要大于30 |
1 | #计算抽样分布的标准差 |
1 | #计算原始样本的均值 |
若零假设为:u ≥ 7,则p_value = (null_vals < sample_mean ).mean();
若零假设为:u = 7,则p_value = (null_vals < sample_mean).mean() + (null_vals > null_mean + (null_mean - sample_mean) ).mean()
线性回归是属于机器学习中监督学习范畴的一种简单预测算法。我们通过查看两个定量变量之间是否存在线性关系,来进行预测。一般使用散点图对变量之间的关系进行可视化。
反应变量就是你想进行预测的变量,其实也就是因变量(y);
解释变量就是你用于预测的变量,其实也就是自变量(x)。
相关系数:最常用的就是皮尔逊相关系数,用r表示,取值范围为[-1,1],正值表示正相关,负值表示负相关,绝对值越大,相关性就越强。在描述相关性强弱时,可以参考如下取值范围:
关于更多更详细的相关系数的知识,请戳统计学之三大相关性系数,博主写得深入浅出,而且有很多浅显易懂的例子,感兴趣的话可以看看。
线性回归的方程模型就是一元一次方程,如下所示:
b0表示截距,也就是回归线与y轴交点的y坐标;
b1表示斜率,也就是回归线的倾斜程度;
y^ 表示回归线反应变量的预测值,并不是确切的数据集中的y值。
拟合回归线时我们采用的主要算法叫做 最小二乘法,即通过回归线得到的预测反应变量值与实际反应变量之差最小时的那条就是最佳拟合回归线,其原理公式可以表示为:
在python中我们需要调用statsmodels
包来拟合回归线:
1 | # 加载statsmodels包 |
在建立模型时,一般情况下都是需要手动添加截距(一般为常数 1), 想了解更多,可以查阅Statcon: Why we need the intercept或者When is it ok to remove the intercept in a linear regression model? - Cross Validated
coef
:对应变量的参数值std err
:标准误差t
:统计检验值P>|t|
:这个是对应的 p
值,它的零假设为该变量的参数值等于0,可以指示该变量是否有利于预测反应变量,也能用于比较多个变量中哪个更重要。R-squared
:即决定系数,它是相关系数的平方。取值范围在[0,1],值越大,拟合效果就越好,这个值的统计意义可以简单解释为此次拟合中的解释变量能有多少百分比的可能去解释反应变量。多元线性回归就是由多个自变量去预测因变量的方法,其模型方程与简单线性回归基本一致,只不过是将单自变量变为了多个自变量的矩阵,如下所示:
其中X就是多个自变量的矩阵。
在Python中的编程实现步骤也如简单线性回归类似,别忘了要定义一个截距
1 | # 加载statsmodels包 |
这里和简单线性回归是一致的,只不过在解释单个自变量与因变量之间的关系时,需要加上一句“在其它变量不变的情况下……”
处理分类变量的一个思路就是将其转化为虚拟变量,也就是将各个分类变量单独成列,然后把观察行对应的分类变量量化为0(可理解为“否”)和1(可理解为“是”)作为该列的元素,再进行拟合处理。
在拟合处理时,我们添加的虚拟变量的数量应该为原数据集中的虚拟变量总数减一。
因为要计算最佳拟合系数时,需要用到变量矩阵的转秩,而判断矩阵是否可逆的充分必要条件就是这个矩阵是满秩的,又因为我们的虚拟变量矩阵中每一个变量都可以由其他变量推导而来,所以必须要舍弃一列才能确保变量矩阵为满秩。【感兴趣可以去可汗学院补一补线性代数知识】
使用pandas中的get_dummies函数来进行虚拟变量的转换
1 | #对neighborhood列进行量化,并将结果存储在df数据集的A/B/C三个新列中 |
注意:get_dummies函数输出结果的默认排序为字典顺序(即a-z),所以在进行新列储存时,一定要注意原始变量中的分类与虚拟变量列一一对应。
还是以ABC三个分类变量来假设,我们以C作为基准变量(也就是删除的那列),那么在显示的结果中:
coef | |
---|---|
Intercept | i |
A | a |
B | b |
1.Intercept的coef表示:如果分类为C的话,因变量即为i;
2.A的coef表示:如果分类为A的话,因变量为i+a;
3.B的coef表示:如果分类为B的话,因变量为i+b。
这部分课程中给了很多额外资料的链接,理论性很重,不太好啃,建议等通关后复盘的时候试着看一看。
如果我们的自变量彼此相关,就会出现多重共线性。多重共线性的一个主要问题在于:它会导致简单线性回归系数偏离我们想要的方向。要判断是否有多重共线性,最常见的办法是借助散点图或 **方差膨胀因子 (即 VIF)**。
散点图比较好理解,使用之前提到过的seaborn中的pairplot能很直观的看出各个变量之间的相关性。代码如下:
1 | import seaborn as sns |
方差膨胀因子(Variance Inflation Factor,VIF)是指解释变量之间存在多重共线性时的方差与不存在多重共线性时的方差之比。具体的计算方法如下(计算不做要求,但要理解)
假若有X1 、X2 、X3三个自变量,X1的vif计算:
1.x1对常数项(截距)、x2、x3做多元线性回归,求出R^2
2.则变量X1的VIF=1/(1-R^2)
3.同理计算出变量X2和X3的VIF。
它是指示多元线性回归中多重共线性严重与否的指标,VIF越大,多重共线性就越严重。
经验判断方法表明:
当0<VIF<10,不存在多重共线性;
当10≤VIF<100,存在较强的多重共线性;
当VIF≥100,存在严重多重共线性。
所以我们在处理的时候,就要去除VIF超过10的最不感兴趣的变量。
在python中的编程实现如下:
1 | # 计算 VIF 需要使用 statsmodel 包 |
高阶项就是在回归模型中添加诸如x^2,x^3,x1·x2等变量,获取的方式可以直接使用df[‘col_1’]进行高阶计算即可。
关键是在于观察变量之间的散点图,来确定是否需要添加高阶项。
注意:如果确定要添加某变量的高阶项,一定要确保该变量也要添加进去。
之后的24-33节也是选修,而且给了Udacity一套免费的机器学习入门课程,建议通关后再来复盘。
逻辑回归就是对分类变量进行预测的方法,尤其是对二分类问题(非1即0),比如说是否使用优惠券,是否存在贷款逾期问题等等。
逻辑回归的方程模型就是sigmoid函数:
结合二分类问题的概率,做对数变换可得:
如上p/(1-p)即为事件的机会比,在该问题中,能预测范围在0到1之间。
编程实现与线性回归类似,只不过将最小二乘法(OLS)替换成了逻辑回归(Logit):
1 | # 加载statsmodels包 |
coef
:对应变量的系数std err
:标准误差t
:统计检验值P>|t|
:这个是对应的 p
值,可以指示该变量是否有利于预测反应变量,也能用于比较多个变量中哪个更重要。在这里我们并不关注截距,而重点关注各个解释变量。
在进行结果解释时我们常说:
在保持其他变量不变的情况下,
之后的课程已经是机器学习入门阶段的范畴,可以等通关后,再去研究。(建议先开始免费的机器学习课程,再结合本章内容复盘看,更有助于你理解)
本周导学的内容较难,理解起来也比较困难,对于置信区间和假设检验两节,大家可以再额外补充一些统计学方面的相关知识,更有助于你理解;对于回归知识,建议多看几遍教学视频再结合例题,在实践中不断尝试去理解,大家加油!下周就要开始项目四了,阶段性的胜利就在前方!
]]>If you tell yourself you can’t, you won’t.
Hi,同学们,上一阶段我们学习了数据分析的基本流程、Pandas在数据分析各个过程中的应用以及Matplotlib&Pandas的可视化基础,截至目前,你们已经算是掌握了基础的数据分析技能啦!撒花!但是在统计学理论和预测方面仍有欠缺,那么P4阶段就是解决这个欠缺哒!
本周开始,我们就进入到了项目四(P4)阶段,本阶段总共包含三周,在这三周内,我们要对统计学进行学习,掌握基础的描述统计学理论、基本的概率知识、二项分布和贝叶斯公式,并学会使用 Python 来实践;学习正态分布、抽样分布、置信区间以及假设检验的概念和计算方式;学习线性回归以及逻辑回归,在真实场景中应用,比如分析 A/B 测试结果,搭建简单的监督机器学习模型。可谓是时间紧任务重,但是也别怕,统计学的基础知识还是非常简单的,跟着课程内容一步步来,自己多做笔记多查资料,一定没问题的!
那么我们的课程安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 统计学基础 | 描述统计学 - 抽样分布与中心极限定理 |
第2周 | 统计学进阶 | 置信区间 - 逻辑回归 |
第3周 | 完成项目 | 项目:分析A/B测试结果 |
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
学习课程中的描述统计学 - 抽样分布与中心极限定理课程,掌握统计学基础知识。
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 描述统计学 - 抽样分布与中心极限定理 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
描述统计分析就是通过数字或可视化的方法,对数据集进行整理、分析,并对数据的分布状态、数字特征和随机变量之间的关系进行估计和描述。其简要可以分为集中趋势分析、离散程度分析以及相关分析三大部分。所以,虽然这部分是选修内容,但拜托各位一定要看,这部分理论是数据分析的基础。
数据类型是基础,尤其是之后在进行回归预测时,针对不同的数据类型可以选择不同的算法,所以必须掌握。
数据类型可以分为两大类:数值和分类;进而分为四小类:连续、离散、定序和定类。
数据类型 | ||
---|---|---|
数值: | 连续 | 离散 |
身高、年龄、收入 | 书中的页数、院子里的树、咖啡店里的狗 | |
分类: | 定序 | 定类 |
字母成绩等级、调查评级 | 性别、婚姻状况、早餐食品 |
数据类型 | 描述方面 | 描述方式 | 备注 |
---|---|---|---|
数值: | 集中趋势 | 均值 | |
中位数 | 偶数个时取中间两值均数 | ||
众数 | 存在没有或多个的可能 | ||
离散程度 | 极差 | max - min | |
四分位差(IQR) | 75%数 - 25%数 | ||
方差 | 每个观察值与均值之差平方和的平均数 | ||
标准差 | 方差的平方根 | ||
数据形状 | 左偏态 | 均值小于中位数(普遍但不绝对,下同) | |
(需做直方图) | 右偏态 | 均值大于中位数 | |
对称分布(通常是正态分布) | 均值等于中位数 | ||
异常值 | 一般为上下超过1.5倍四分位差 | 处理方式见下面【异常值的处理】 | |
分类: | 分类计量个数或比例 |
偏态分布示意图
其他概念:
五数概括描述法:利用最小值、第一四分位数(25%处)、第二四分位数(中位数)、第三四分位数(75%处)和最大值五个数对数值型变量的离散程度进行描述的方法。
当我们的数据遵循正态分布时,我们可以使用均值
和标准差
完全理解我们的数据集。
但是,如果我们的数据集是偏态分布,五数概括法
(和关联的集中趋势度量)更适用于概括数据。
除直方图外,你还可以使用箱线图进行统计描述,箱线图其实是五数概括法的可视化。
异常值的处理:
1. 至少注意到它们的存在并确定对概括统计的影响。
2. 如果是输入错误 — 删除或改正
3. 理解它们为何存在,以及对我们想要回答的关于数据的问题的影响。
4. 当有异常值时,报告五数概括法的值通常能比均值和标准差等度量更好地体现异常值的存在。
5. 报告时要小心。知道如何提出正确的问题。
随机变量集用大写字母,如X表示;
而集里面的某个变量用对应的小写字母,如x1,x2等表示。
推论统计就是根据现有收集的部分数据对更大的总体数据进行推论的方法。他的几个关键要素为:
本节以录取案例分析为例,展示了辛普森悖论。这个例子不必深究,只是为了提醒大家要以多种方式去观察数据,避免出现案例分析中的反例。
辛普森悖论是在某个条件下的两组数据,分别讨论时都会满足某种性质,可是一旦合并考虑,却可能导致相反的结论。那么如何避免辛普森悖论呢?那就要从产生它的源头——混杂因素上考虑,混杂因素就是一个与核心研究无关的变量,它会随着变量的改变而改变,就比如说在课程中的例子中,不同专业的总人数就有很大差异,它会随着专业的改变而改变。所以在之后处理类似问题时就要进行多变量分析,这样才能帮助我们认清事件的本质。
从课程中给的这幅关系图就能很明显的看出来,概率是由模型(MODEL)去预测数据(DATA),而统计是由数据去建立模型(进而再去做预测,也就是‘’根据数据去预测数据’‘)。
概率,是一种几率、可能性,描述是事件发生的可能性度量量。随机事件,指一个被赋予机率的事件
集合,针对的是事件在样本空间的一个子集。事件A发生的概率,用符号P(A)表示 。
任何事件的发生概率在 0 和 1 之间,其中包括 0 和 1。(0表示不可能发生,1表示必然发生)
独立事件:事件每次发生的结果与前后的发生结果无关。比如说,第一次掷骰子的结果与第二次的结果
互斥事件:不可能在同一次实验中出现的俩事件。比如说,掷骰子实验中的1和6
对立事件:是一种特殊的互斥事件,即试验中只有俩种可能A和B,那么事情的发生非A即B。可以表示为
如掷硬币的正面和反面。
加法原理:若两种方法均能完成此事,则此事发生的概率为P(A) + P(B)
乘法原理:若两个步骤分别不能完成此事,则此事发生的概率为P(A)·P(B)
也叫伯努利分布,是指n个独立的事件A发生的概率分布。设每次试验中事件A发生的概率为p,则进行n次试验,A发生k次的概率为:
在现实中,我们处理的事情并不像骰子和硬币那样简单,有些时间的结果往往依赖于其他的事情,比如说晨练的概率跟这个人是不是夜猫子有关等等。那么,这就引出了条件概率,即在事件B发生的条件下,事件A发生的概率为:
其中,P(AB)表示AB同时发生的概率。
在如下的文氏图中,AB同时发生的概率可以表示为两个圆的交集,那么B已经发生的条件下A发生的概率就是这个交集(橙色部分)占整个B圆的比例。
之前讲过独立事件,那么用公式的方式可以表达为:
P(A) = P(A|B)
。根据条件概率公式可以推导出,当P(AB) = P(A)P(B)
时,则可说明A事件与B事件相互独立。
全概率公式
也就是A发生的概率为在互斥的多个事件(B1,B2…)已发生的条件下的条件概率之和。公式可以表示为:
贝叶斯法则是概率推理的黄金法则,是利用先验概率计算后验概率的方法。
课程中的癌症例子十分贴切,讲解的也十分详细,所以大家看到前20个小节,能理解贝叶斯法则就可以了,后面的是在无人驾驶中的应用例子,可以跳过不看。
在课程示例中:
由条件概率能计算出患癌与检查结果为阳性同时发生的概率P(C,Pos)
(红色区域占整个矩形的比例)和没患癌与检查结果同时发生的概率P(~C,Pos)
(绿色区域占整个矩形的比例)。
二者相加,即为检查结果为阳性的概率(全概率公式)P(Pos)。
则,检查结果为阳性的条件下患癌概率为:
这样我们就得到了更接近真实的检查结果为阳性的患癌概率。
在这个例子中:
癌症发生的概率P(C)
为先验概率,即在我们进行检查之前就对患癌概率的一个判断;
阳性结果下为癌症的概率P(C|Pos)
为后验概率(阳性下非癌症、阴性癌症、阴性非癌症都是),这些是在检查发生之后,我们对患癌概率这件事的重新评估;
这就是贝叶斯法则的含义。我们先预估一个”先验概率”,然后加入实验结果,由此得到更接近事实的”后验概率”。
如果感觉理解困难,可以看一下白话版的贝叶斯讲解:怎样用非数学语言讲解贝叶斯定理(Bayes’s theorem)
前面我们学习了概率的基本知识,有了理论基础,本节就是利用Python落地的教学。应用的第三方包为NumPy和Pandas。
使用的函数为numpy.random.randint(low, high=None, size=None, dtype='l')
:
函数的具体用法如下:
1 | import numpy as np |
使用的函数为numpy.random.choice(a, size=None, replace=True, p=None):
函数的具体用法如下:
1 | #输入数字时取数 |
使用的函数为numpy.random.binomial(n, p, size=None),参数也很好解释。
参数中的n即为每次试验中取值的次数,p则为试验中的某一种事件成功的概率,size则是试验的次数。
这里主要是一些Pandas函数的应用,经过上一阶段的学习应该已经很熟练了。
主要涉及的函数是分组和统计计数类的函数,比如说groupby,query,count等,如果忘记的话,自己查官方文档或者之前的笔记,这里不再赘述。
课程中以抛硬币模型引入了二项分布进而讲解了正态分布模型,那么到底什么是正态分布或者满足什么条件就可以算是正态分布了呢?
在相同条件下,我们随机地对某一测试对象(抛硬币20次,其中正面的次数)进行多次测试(抛很多次20次)时,测得的数值在一定范围内波动(从0到20),其中接近平均值的数据(10左右)占多数,远离平均值的占少数。具有这种分布规律的随机变量的分布就称作正态分布。
大概长这样儿:
它的概率密度函数可以表示为:
这里为什么要引入正态分布呢?
在此之前,先回顾下推论统计的几个概念:
课程中举得例子是统计优达学生中喝咖啡的人所占比例,我们看下图:
图中所有的杯子(学生)就叫做总体;此外可以看到有四个深浅不一的蓝色底框,每个底框链接了5个学生,这5个学生就是样本,每组样本我们还计算了喝咖啡的比例,这就是统计量。
一般的,样本数≥30即可称为大样本。 大样本条件下,抽样平均数的分布接近正态分布。
但必要抽样数目的确定是有相关公式计算的,这里就不给出了,感兴趣的话可以去搜搜看。
现在我们继续按照课程中的例子进行取样,样本容量为5,不断得取10000次,计算均值的分布情况如下:
(完全看不出这是个什么分布)
将样本容量改为50,仍然取10000次,计算均值的分布情况如下:
已经可以看出正态分布的样子了,那如果继续增加样本容量,改为5000,同样取10000次,计算均值的分布情况如下:
想比上一幅图,这幅可视化更接近正态分布,均值处于相同的位置,但方差(离散程度)明显小了很多。
上面的这个过程就是中心极限定理的含义,随着样本容量的逐渐增大,平均数的抽样分布越接近正态分布(但也不一定必须要很大很大才能近似于正态分布),同样这也适用于求和,比例等,但不适用于所有的统计量,比如说最大值,方差等等。
中心极限定理的妙处就在于,我们可以从任意的乱七八糟的分布取任意数量的样本值(比如上面例子中的5,50),然后计算样本的均值(或者和),不断得取值求均,最终做他们频率的可视化,你会发现这是一个非常完美的正态分布。
现实生活中有很多的随机过程,有的分布就是乱七八糟,但是你可以通过中心极限定理,得到他们均值或者和的正态分布,这也是为什么正态分布在统计中如此常用的原因之一。
如果感觉理解起来还是有点儿困难的话,你可以戳在线抽样分布模拟器,自己动手试一试。
大数定理表达的是随着样本容量增加,样本平均数越来越接近总体平均数,字面上的意思很好理解,但这里有一点要注意,我们举例来说明一下:
比如说,我现在有100枚硬币,放在一个盒子里,随便摇一下盒子,打开,对正面朝上的硬币进行计数(当然,我们知道期望为100 x 0.5 = 50):
第一次实验的结果是55;第二次是60;第三次是70,三次实验的均值为((55+60+70)/3 ≈62),那你觉得,下次实验的结果是更有可能小于50还是大于50呢?
你有可能这样想,根据大数定理,随着我们试验次数的不断增加,均值肯定是不断趋向于50的,前三次的实验中每次都超过50,那么下次的实验会有更大的可能小于50,来纠正前三次实验的偏差。
如果你真的这样想,你就陷入了赌徒悖论。大数定理不关心前面发生的有限次实验,因为后面还有无限次的实验,而这无限次实验的期望值是50。这个例子可能比较随意,但这就是大数定理的含义。
自助法,bootstrap,也就是重复抽样。还记得上一节导学中讲到的numpy.random.choice函数吗?里面有一个replace参数,默认为True表示重复取样,也就是自助法;若设置为False,则表示不重复取样。
本期导学主要对描述统计学和概率的基础知识进行了总结,这部分偏理论一些,如果觉得理解起来有点吃力,可以通过重复看视频,边看边用笔去算或者去网上搜集一些资料或者找一些教科书去查阅,要求是:不一定要完全掌握其原理,但求理解和会用。
]]>Nothing is particularly hard if you divide it into small jobs.
Hi,同学们,本周是我们P3阶段的最后一周,前三周我们掌握了数据分析的基本流程、Pandas在数据分析各个流程中的基本应用,使用matplotlib&Pandas进行可视化的技巧,并且在项目三中得到了巩固和锻炼。我也陆续收到了大家的项目展示,都十分厉害,尤其是问题的提出以及可视化,非常能吸引人,只是数据整理阶段的代码还需再慢慢磨练,得以精简。本周导学呢,我们就是对之前所学做一个总结,希望大家也能自己做一份总结(这份总结才是最贴切你自己需求的),优达日的时候我们会一起交流一下自己的项目心得以及踩过的坑,等你们哦~
项目三(P3)阶段总共包含四周,在这一个月内,我们要对数据分析入门进行学习,学习数据分析思维,掌握Python数据分析及可视化方法,并使用所学知识完成项目三:探索数据集,尝试着自己完成整个数据分析的流程,得到一些饶有兴趣的结论,你一定会非常有成就感哒!那么以下便是这四周的学习安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 数据分析过程-1 | 数据分析过程&案例研究-1 |
第2周 | 数据分析过程-2 | 案例研究-1&案例研究-2 |
第3周 | 完成项目 | 项目:探索数据集 |
第4周 | 项目修改与通过 | 修改项目、查缺补漏、休息调整 |
!!看这里!!:在P3课程里面安排了SQL的高阶课程,但是因为在项目三中并不会涉及到SQL知识,所以为了保证大家学习的连贯性,在完成前两周的课程之后,就开始项目。至于!!SQL的高阶知识,大家可以放在课程通关后进行选修!!;
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 项目三 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
数据分析的基本流程
Pandas在数据分析中的应用
&
/|
)基本概念(fig/ax)
开始绘图(plt.subplots/plt.add_subplot/plt.figure)
坐标轴设置
调整范围(ax.axis/xlim/ylim)
调整刻度
双轴(twinx)
标题与轴标题(title,xlabel,ylabel)
图例(legend)
颜色与样式(plot(x,y,’color``marker``line
‘)
网格(grid)
图像注释(annote)
平行于坐标轴的线(vline/hline)
常用可视化图形
如何着手探索性数据分析?
可视化
一些函数:
通过这四周的学习,你又掌握了:
此外,你还增长了这些软技能:
如果你学习时间充裕,你还有可能掌握了:
哈!这么总结下来,发现不知不觉间,又掌握了很多!又进步了很多!我导师之前教育我说:“你之所以现在这么焦虑,都是因为你自己的能力满足不了你的欲望。”那么,同样因为对未来感到焦虑来到这里学习的你们,经过这段时间的学习,焦虑是不是缓解了许多呢?哈哈,所以,请不要放松脚步,KEEP GOING!
]]>Stop being afraid of what could go wrong and start being positive about what could go right.
Hi,同学们,经过了前两周的学习,我们掌握了数据分析的基本流程、Pandas在数据分析各个流程中的基本应用以及使用matplotlib&Pandas进行可视化的技巧,那么本周我们就真刀实枪地找一套数据集练练手。本周的导学有两期,分别选用了项目三中的两个数据集(TMDb电影数据和FBI枪支数据)进行分析,只是分享思路和方法,起一个抛砖引玉的作用,大家选择其他的数据集也可以举一反三,如果有什么棘手的问题随时微信联系我就OK~
本周开始,我们就进入到了项目三(P3)阶段,本阶段总共包含四周,在这一个月内,我们要对数据分析入门进行学习,学习数据分析思维,掌握Python数据分析及可视化方法,并使用所学知识完成项目三:探索数据集,尝试着自己完成整个数据分析的流程,得到一些饶有兴趣的结论,你一定会非常有成就感哒!那么以下便是这四周的学习安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 数据分析过程-1 | 数据分析过程&案例研究-1 |
第2周 | 数据分析过程-2 | 案例研究-1&案例研究-2 |
第3周 | 完成项目 | 项目:探索数据集 |
第4周 | 项目修改与通过 | 修改项目、查缺补漏、休息调整 |
!!看这里!!:在P3课程里面安排了SQL的高阶课程,但是因为在项目三中并不会涉及到SQL知识,所以为了保证大家学习的连贯性,在完成前两周的课程之后,就开始项目。至于!!SQL的高阶知识,大家可以放在课程通关后进行选修!!;
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 项目三 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
强烈建议大家完成本地环境的搭建,在本地完成此项目。搭建本地环境的方法请参考Anaconda的安装与配置一节,完成后你将获得本项目中会用到的关键软件:Spyder和Jupyter Notebook。
数据集选择:在此处选择你感兴趣的数据集并下载至与项目文件相同的文件夹。(若下载失败,请微信联系我索取)
本地打开:在项目文件的文件夹下,按住Shift
键,右击选择在此处打开命令窗口
,输入jupyter notebook
,待打开本地页面之后,选择项目文件打开,之后就请开始你的表演。
项目文件中已经给大家列好了基本流程,所以请在开始项目之前,一定要先整体浏览一遍项目文件,着重看一下:
要记得,数据分析过程不是一蹴而就的,是螺旋上升接近目标的过程,所以一定要保持耐心,对照着项目评估准则一步步完成。
另外,一开始你的notebook会显得很乱没有章法,那在提交之前最好能再修改一个整理好的版本。
该数据来自联邦调查局 (FBI) 的全国即时犯罪背景调查系统 (NICS)。NICS 用于确定潜在买家是否有资格购买枪支或爆炸物。枪支店可以进入这个系统,以确保每位客户没有犯罪记录或符合资格购买。该数据已经收纳了来自
census.gov 的州级数据作为补充数据。NICS 数据在一个 xlsx 文件格式的一个表格中,它包含了按照月份(month)、州 (state) 、类型 (type) 统计的武器调查数量 (the number of firearm checks) ;美国的人口普查数据 (U.S. census data) 储存在一个 csv 文件中。它包含了州级的几个变量,每个州的大多数变量在 2016 年只有一个数据点,但一些变量有一年以上的数据。
虽说本数据集有两个数据文件,但围绕的关键词只有一个,那就是枪支,所以提出问题时,也一定要围绕着该关键词进行提问。问题示例:
一般来说,就导入如下几个拓展包就够了,当然如果后续操作中还需导入其他包的话,再补充即可。
1 | # 用这个框对你计划使用的所有数据包进行设置 |
1 | #导入枪支数据 |
1 | df_gun.head() |
这里要注意一点,因为数据集的列数较多,jupyter会自动折叠中间的部分列,导致我们预览数据时总是看不完整,这时候你可以尝试下:
1 | #col_numbers设置为不小于你数据集列数的某一值 |
同理,也可以用’max_rows’设置最大显示行数。
1 | df_gun.info() |
1 | <class 'pandas.core.frame.DataFrame'> |
纵览了一下,各列的数据类型基本没什么问题,唯一有问题的是month
列,应该是datetime
类型。整个数据集就是由时间、州名和各式各样的枪支数据组成的。
1 | #这里我们计算的缺失比例 |
1 | month 0.000000 |
可见数据集的缺失情况非常严重,这时候需要你直接运行df_gun
去观察全部数据,这样才能有据猜想数据缺失的原因。简要通览数据后,我们发现近年的数据缺失不大,猜想之前的统计中没有对枪支进行详细分类或者是统计不全导致的,而且就枪支数量而言,缺失数据较少的permit、handgun、long_gun和other等列占绝对优势,所以我们完全可以只筛选最有代表性的这几列进行分析。
因为筛选后的数据跟之前相差较大,为了提高后续步骤的效率,可以在此先进行数据清理
1
2 #因为此次筛选的数据列是间隔的,所以调用了numpy的r_函数生成列表,按照列序号筛选间隔的列。
df_gun = df_gun.iloc[:,np.r_[0:3,4,5,7,8,26]].dropna()之后,还需对最后一列
totals
进行修正
1 df_gun['totals'] = df_gun['permit']+df_gun['handgun']+df_gun['long_gun']+df_gun['multiple']+df_gun['admin']
1 | #检查是否有数据重复 |
1 | 0 |
无重复数据。
1 | df_gun['state'].nunique() |
1 | 55 |
美国一共有50个州,多出来的5个是什么鬼?是不是有缩写的州名导致的重复?
1 | df_gun['state'].value_counts() |
1 | New Mexico 227 |
结果一目了然,不仅有美国各州,还包括了Mariana Islands 、Virgin Islands 等地,感兴趣可以去搜了一下,都是老美宣誓主权的一些群岛。
评估的步骤差不多,所以只罗列一些需要注意的点。
1 | df_census.info() |
1 | <class 'pandas.core.frame.DataFrame'> |
发现一个奇怪的事情,基本上所有列数据都在65行之后没有了,肯定有什么猫腻,可以用tail()或者直接打开文件查看(因为数据量很小),发现后面几行都是对数据统计的一些说明,没有实际意义,直接删除即可。而且在该数据中只有50个州的数据。
清理数据就是对上一步中发现的问题进行清理,并且删除无关列,最终得到的是一个方便你进行分析及可视化的干净数据。
清理前记得备份数据
删除无关列
建议使用drop函数
1 | #删除列 |
数据融合
想要找出人口普查的数据与枪支数据之间的关系,肯定要把这两个数据进行融合。
融合前,我们先观察一下人口普查数据中到底有哪些,发现每个州的大部分变量都只在2016年有记录点,所以我们就要分别从人口普查数据和枪支数据中筛选出2016年的数据,再以州作为键(key)进行合并。
筛选数据
1 | #先筛选出人口普查数据中2016年的数据,并将Fact列作为索引 |
处理千位分隔符和百分号
在人口普查数据中数字中均包含有千位分隔符或者是百分号,这会给我们之后进行分析带来不便,处理掉他们,并且转换为浮点型数据。
1 | #先将有千位分隔符的列转为float类型 |
百分号的处理方式同上类似。
数据融合
我们在之前的导学中总结过Pandas做数据融合的方法,就此项目而言,两个数据以索引(Index,也就是各州的州名)为键进行融合,最简单的方法就是用join()函数了。如果你忘了,可以点这里复习一下。
1 | df_2016 = df_gun_2016.join(df_census_2016) |
好,至此我们的数据就算是整理完毕了,接下来就是探索性分析及可视化阶段,这里没有什么特别需要注意的地方,大家就随性而为。
在这个阶段你可以随意做可视化,尽可能多得去探索你想解决的问题。在探索阶段,作图可以不用很规范,你自己知道是什么意思就可以,而且可能会有些探索的问题结果意义不大,所以在提交项目时,要进行择优保留并对其润色修饰。
对你整理好的可视化图像进行总结,结论要有根有据但也不要只是停留在描述
,可以进行适当的猜测。
Awareness is the greatest agent for change.
Hi,同学们,经过了前两周的学习,我们掌握了数据分析的基本流程、Pandas在数据分析各个流程中的基本应用以及使用matplotlib&Pandas进行可视化的技巧,那么本周我们就真刀实枪地找一套数据集练练手。本周的导学有两期,分别选用了项目三中的两个数据集(TMDb电影数据和FBI枪支数据)进行分析,只是分享思路和方法,起一个抛砖引玉的作用,大家选择其他的数据集也可以举一反三,如果有什么棘手的问题随时微信联系我就OK~
本周开始,我们就进入到了项目三(P3)阶段,本阶段总共包含四周,在这一个月内,我们要对数据分析入门进行学习,学习数据分析思维,掌握Python数据分析及可视化方法,并使用所学知识完成项目三:探索数据集,尝试着自己完成整个数据分析的流程,得到一些饶有兴趣的结论,你一定会非常有成就感哒!那么以下便是这四周的学习安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 数据分析过程-1 | 数据分析过程&案例研究-1 |
第2周 | 数据分析过程-2 | 案例研究-1&案例研究-2 |
第3周 | 完成项目 | 项目:探索数据集 |
第4周 | 项目修改与通过 | 修改项目、查缺补漏、休息调整 |
!!看这里!!:在P3课程里面安排了SQL的高阶课程,但是因为在项目三中并不会涉及到SQL知识,所以为了保证大家学习的连贯性,在完成前两周的课程之后,就开始项目。至于!!SQL的高阶知识,大家可以放在课程通关后进行选修!!;
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 项目三 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
强烈建议大家完成本地环境的搭建,在本地完成此项目。搭建本地环境的方法请参考Anaconda的安装与配置一节,完成后你将获得本项目中会用到的关键软件:Spyder和Jupyter Notebook。
数据集选择:在此处选择你感兴趣的数据集并下载至与项目文件相同的文件夹。(若下载失败,请微信联系我索取)
本地打开:在项目文件的文件夹下,按住Shift
键,右击选择在此处打开命令窗口
,输入jupyter notebook
,待打开本地页面之后,选择项目文件打开,之后就请开始你的表演。
项目文件中已经给大家列好了基本流程,所以请在开始项目之前,一定要先整体浏览一遍项目文件,着重看一下:
要记得,数据分析过程不是一蹴而就的,是螺旋上升接近目标的过程,所以一定要保持耐心,对照着项目评估准则一步步完成。
另外,一开始你的notebook会显得很乱没有章法,那在提交之前最好能再修改一个整理好的版本。
本项目选择的数据集为Kaggle提供的TMDb电影数据。此数据集中包含 1 万条电影信息,信息来源为“电影数据库”(TMDb,The Movie Database),包括用户评分和票房等。数据已进行了简单清理,涉及到的变量如下表所示:
变量名 | 注释 | 变量名 | 注释 |
---|---|---|---|
id | 电影序号 | keywords | 电影关键词 |
imdb_id | imdb电影序号 | overview | 剧情摘要 |
popularity | 受欢迎程度 | runtime | 电影时长(min) |
budget | 预算($) | genres | 电影风格 |
revenue | 收入 | production_companies | 制作公司 |
original_title | 电影名称 | release_date | 发布日期(月/日/年) |
cast | 演员表 | vote_count | 评价次数 |
homepage | 电影网址 | vote_average | 平均评分 |
director | 导演 | release_year | 发布年份 |
tagline | 宣传词 | budget_adj | 预算(考虑通胀) |
revenue_adj | 收入(考虑通胀) |
对数据简单浏览之后,你要进行角色扮演了,假如你现在就是一名电影行业的数据分析师,通过分析此数据集,你能为公司提供哪些有用的发现或者规律呢?或者你只是一名会数据分析的电影爱好者,通过分析此数据集,你能否给小伙伴们推荐一些合适的电影呢?这里提供几个参考:
电影类型相关:
导演相关:
制作公司相关:
影响电影评分的要素有哪些?
影响电影收益的要素有哪些?
最近几年的电影都有哪些关键词?
……
整理好你感兴趣的问题后,那就开始吧~
在本示例中,选择的主题为今晚有空,让好电影与你相伴,所以我们的目标就是筛选出好看的电影咯~
一般来说,就导入如下几个拓展包就够了,当然如果后续操作中还需导入其他包的话,再补充即可。
1 | # 用这个框对你计划使用的所有数据包进行设置 |
1 | df = pd.read_csv('tmdb-movies.csv') |
1 | df.info() |
1 | <class 'pandas.core.frame.DataFrame'> |
纵然了一下,各列的数据类型没什么问题,唯一一个可能有问题的是release_date
列,应该是datetime
类型,但因为我们后面的分析中只会用到电影的上映年份,也就是release_year
列,所以这列不处理也罢。
1 | df.isnull().sum() |
1 | id 0 |
可见数据集的情况很不错,几个关键列几乎没有缺失。至于director
列的缺失,你可以依照电影标题去搜索它的导演,然后进行填充,或者干脆直接删除掉。
1 | sum(df.duplicated()) |
1 | 1 |
有一行重复数据,过会儿直接清理掉。
1 | df.describe() |
因为这是在数据评估阶段,所以着重看min和max,检查是否有异常值。本数据集中没什么问题。
查看各列元素
1 | df['column_name'] |
可以查看各列的详细情况,避免因为折叠而忽略了某些严重问题。
比如说,我们通过查看各列情况,发现cast
、keywords
、genres
和production_companies
这四列中的都包含有以|
分隔开的多个平级元素,这在进行之后的按类分析时会非常不便,所以需要清理。(但也不是这四列都要清理,只用清理你的分析中会用到的就行。)
还有就是budget_adj
和revenue_adj
两列是科学记数法,在进行可视化的时候,坐标轴的显示肯定就会很丑,到时候要注意处理。
清理数据就是对上一步中发现的问题进行清理,并且删除无关列,最终得到的是一个方便你进行分析及可视化的干净数据。
清理前记得备份数据
数据备份
1 | df_clean = df.copy() |
删除无关列
在本次示例项目中,我们的目的是找出好看的电影,所以评分和受欢迎程度是关键参数,然后再探索下他们与其他参数之间是否存在联系。
那就按照如下方法删除一些无关列(其实是筛选出想要的列,顺便再拍一下序):
1 | df = df[['original_title','production_companies','director','cast','genres','keywords','runtime','popularity','vote_count','vote_average','release_year','budget_adj','revenue_adj']] |
缺失值的处理
因为关键列并没有出现数据缺失,所以并未进行处理。
删除重复值
1 | df.drop_duplicates(inplace = True) |
genres
列处理
电影类型是关键筛选条件,所以要细分。
1 | #将genres列转为str格式(因为NaN是float格式的) |
1 | #获取所有的电影类型 |
1 | #从genres_set中删除nan |
1 | #将各电影类型作为列添加到数据集中,并用1表示‘是’,0表示‘否’ |
1 | #删除genres列,并检查 |
production_companies
列处理
属于电影的参考列,所以我们只筛选首公司。
1 | #只筛选第一家主要投资的公司 |
1 | #为了符合逻辑,更改列名 |
cast
列处理
演员也是电影的参考列,只筛选出两名主演。
1 | #筛选前两位主演 |
添加income_adj
列
原数据中只有budget_adj
和revenue_adj
列,后者减去前者即为电影的收益。
1 | df_clean['income_adj'] = df_clean['revenue_adj'] - df_clean['budget_adj'] |
至此,清理数据告一段落。
在这个阶段你可以随意做可视化,尽可能多得去探索你想解决的问题。在探索阶段,作图可以不用很规范,你自己知道是什么意思就可以,而且可能会有些探索的问题结果意义不大,所以在提交项目时,要进行择优保留并对其润色修饰。
电影的受欢迎程度和平均评分是我们在进行电影推荐时的主要参考,所以我们先来观察下这两列的主要分布情况以及与其他列的相关性。
1 | #受欢迎程度的分布情况 |
1 | #平均评分的分布情况 |
通过观察这两幅图我们可以发现:绝大部分的电影受欢迎程度都在10以下,平均评分却是一个类正态分布,电影评分集中在5到7之间。
与上映年份的关系
1 | #受欢迎程度 |
1 | #评分 |
通过观察这两幅可视化,我们发现:随着上映日期逐渐接近现在,受欢迎程度呈波动上升趋势,但是评分却是波动下降。这应该是因为年代越久远的电影观看人数越少,评分次数也就越少(需附图验证),个别的高评分对平均评分的影响也就越大,这才导致了受欢迎程度低却评分高的现象。
本数据集中的数值型变量不是很多,但要是一对一对的去看他们之间的相关性会很累,懒人智者推动科技进步嘛,前辈们帮我们都考虑好了,可以参考下面的代码:
1 | #筛选出数值变量 |
各变量之间相关性的热度图
1 | fig, ax = plt.subplots(figsize=(10, 6)) |
从这幅图里面,可以很明显的读出一些信息:
pairplot
你不满足于只看冷冰冰的数字,想看到更直观的散点图或者直方图,那就请参考如下代码:
1 | pp = sns.pairplot(df_corr, size=1.8, aspect=1.8, plot_kws=dict(edgecolor="k", linewidth=0.5), diag_kind="kde", diag_kws=dict(shade=True)) |
从上面这幅可视化中,我们不仅能看到各变量两两之间的散点图(相关性),还能看到各变量的分布情况,真可谓是大杀器。
那,热度与评分和其他分类变量有没有什么关系呢?
…(请继续探索)
… KEEP GOING
在做电影推荐时,受欢迎程度和评分是我们的关键评估指标。
比如说,你有一个哥们比较喜欢看Adventure
类的电影,听说你在做TMDb的电影数据分析,所以来找你推荐,你会推荐哪些呢?
1 | #首先我们要筛选出Adventure类的电影 |
1 | #既然是推荐,自然要筛选一些热门的评分高的电影,所以这里我们选择了好于其他90%的电影(结果为15部电影) |
1 | #排序 |
1 | #可视化 |
结论立马就出来了,首推的电影就是Interstellar(星际穿越)。当然这种方法可以定义成一个函数,参数即为电影类型
,这样就能省心省力的得到所有电影的最热最佳推荐了。
当然,你还可以尝试:
按导演推荐
我一开始想着用groupby直接按照导演分类,然后求评分的均值再作图,可是结果并不如人意。
1 | df_clean.groupby('director')['vote_average'].mean().sort_values()[-15:].plot(kind = 'barh',color = 'b'); |
这些导演好像都不是很熟悉,应该是数据集中只收录了一部或者很少的电影作品,然而又因为这些作品的评分较高,才导致这种情况,所以我们要先对导演做一个筛选,比如说,筛选出收入作品数量在10部及以上的导演。
1 | #先对原数据中的director列作计数统计,然后筛选大于等于10的数据存为一个新的DataFrame(目的是为了方便筛选) |
1 | #受欢迎程度 |
这次得到的结果更大众一些,出现的导演名字也基本都听过。Christopher Nolan和Quentin分别获得了双料榜首和榜眼,这两个人的名字也算是电影的品质保证了吧。
按主演推荐
按制片公司推荐
… …
当然,你还可以分析电影评分与其他变量的相关性,或者从效益角度出发,去分析票房、预算、收益等等。但万变不离其宗,用数据分析的流程做指导,所学知识为基础,Bing或者Google为利剑(搜索的时间可能要占到一半以上,所以不要慌,搜索完记在小本本上),开始你的项目三征服之路吧!
对你整理好的可视化图像进行总结,结论要有根有据但也不要只是停留在描述
,可以进行适当的猜测。
If you don’t like where you are , change it. You’re not a tree.
Hi,同学们,上一周我们学习了数据分析的基本流程,以及Pandas在数据分析各个流程中的应用,本周呢就是在上周的基础上,掌握Python数据分析可视化的基础知识,包括matplotlib及pandas可视化。可视化是数据分析的重要环节,是你进行探索性数据分析、得出结论、传达结果的关键,所以,一定的可视化技巧是非常必须的,除了本章涉及到的两个知识点外,我还会在最后提供一些其他的python可视化库链接和其他可视化软件的链接,希望大家能不满足于导学,而去积极求索,加油!!
本周开始,我们就进入到了项目三(P3)阶段,本阶段总共包含四周,在这一个月内,我们要对数据分析入门进行学习,学习数据分析思维,掌握Python数据分析及可视化方法,并使用所学知识完成项目三:探索数据集,尝试着自己完成整个数据分析的流程,得到一些饶有兴趣的结论,你一定会非常有成就感哒!那么以下便是这四周的学习安排:
时间 | 学习重点 | 对应课程 |
---|---|---|
第1周 | 数据分析过程-1 | 数据分析过程&案例研究-1 |
第2周 | 数据分析过程-2 | 案例研究-1&案例研究-2 |
第3周 | 完成项目 | 项目:探索数据集 |
第4周 | 项目修改与通过 | 修改项目、查缺补漏、休息调整 |
!!看这里!!:在P3课程里面安排了SQL的高阶课程,但是因为在项目三中并不会涉及到SQL知识,所以为了保证大家学习的连贯性,在完成前两周的课程之后,就开始项目。至于!!SQL的高阶知识,大家可以放在课程通关后进行选修!!;
本阶段可能是个挑战,请一定要保持自信,请一定要坚持学习和总结,如果遇到任何课程问题请参照如下顺序进行解决:
饭要一口一口吃,路要一步一步走,大家不要被任务吓到,跟着导学一步一步来,肯定没问题哒!那我们开始吧!
注:本着按需知情原则,所涉及的知识点都是在数据分析过程中必须的、常用的,而不是最全面的,想要更丰富,那就需要你们课下再进一步的学习和探索!
时间 | 学习资源 | 学习内容 |
---|---|---|
周二 | 微信群 - 每周导学 | 预览每周导学 |
周三、周四 | Udacity - Classroom | 案例研究1&2 |
周五 | 微信/Classin - 1V1 | 课程难点 |
周六 | Classin - 优达日 | 本周学习总结、答疑 |
周日 | 笔记本 | 总结沉淀 |
周一 | 自主学习 | 查漏补缺 |
matplotlib是Python泰斗级别的绘图库,因受到Matlab的启发构建而成,所以你会觉得它的命令API,还有那九十年代感强烈的可视化图像跟matlab很相似。它非常适合在jupyter notebook中交互式作图,这个库“功能非常强大”,但也“非常复杂”,所以这里只能介绍matplotlib的一些基础和常用的方法,想了解更多就需要你自主探索啦!
1 | import matplotlib.pyplot as plt |
1 | #想在Jupyter Notebook中顺利显示出可视化图像,你需要添加如下代码 |
你可以点击matplotlib.pyplot搜索查看一些函数的说明和用法;或者你可以点击Pyplot Gallery查看一些代码实例,找到灵感。
在使用matplotlib生成图像时,整个图像为一个Figure对象。在Figure对象中可以包含一个,或者多个Axes对象。每个Axes对象都是一个拥有自己坐标系统的绘图区域。其逻辑关系如下:
在如下的单图fig中,我们给出了我们的绘图中只有一个坐标系区域(也就是ax),此外还有以下对象:
各个对象之间的隶属关系如下图所示:
所以大家在之后进行可视化的时候,根据这些隶属关系来去对参数进行设置,这样逻辑不乱,代码也清晰。
在绘图前,首先需要设置的就是fig(画布)和ax(图),我们主要通过plt.subplots()函数来定义
1 | #绘制单图 |
1 | #绘制多图,subplots的第一个参数为行数,第二个参数为列数 |
1 | #绘制多图时,注意前面的变量为一个矩阵的形式,如下前面为2x2矩阵,则后面subplots的行列参数也应该都为2 |
绘制子图主要使用的函数为:add_subplot(abc),调用该函数会生成一个包含axb个子图的画布,而c则表示位置,按照从左至右,从上至下的顺序依次排列。
1 | x = np.arange(1,100) |
调整范围
主要是用来利用调整坐标轴范围进行图像的截取,可以使用ax.axis()函数,也可使用plt.xlim()或者plt.ylim()函数,具体用法如下:
1 | #ax.axis([0,10,0,50]) [x左,x右,y下,y上] |
坐标轴刻度调整
1 | #利用ax.locator_params()设置刻度间隔 |
1 | #利用plt.xticks()设置x轴刻度顺序/旋转角度 |
1 | #时间刻度调整 |
双轴
有时候想要在同一张图中显示两种不同范围的变量,这时候就要设置双轴
双轴的关键代码为twinx()函数(也就是双胞胎x轴?)
1 | x = np.arange(1,11,0.1) |
标题与轴标题都是一幅可视化图像中的必须要素。你可以参考如下示例来设置你的标题与轴标题。
示例:
1 | plt.title('This is title',color = 'r',fontsize = 17) |
图例在进行多变量比较的可视化中必不可少。你可以通过在plot()函数中添加参数’label’来对所绘曲线设置图例
1 | x = np.arange(1,11,1) |
也可以通过调用plt.legend()函数对图例进行设置。
1 | x = np.arange(1,11,1) |
调用matplotlib.pyplot.plot函数即可设置所画图像的颜色与样式,设置方法如下:
1 | plt.plot(x,y,'[color][marker][line]') |
常用颜色
字符 | 颜色 | 字符 | 颜色 |
---|---|---|---|
b | 蓝色 | g | 绿色 |
r | 红色 | y | 黄色 |
c | 青色 | k | 黑色 |
m | 洋红色 | w | 白色 |
#rrggbb | RGB颜色 | 0.7 | 灰度值 |
常用线条样式
字符 | 描述 | 字符 | 描述 |
---|---|---|---|
‘-‘ | 实线 | ‘:’ | 虚线(·······) |
‘–’ | 虚线(——) | ‘None’或’ ‘或’’ | 什么都不画 |
‘-.’ | 点划线 |
线条标记
字符 | 描述 | 字符 | 描述 |
---|---|---|---|
‘o’ | 圆圈 | ‘.’ | 点 |
‘D’ | 菱形 | ‘s’ | 正方形 |
‘h’ | 六边形1 | ‘*’ | 星号 |
‘H’ | 六边形2 | ‘d’ | 小菱形 |
‘_’ | 水平线 | ‘v’ | 一角朝下的三角形 |
‘8’ | 八边形 | ‘<’ | 一角朝左的三角形 |
‘p’ | 五边形 | ‘>’ | 一角朝右的三角形 |
‘,’ | 像素 | ‘^’ | 一角朝上的三角形 |
‘+’ | 加号 | ‘\‘ | 竖线 |
‘None’,’’,’ ‘ | 无 | ‘x’ | X |
示例:
1 | fig,ax = plt.subplots() |
也就是可视化图像中的网格,可以方便读者快速估取某点的横纵坐标。我们通过调用plt.grid()函数来对启用网格。一般情况下,使用该函数的默认参数即可
1 | #采用默认参数 |
但你也可以通过如下方式进行设置。
1 | y = np.arange(1,5,0.1) |
有时候你需要为可视化图中的某个关键点做出注释,方便读者能一眼看出,这时候你就需要调用plt.annote()函数来实现你的目的了。
该函数中几个关键的参数分别为:
str:一个字符串,来写出你想要标注的内容;
xy:标注点的坐标
xytext:标注内容起始位置的坐标(也就是从该点开始显示你的注释内容)
arrowprops:设置注释指向标注点的箭头
你也可以去搜索该函数,获取更多参数的设置方法。
示例:
1 | x =np.arange(-10,11,1) |
你可能需要添加一条平行于x轴或者是y轴的线,在图像中分割不同区域。这时候,你就需要调用vlines(x, ymin, ymax)函数或者是hlines(y, xmin, xmax)函数,除了括号内的参数之外,你还可以设置颜色(color)参数和线型(linestyles)参数。(设置方法参考颜色与样式章节)
示例:
1 | plt.vlines(0, 0, 0.5, colors = "c", linestyles = "--"); |
如何能选择最适合的图形来表示你想分析的结果呢?这里提供一个简单的参考~
1 | np.random.seed(7)#设置随机种子,可以保证每次的随机数是一致的 |
1 | #例1 |
1 | #例2 横向柱形图 |
1 | #例3 拼接柱状图 |
1 | #例4 并列柱状图 |
1 | fig = plt.figure() |
1 | labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' |
1 | fig = plt.figure() |
1 |
|
参考如下代码:
1 | #保存至当下路径 |
使用matplotlib做可视化不能显示中文,根本原因是因为官方配置中没有中文字体,所以,我们把中文字体添加进去就ok啦。具体方法如下:
1 | #coding:utf-8 |
示例:
1 | x = np.arange(1,11,1) |
有可能你做得可视化图像中,坐标轴的符号显示一个框框,这时候你添加如下设置即可。
1 | plt.rcParams['axes.unicode_minus']=False |
pandas plot函数是基于matplotlib的一个在pandas中快速绘图的方法,用法简单,而且兼容所有matplotlib属性设置的函数,所以,你可以用pandas plot函数来绘图,然后调用matplotlib中的函数对可视化图形进行设置,最终达到你心中的预期。
其余参数与matplotlib的参数设置类似,这里不再赘述。
matplotlib是python可视化的鼻祖,绘图全面,多功能是他的优点,几乎没有他不能完成的可视化任务;
但是,他的缺点也很明显,比如:可视化图形配色丑;参数太多,设置琐碎;没有交互式。。。
所以针对这些问题,后人们又开发了许多python的可视化包,比如说:以美观、简洁著称的seaborn、做交互式的plotly、pyecharts等等,后续我看时间允许的话,再出一些教程,大家也可以按需去官网学习,主要是看给出的示例,看关键代码,自己多总结。
P3的项目需要你完完整整得过一遍数据分析的过程,所以呢,单独的某一个数据集肯定满足不了大家,贴心的Udacity给大家准备了几个数据集备选,戳数据集预览,挑一个自己感兴趣的先~