趁着过年宅家,读了托马兹·卓巴斯的《数据分析实战》,2018年6月出版,本系列为读书笔记。主要是为了系统整理,加深记忆。

关于作者
托马兹·卓巴斯(Tomasz Drabas)是微软的数据科学家,目前工作于西雅图。他拥有超过13年的数据分析经验,行业领域覆盖高新技术、航空、电信、金融以及咨询。
2003年,Tomasz获得战略管理的硕士学位后,从位于波兰华沙的LOT波兰航空公司开启了他的职业生涯。2007年,他前往悉尼,在新南威尔士大学航空学院攻读运筹学博士学位;他的研究结合了离散选择模型和航空作业。在悉尼的日子里,他曾担任过Beyond Analysis Australia公司的数据分析师,沃达丰和记澳大利亚公司的高级数据分析师/数据科学家,以及其他职位。他也发表过学术论文,参加过国际会议,并且担任过学术期刊的审稿人。
2015年,他搬到西雅图,开始在微软工作。在这里他致力于解决高维特征空间的问题。

本书深入数据分析与建模的世界,使用多种方法、工具及算法,提供了丰富的技巧。
  本书第 一部分会讲授一些实战技巧,用于读取、写入、清洗、格式化、探索与理解数据;第二部分由一些较深入的主题组成,比如分类、聚类和预测等。第三部分介绍更高深的主题,从图论到自然语言处理,到离散选择模型,再到模拟。
  通过阅读本书,你将学到:
  - 使用Pandas与OpenRefine读取、清洗、转换与存储数据
  - 使用Pandas与D3.js理解数据,探索变量间的关系
  - 使用Pandas、mlpy、NumPy与Statsmodels,应用多种技法,分类、聚类银行的营销电话
  - 使用Pandas、NumPy与mlpy减少数据集的维度,提取重要的特征
  - 使用NetworkX和Gephi探索社交网络的交互,用图论的概念识别出欺诈行为
  - 通过加油站的例子,学习代理人基建模的模拟技术

第1章讲解了利用多种数据格式与数据库来读取与写入数据的过程,以及使用OpenRefine与Python对数据进行清理。
第2章描述了用于理解数据的多种技巧。我们会了解如何计算变量的分布与相关性,并生成多种图表。
第3章介绍了处理分类问题的种种技巧,从朴素贝叶斯分类器到复杂的神经网络和随机树森林。
第4章解释了多种聚类模型;从最常见的k均值算法开始,一直到高级的BIRCH算法和DBSCAN算法。
第5章展示了很多降维的技巧,从最知名的主成分分析出发,经由其核版本与随机化版本,一直讲到线性判别分析。
第6章涵盖了许多回归模型,有线性的,也有非线性的。我们还会复习随机森林和支持向量机,它们可用来解决分类或回归问题。
第7章探索了如何处理和理解时间序列数据,并建立ARMA模型以及ARIMA模型。
第8章介绍了如何使用NetworkX和Gephi来对图数据进行处理、理解、可视化和分析。
第9章描述了多种与分析文本信息流相关的技巧:词性标注、主题抽取以及对文本数据的分类。
第10章解释了选择模型理论以及一些流行的模型:多项式Logit模型、嵌套Logit模型以及混合Logit模型。
第11章涵盖了代理人基的模拟;我们模拟的场景有:加油站的加油过程,电动车耗尽电量以及狼——羊的掠食。

本文主要记录使用python工具及第1 章内容。

(一)使用工具

1、本人使用python 3.7.5,64位,可官方下载。https://www.python.org/getit/

2、IDE书中推荐使用Anaconda

Anaconda 官方下载 https://www.anaconda.com/distribution/#download-section
注:如果想直接使用全书示例,请使用该版本。如果想学习各个组件的部署,请参照书中指示手工配置各个组件。
Anaconda 是Python的一个发行版,里面内置了很多工具,不用单独安装,因为做了优化也免去了单独安装带来的一些麻烦。
Anaconda 是一种Python语言的免费增值开源发行版,用于进行大规模数据处理、预测分析,和科学计算,致力于简化包的管理和部署。
下载安装过程时不要添加到Path变量,Anaconda会自动搜索你本机已经安装的python版本。

国内镜像下载
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

Spyder是简单高效的IDE,Spyder是Python(x,y)的作者为它开发的一个简单的集成开发环境。和其他的Python开发环境相比,它最大的优点就是模仿MATLAB的“工作空间”的功能,可以很方便地观察和修改数组的值。
个人感觉:
1)普通的笔记本配置运行Anaconda有点吃力,内存专给它4G还好,主要的是硬盘和CPU,明显听到SATA物理硬盘嘎嘎响(后改到SSD分区好些),启动时CPU会近60%。
2)Anaconda+spyder比通用的Eclipse+pyDev要专业的多,当然后者的项目管理功能更强。

邀月推荐:新手用Anaconda即可。毕竟集成了spyder,其中spyder建议手动升级到4.0以上或最新版本。本人钟爱Eclipse,所以使用Eclipse2019-09版本。

 3、PIP国内镜像(主要解决域外服务器不稳定,你一定懂的。)
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/

设置方法:(以清华镜像为例,其它镜像同理)

(1)临时使用:
可以在使用 pip 的时候,加上参数-i和镜像地址(如https://pypi.tuna.tsinghua.edu.cn/simple),
例如:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas,这样就会从清华镜像安装pandas库。

(2)永久修改,一劳永逸:
(a)Linux下,修改 ~/.pip/pip.conf (没有就创建一个文件夹及文件。文件夹要加“.”,表示是隐藏文件夹)
内容如下:

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn

(b) windows下,直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,然后新建文件pip.ini,即 %HOMEPATH%\pip\pip.ini,在pip.ini文件中输入以下内容(以豆瓣镜像为例):

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn

4、如果不喜欢pip,可以使用conda,本文不赘述,同样要注意设置清华镜像站点。

本人使用win10+以上环境,编译过了书中96%以上的代码,其中报错咎,后续文中详述。本文末尾附上随书源代码下载地址。

(二)第1 章内容:

第1章 准备数据

本章内容涵盖了使用Python和OpenRefine来完成读取、存储和清理数据这些基本任务。你将学习以下内容:

·使用Python读写CSV/TSV文件

·使用Python读写JSON文件

·使用Python读写Excel文件

·使用Python读写XML文件

·使用pandas检索HTML页面

·存储并检索关系数据库

·存储并检索MongoDB

·使用OpenRefine打开并转换数据

·使用OpenRefine探索数据

·排重

·使用正则表达式与GREL清理数据

·插补缺失值

·将特性规范化、标准化

·分级数据

·编码分类变量

1.2使用python读取CSV/TSV文件

独立安装 pandas
pip install pandas

官方文档在这里:
https://pandas.pydata.org/pandas-docs/stable/

/*
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
........
Installing collected packages: pytz, numpy, python-dateutil, pandas
Successfully installed numpy-1.17.4 pandas-0.25.3 python-dateutil-2.8.1 pytz-2019.3
FINISHED
*/


读取CSV:
https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-read-csv-table

padas读取大容量数据的速度,不得不赞一下。

Tips:
1、python3 写CSV文件多一个空行
解决方案:打开文件的时候多指定一个参数。

#write to files
with open(w_filenameCSV,'w',newline='') as write_csv:
    write_csv.write(tsv_read.to_csv(sep=',', index=False)) 

1.3使用python读取JSON文件
独立安装 pandas 同上,略

读取CSV:
https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-json-reader


1.4使用python读取Excel文件
独立安装 pandas 同上,略

Tips:

/*
 Module Not Found Error: No module named 'openpyxl'
 */


解决方案:pip install openpyxl

Tips2:

/*
Traceback (most recent call last):
  File "D:\Java2018\practicalDataAnalysis\Codes\Chapter01\read_xlsx_alternative.py", line 16, in <module>
    labels = [cell.value for cell in xlsx_ws.rows[0]]
TypeError: 'generator' object is not subscriptable
*/


解决方案:
1、改代码

# name of files to read from
r_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

# open the Excel file
xlsx_wb = oxl.load_workbook(filename=r_filenameXLSX)

# extract the 'Sacramento' worksheet
xlsx_ws =  xlsx_wb.active #默认第一个sheet

labels=[]
for row in  xlsx_ws.iter_cols(min_row=1,max_row=1):
    labels+=([cell.value for cell in row])

# extract the data and store in a list
# each element is a row from the Excel file
data = []
for row in  xlsx_ws.iter_rows(min_row=1,max_col=10, max_row=10):
    data.append([cell.value for cell in row])


###print the prices of the first 10 properties
print( [item[labels.index('price')] for item in data[0:10]] )


2、修改openpyxl版本
pip install -I openpyxl==2.3.3

3、采用其他插件如xlrd

 # name of files to read from
r_filenameXLSX = '../../Data/Chapter01/realEstate_trans.xlsx'

try:
    # 打开文件
    xlsx_wb = exls.open_workbook(r_filenameXLSX)
    #sheet2_name = workbook.sheet_names() # 获取所有sheet名称
    #print(sheet2_name)
    # 根据sheet索引或者名称获取sheet内容
    xlsx_ws = xlsx_wb.sheet_by_index(0) # sheet索引从0开始
    # sheet1 = workbook.sheet_by_name('sheet2')
    # sheet1的名称,行数,列数
    print("sheet名:"+xlsx_ws.name, "",str(xlsx_ws.nrows)+"", str(xlsx_ws.ncols)+"")
    s="";
    labels=xlsx_ws.row_values(0,1,10)

    data=[]
    # first 10 rows of xlsx_ws.nrows
    for rownum in range(0, 10):
        #first 10 columns of xlsx_ws.ncols
        data.append(xlsx_ws.row_values(rownum,1,10))
    # print(labels)
    # print(data)

    print( [item[labels.index('price')] for item in data[0:10]] )

except Exception as e:
    print(e)

    



1.5使用python读取XML文件
独立安装 pandas 同上,略

1.6使用python读取html文件
独立安装 pandas 同上,略
独立安装 re 正则表达式模块
pip install html5lib

/*
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
........
Installing collected packages: webencodings, html5lib
Successfully installed html5lib-1.0.1 webencodings-0.5.1
FINISHED
 */


 Tips:ImportError: lxml not found, please install it

/*
   File "D:\tools\Python37\lib\site-packages\pandas\io\html.py", line 843, in _parser_dispatch
    raise ImportError("lxml not found, please install it")
ImportError: lxml not found, please install it
 */


 解决方案pip install lxml

 Tips:ImportError: BeautifulSoup4 (bs4) not found, please install it

/*
  File "D:\tools\Python37\lib\site-packages\pandas\io\html.py", line 837, in _parser_dispatch
    raise ImportError("BeautifulSoup4 (bs4) not found, please install it")
ImportError: BeautifulSoup4 (bs4) not found, please install it
 */

 解决方案pip install BeautifulSoup4
 
 示例:
 https://programtalk.com/python-examples/pandas.read_html/
 
 1.7存储并检索关系数据库
独立安装 pandas 同上,略
独立安装 sqlalchemy,psycopg2
pip install sqlalchemy
--pip install psycopg2
sqlalchemy支持各特别是常见数据库,比如mySQL,Oracle,SqlLite,PostgreSQL等


 1 /*
 2 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
 3 ........
 4 Installing collected packages: sqlalchemy
 5 Successfully installed sqlalchemy-1.3.11
 6 FINISHED
 7
 8
 9 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
10 Collecting psycopg2
11   Downloading https://pypi.tuna.tsinghua.edu.cn/packages/1a/85/853f11abfccfd581b099e5ae5f2dd807cc2919745b13d14e565022fd821c/psycopg2-2.8.4-cp37-cp37m-win_amd64.whl (1.1MB)
12 Installing collected packages: psycopg2
13 Successfully installed psycopg2-2.8.4
14 FINISHED
15
16
17
18 D:\tools\Python37\lib\site-packages\dateutil\parser\_parser.py:1218: UnknownTimezoneWarning: tzname EDT identified but not understood.  Pass `tzinfos` argument in order to correctly return a timezone-aware datetime.  In a future version, this will raise an exception.
19   category=UnknownTimezoneWarning)
20    index            street        city  ...  price   latitude   longitude
21 0      0      3526 HIGH ST  SACRAMENTO  ...  59222  38.631913 -121.434879
22 1      1       51 OMAHA CT  SACRAMENTO  ...  68212  38.478902 -121.431028
23 2      2    2796 BRANCH ST  SACRAMENTO  ...  68880  38.618305 -121.443839
24 3      3  2805 JANETTE WAY  SACRAMENTO  ...  69307  38.616835 -121.439146
25 4      4   6001 MCMAHON DR  SACRAMENTO  ...  81900  38.519470 -121.435768
26
27 [5 rows x 13 columns] */
View Code



1.8存储并检索MongoDB
独立安装 pandas 同上,略
独立安装 PyMongo
pip install --upgrade PyMongo


1.9使用OpenRefine打开并转换数据
下载:https://github.com/OpenRefine/OpenRefine/releases

(substring(value,4,10)+','+substring(value,24,29)).toDate()

1.10使用OpenRefine探索数据

 
 1.11排重
 
 1.12使用正则表达式与GREL清理数据
 

 --value.match(/(.*)(..)(\d{5})/)[0],注意空格
 value.match(/(.*) (..) (\d{5})/)[0]--city
 value.match(/(.*) (..) (\d{5})/)[1]--State
 value.match(/(.*) (..) (\d{5})/)[2]--zip

 
 1.13插补缺失值

 # impute mean in place of NaNs
#估算平均数以替代空值
csv_read['price_mean'] = csv_read['price'] \
    .fillna(
        csv_read.groupby('zip')['price'].transform('mean')
    )

# impute median in place of NaNs
#估算中位数以替代空值
csv_read['price_median'] = csv_read['price'] \
    .fillna(
        csv_read.groupby('zip')['price'].transform('median')
    )


    
1.14将特征规范化、标准化
数据规范化:让所有的数都落在0与1的范围内(闭区间)
数据标准化:移动其分布,使得数据的平均数是0,标准差是1
规范化数据,即让每个值都落在0和1之间,我们减去数据的最小值,并除以样本的范围。统计学上的范围指的是最大值与最小值的差。normalize(...)方法就是做的前面描述的工作:对数据的集合,减去最小值,除以范围。
标准化的过程类似:减去平均数,除以样本的标准差。这样,处理后的数据,平均数为0而标准差为1。standardize(...)方法做了这些处理:

def normalize(col):
    #Normalize column 规范化
     return (col - col.min()) / (col.max() - col.min())

def standardize(col):
     #Standardize column 标准化
    return (col - col.mean()) / col.std()


1.15分级数据
当我们想查看数据分布的形状,或将数据转换为有序的形式时,数据分级就派上用场了。
独立安装 pandas 同上,略
独立安装 Numpy
pip install numpy


分位数与百分位数有紧密的联系。区别在于百分位数返回的是给定百分数的值(即间隔均匀),而分位数返回的是给定分位点的值(即数目大致相等)。
想了解更多,可访问https://www.stat.auckland.ac.nz/~ihaka/787/lectures-quantiles-handouts.pdf
1)以下代码取百分位数:

#    根据线性划分的价格的范围,创建间隔相等的价格容器
#   示例linspace(0,6,6)==>[0,,1.2,,2.4,,3.6,,4.8,,6.0]
bins = np.linspace(
    csv_read['price_mean'].min(),
    csv_read['price_mean'].max(),
    6
)

# and apply the bins to the data
#  将容器应用到数据上,digitize第一个参数是要分级的列,第二个参数是容器的数组
csv_read['b_price'] = np.digitize(
    csv_read['price_mean'],
    bins
)

# print out the counts for the bins
#  每个容器中的记录计数
counts_b = csv_read['b_price'].value_counts()
print(counts_b.sort_index())


有时候我们不会用均匀间隔的值,我们会让每个箱中拥有相同的数目。要达成这个目标,我们可以使用分位数。
我们想把列拆成十分位数,即10个(差不多)相等的容器。要做到这点,我们可以使用下面的代码:

# create bins based on deciles
# 创建基于十分位数的箱子,即每个箱中拥有差不多相同的数目
decile = csv_read['price_mean'].quantile(np.linspace(0,1,11))

# and apply the decile bins to the data
# 对数据应用分数位
csv_read['p_price'] = np.digitize(
    csv_read['price_mean'],
    decile
)

# print out the counts for the percentile bins
counts_p = csv_read['p_price'].value_counts()
print(counts_p.sort_index())



.quantile(...)方法可以传一个(0到1之间的)数字,来表明要返回的分位数(例如,0.5是中位数,0.25和0.75是上下四分位数)。它也可以传入一个分位的列表,返回相应的值的数组。.linspace(0,1,11)方法会生成这个数组:.quantile(...)方法会以price_mean列的最小值开始,直到最大值,返回十分位数的列表。

/*
1    350
2    480
3    118
4     26
5      4
6      3
Name: b_price, dtype: int64
1      96
2     100
3      98
4      98
5      97
6      97
7      99
8      97
9      99
10     97
11      3
Name: p_price, dtype: int64
 */




1.16编码数据变量
最后一步就是分类变量。
统计模型只能接受有序的数据。分类变量(有时根据上下文可表示为数字)不能直接在模型中使用。要使用它们,我们要先进行编码,也就是给它们一个唯一的数字编号。

Tips:

# dummy code the column
# 根据房产类型列[type]处理的简单代码
# prefix指定以d开头,本例中是d_Condo,可通过prefix_sep参数修改
csv_read = pd.get_dummies(
    csv_read,
    prefix='d',
    columns=['type']
)


结果生成4个水平列:
d_Condo、d_Multi-Family、d_Residential、d_Unkown


官方文档:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html

第1 章完。

随书源码官方下载:
http://www.hzcourse.com/web/refbook/detail/7821/92

02-14 03:33