由于第二版是2019年出版,某些库或方法可能已经过时,在此汇总新版本和之前书中的老版本的差异,供大家了解。
在遇到类似于“没有找到方法”、“无法找到库”、“不存在”等类似问题时,可先在这里查看下是否存在现成解决方案。
更新时间:2021-06-12
第一章
1.1 第一章最后的“销售预测应用”部分中的代码需要更新。
原始代码为:
new_x = 84610
pre_y = model.predict(new_x) # 老版本
print(pre_y)
新版本中,需要改为:
new_x = 84610
pre_y = model.predict([[new_x]]) # 新版本
print(pre_y)
第二章
2.1 在“2.2.2 从Excel获取运营数据”中,最新版本的xlrd已经不支持除了xls以外的其他格式(意外,功能竟然缩减),因此使用方法有所变化。
原始代码为:
# 打开文件
xlsx = xlrd.open_workbook('demo.xlsx') # 老版本支持xlsx
# 查看所有sheet列表
print('All sheets: %s' % xlsx.sheet_names())
新版本为:
# 打开文件
xlsx = xlrd.open_workbook('demo.xls') # 新版本只支持xls,其他格式均不支持
# 查看所有sheet列表
print('All sheets: %s' % xlsx.sheet_names())
第三章
3.1 在“3.1 数据清洗:缺失值、异常值和重复值的处理”中“1. 缺失值处理”,其中的缺失值处理库,现在导入方法和名称都发生变化。
导入库
原始版本代码:
import pandas as pd # 导入pandas库
import numpy as np # 导入numpy库
from sklearn.preprocessing import Imputer # 老版本,导入sklearn.preprocessing中的Imputer库
新版本的代码为:
import pandas as pd # 导入pandas库
import numpy as np # 导入numpy库
from sklearn.preprocessing import Imputer # 老版本,导入sklearn.preprocessing中的Imputer库
使用sklearn将缺失值替换为特定值
原始版本代码:
# 使用sklearn将缺失值替换为特定值
nan_model = Imputer(missing_values='NaN', strategy='mean', axis=0) # 老版本,建立替换规则:将值为NaN的缺失值以均值做替换
nan_result = nan_model.fit_transform(df) # 应用模型规则
print(nan_result) # 打印输出
新版本的代码为:
# 使用sklearn将缺失值替换为特定值
# SimpleImputer
nan_model = SimpleImputer(missing_values=np.nan, strategy='mean') # 新版本,建立替换规则:将值为NaN的缺失值以均值做替换
nan_result = nan_model.fit_transform(df) # 应用模型规则
print(nan_result) # 打印输出
3.2 在“ 3.4 解决样本类别分布不均衡的问题 ”中,imblearn的库的用法发生变化。
使用SMOTE方法进行过抽样处理
原版本代码为:
# 使用SMOTE方法进行过抽样处理
model_smote = SMOTE() # 建立SMOTE模型对象
x_smote_resampled, y_smote_resampled = model_smote.fit_sample(x, y) # 老版本,输入数据并作过抽样处理
x_smote_resampled = pd.DataFrame(x_smote_resampled,
columns=['col1', 'col2', 'col3', 'col4', 'col5']) # 将数据转换为数据框并命名列名
y_smote_resampled = pd.DataFrame(y_smote_resampled, columns=['label']) # 将数据转换为数据框并命名列名
smote_resampled = pd.concat([x_smote_resampled, y_smote_resampled], axis=1) # 按列合并数据框
groupby_data_smote = smote_resampled.groupby('label').count() # 对label做分类汇总
print(groupby_data_smote) # 打印输出经过SMOTE处理后的数据集样本分类分布
新版本代码:
# 使用SMOTE方法进行过抽样处理
model_smote = SMOTE() # 建立SMOTE模型对象
x_smote_resampled, y_smote_resampled = model_smote.fit_resample(x, y) # 新版本,输入数据并作过抽样处理
x_smote_resampled = pd.DataFrame(x_smote_resampled,
columns=['col1', 'col2', 'col3', 'col4', 'col5']) # 将数据转换为数据框并命名列名
y_smote_resampled = pd.DataFrame(y_smote_resampled, columns=['label']) # 将数据转换为数据框并命名列名
smote_resampled = pd.concat([x_smote_resampled, y_smote_resampled], axis=1) # 按列合并数据框
groupby_data_smote = smote_resampled.groupby('label').count() # 对label做分类汇总
print(groupby_data_smote) # 打印输出经过SMOTE处理后的数据集样本分类分布
使用RandomUnderSampler方法进行欠抽样处理
原始版本代码:
# 使用RandomUnderSampler方法进行欠抽样处理
model_RandomUnderSampler = RandomUnderSampler() # 建立RandomUnderSampler模型对象
x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled = model_RandomUnderSampler.fit_sample(
n x,
y) # 老版本,输入数据并作欠抽样处理
x_RandomUnderSampler_resampled = pd.DataFrame(x_RandomUnderSampler_resampled,
columns=['col1', 'col2', 'col3', 'col4',
'col5']) # 将数据转换为数据框并命名列名
y_RandomUnderSampler_resampled = pd.DataFrame(y_RandomUnderSampler_resampled,
columns=['label']) # 将数据转换为数据框并命名列名
RandomUnderSampler_resampled = pd.concat(
[x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled],
axis=1) # 按列合并数据框
groupby_data_RandomUnderSampler = RandomUnderSampler_resampled.groupby(
'label').count() # 对label做分类汇总
print(groupby_data_RandomUnderSampler) # 打印输出经过RandomUnderSampler处理后的数据集样本分类分布
新版本代码:
# 使用RandomUnderSampler方法进行欠抽样处理
model_RandomUnderSampler = RandomUnderSampler() # 建立RandomUnderSampler模型对象
x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled = model_RandomUnderSampler.fit_resample(
x,
y) # 新版本,输入数据并作欠抽样处理
x_RandomUnderSampler_resampled = pd.DataFrame(x_RandomUnderSampler_resampled,
columns=['col1', 'col2', 'col3', 'col4',
'col5']) # 将数据转换为数据框并命名列名
y_RandomUnderSampler_resampled = pd.DataFrame(y_RandomUnderSampler_resampled,
columns=['label']) # 将数据转换为数据框并命名列名
RandomUnderSampler_resampled = pd.concat(
[x_RandomUnderSampler_resampled, y_RandomUnderSampler_resampled],
axis=1) # 按列合并数据框
groupby_data_RandomUnderSampler = RandomUnderSampler_resampled.groupby(
'label').count() # 对label做分类汇总
print(groupby_data_RandomUnderSampler) # 打印输出经过RandomUnderSampler处理后的数据集样本分类分布
第四章
4.1 Kmeans的评估方法,新版本中去掉了calinski_harabaz_score方法。
导入库
原始版本代码:
from sklearn.metrics import silhouette_score,calinski_harabaz_score
新版本代码:
from sklearn.metrics import silhouette_score # 效果评估模块, 新版本中已经没有 calinski_harabaz_score 方法
模型效果指标评估
原始版本代码:
# 模型效果指标评估
# 总样本量,总特征数
n_samples, n_features = raw_data.iloc[:,1:].shape
print('samples: %d \t features: %d' % (n_samples, n_features))
# 非监督式评估方法
silhouette_s = silhouette_score(scaled_numeric_features, model_kmeans.labels_, metric='euclidean') # 平均轮廓系数
calinski_harabaz_s = calinski_harabaz_score(scaled_numeric_features, model_kmeans.labels_) # 老版本有,新版本没有该方法了
unsupervised_data = {'silh':[silhouette_s],'c&h':[calinski_harabaz_s]} # 老版本方法
unsupervised_score = pd.DataFrame.from_dict(unsupervised_data)
print('\n','unsupervised score:','\n','-'*60)
print(unsupervised_score)
新版本代码
# 模型效果指标评估
# 总样本量,总特征数
n_samples, n_features = raw_data.iloc[:,1:].shape
print('samples: %d \t features: %d' % (n_samples, n_features))
# 非监督式评估方法
silhouette_s = silhouette_score(scaled_numeric_features, model_kmeans.labels_, metric='euclidean') # 平均轮廓系数
unsupervised_data = {'silh':[silhouette_s]} # 新版本方法
unsupervised_score = pd.DataFrame.from_dict(unsupervised_data)
print('\n','unsupervised score:','\n','-'*60)
print(unsupervised_score)
4.2 “ 4.2 回归分析-案例:大型促销活动前的销售预测 ”中的GradientBoostingRegressor的导入来源库发生变化。
原始版本代码:
from sklearn.ensemble.gradient_boosting import GradientBoostingRegressor # 老
版本,集成算法
新版本代码:
from sklearn.ensemble import GradientBoostingRegressor # 新版本方法
4.3 “ 4.3 分类分析-案例:用户流失预测分析与应用 ”中的“数据预处理”中的SMOTE的调用方法发生变化。
原始版本代码:
# 数据预处理
# 填充缺失值
X = X.fillna(X.mean())
# 样本均衡处理
#'''
model_smote = SMOTE() # 建立SMOTE模型对象
X, y = model_smote.fit_sample(X,y) # 老版本方法,输入数据并作过抽样处理
#'''
新版本代码
# 数据预处理
# 填充缺失值
X = X.fillna(X.mean())
# 样本均衡处理
#'''
model_smote = SMOTE() # 建立SMOTE模型对象
X, y = model_smote.fit_resample(X,y) # 新版本方法,输入数据并作过抽样处理
#'''
4.4 “ 4.4 关联分析 ”中利用Echarts展示商品关联结果图,由于存在v0.5和V1两个互不兼容的版本,因此代码有差异。
导入库
原始版本代码:
from pyecharts import Graph # 老版本导入库
新版本代码
from pyecharts.charts import Graph # 新版本导入
from pyecharts import options as opts # 新版本导入配置方法库
创建关系图
原始版本代码
graph = Graph("商品关联结果图", width=800, height=800)
graph.add("商品名称", nodes, edges, is_label_show=True, is_focusnode=True, is_roam=True,
repulsion=8000, graph_layout='circular',
line_width=2, label_text_size=14, is_random=True)
graph
新版本代码
graph = Graph(init_opts=opts.InitOpts(width="800px", height="800px"))
graph.add("", nodes, edges, repulsion=8000,layout="circular",is_rotate_label=True)
graph.set_global_opts(title_opts=opts.TitleOpts(title="商品关联结果图"))
graph.render_notebook()
另外,调用的R版本,使用了最新的R4.1.0,请读者知悉。其中涉及到的R部分代码,略微做了修改,主要增加了判断库是否存在,如果不存在则自动安装的功能。具体代码如下:
# 定义R
r_script = '''
if (!require('arules'))
install.packages('arules')
library(arules)
data <- read.transactions("order_table.csv", format="single",header=TRUE,cols=c("order_id", "product_name"), sep=",")
init_rules <- apriori(data, parameter = list(support = 0.01, confidence = 0.05, minlen = 2))
sort_rules <- sort(init_rules,by="lift")
rules_pd <- as(sort_rules, "data.frame")
'''
4.5 “4.6 时间序列分析”中的R版本升级为最新的R4.1.0,经过测试,所有代码不变。
第五章
5.1 “ 案例-基于RFM的精细化用户管理 ”中Bar3D库的导入和使用,在原书v0.5和目前的v1版本发生变化。
导入库
原始版本:
from pyecharts import Bar3D # 老版本代码,3D柱形图
新版本代码
from pyecharts.charts import Bar3D # 新版本diam,3D柱形图
from pyecharts import options as opts # 新版本代码,先导入配置方法库
RFM图形展示
原始版本代码
# 老版本,显示图形
bar3d = Bar3D("", width=900, height=600)
range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf',
'#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
bar3d.add(
"rfm分组结果",
"",
"",
[d.tolist() for d in display_data.values],
is_visualmap=True,
visual_range=[0, display_data['number'].max()],
visual_range_color=range_color,
grid3d_width=200,
grid3d_height=80,
grid3d_depth=80
)
bar3d
新版本代码:
# 新版本
bar3d = Bar3D(init_opts=opts.InitOpts(width="900px", height="600px"))
range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf',
'#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
data = [d.tolist() for d in display_data.values]
bar3d.add(
series_name="rfm分组结果",
data=data,
xaxis3d_opts=opts.Axis3DOpts(type_="category"),
yaxis3d_opts=opts.Axis3DOpts(type_="category"),
zaxis3d_opts=opts.Axis3DOpts(type_="value")
)
bar3d.set_global_opts(
visualmap_opts=opts.VisualMapOpts(
max_ =display_data['number'].max(),
range_color=range_color,
)
)
bar3d.render_notebook()
5.2 “ 案例-基于RFM的精细化用户管理 ”中 MySQL写库方法改进
原书中的MySQL写库,采用的是单条写库的方法,原始代码为将commit放到for循环中,导致每次循环时都需要提交,效率低:
for each_value in write_db_data.values:
insert_sql = "INSERT INTO `%s` VALUES ('%s',%s,%s,%s,%s,'%s','%s')" % \
(table_name, each_value[0], each_value[1], each_value[2], \
each_value[3],each_value[4],each_value[5],
timestamp) # 写库SQL依据
cursor.execute(insert_sql) # 执行SQL语句,execute函数里面要用双引号
con.commit() # 提交命令
这种方式会导致写库速度相当慢。因此,仍然是单条写库操作,需要将commit放到for外面,即多次执行后一次性提交:
for each_value in write_db_data.values:
insert_sql = "INSERT INTO `%s` VALUES ('%s',%s,%s,%s,%s,'%s','%s')" % \
(table_name, each_value[0], each_value[1], each_value[2], \
each_value[3],each_value[4],each_value[5],
timestamp) # 写库SQL依据
cursor.execute(insert_sql) # 执行SQL语句,execute函数里面要用双引号
con.commit() # 提交命令
但这种单条写库的操作,对于大量数据时仍然很慢,因此将改成批量写库的方法,新代码具体为:
batch_data = [[*each_value,timestamp] for each_value in write_db_data.values]
query = f"INSERT INTO `{table_name}` VALUES (%s,%s,%s,%s,%s,%s,%s)"
cursor.executemany(query, batch_data) # 执行SQL语句,executemany函数批量写入
con.commit() # 提交命令
5.3 “ 案例-基于嵌套Pipeline和FeatureUnion复合数据工作流的营销响应预测 ”中样本均衡的SMOTE的使用方法发生变化。
原始代码版本:
x_smote_resampled, y_smote_resampled = model_smote.fit_sample(X_train, y_train) # 老版本,输入数据并作过抽样处理
新版本:
x_smote_resampled, y_smote_resampled = model_smote.fit_resample(X_train, y_train) # 新版本,输入数据并作过抽样处理
第六章
6.1 “ 案例-基于集成算法AdaBoost、GradientBoosting、RandomForest和Bagging的投票组合模型的异常检测 ”中的样本均衡SMOT应用方法发生变化。
原始版本代码:
x_smote_resampled, y_smote_resampled = model_smote.fit_sample(X_train, y_train) # 老版本代码,输入数据并作过抽样处理
新版本代码:
x_smote_resampled, y_smote_resampled = model_smote.fit_resample(X_train, y_train) # 新版本代码,输入数据并作过抽样处理
6.2 “ 案例-基于集成算法AdaBoost、GradientBoosting、RandomForest和Bagging的投票组合模型的异常检测 ”中的StratifiedKFold模型交叉检验参数应用方法发生变化。
原始版本代码:
# 交叉检验
model_rf = RandomForestClassifier(max_features=0.8, random_state=0) # 随机森林分类模型对象
model_gdbc = GradientBoostingClassifier(max_features=0.8, random_state=0) # GradientBoosting分类模型对象
estimators = [('randomforest', model_rf), ('gradientboosting', model_gdbc)] # 建立组合评估器列表
model_vot = VotingClassifier(estimators=estimators, voting='soft', weights=[0.9, 1.2],
n_jobs=-1) # 建立组合评估模型
cv = StratifiedKFold(5, random_state=2) # 老版本代码,设置交叉检验方法
cv_score = cross_val_score(model_gdbc, x_smote_resampled, y_smote_resampled, cv=cv) # 交叉检验
print('{:*^60}'.format('Cross val scores:'),'\n',cv_score) # 打印每次交叉检验得分
print('Mean scores is: %.2f' % cv_score.mean()) # 打印平均交叉检验得分
新版本代码:
# 交叉检验
model_rf = RandomForestClassifier(max_features=0.8, random_state=0) # 随机森林分类模型对象
model_gdbc = GradientBoostingClassifier(max_features=0.8, random_state=0) # GradientBoosting分类模型对象
estimators = [('randomforest', model_rf), ('gradientboosting', model_gdbc)] # 建立组合评估器列表
model_vot = VotingClassifier(estimators=estimators, voting='soft', weights=[0.9, 1.2],
n_jobs=-1) # 建立组合评估模型
cv = StratifiedKFold(5) # 新版本代码,设置交叉检验方法
cv_score = cross_val_score(model_gdbc, x_smote_resampled, y_smote_resampled, cv=cv) # 交叉检验
print('{:*^60}'.format('Cross val scores:'),'\n',cv_score) # 打印每次交叉检验
得分
print('Mean scores is: %.2f' % cv_score.mean()) # 打印平均交叉检验得分
第七章
7.1 “ 案例-基于自动K值的KMeans广告效果聚类分析 ”最后输出雷达图时,新版本的plt需要额外对label做封装。
原始代码为:
# 交叉检验
model_rf = RandomForestClassifier(max_features=0.8, random_state=0) # 随机森林分类模型对象
model_gdbc = GradientBoostingClassifier(max_features=0.8, random_state=0) # GradientBoosting分类模型对象
estimators = [('randomforest', model_rf), ('gradientboosting', model_gdbc)] # 建立组合评估器列表
model_vot = VotingClassifier(estimators=estimators, voting='soft', weights=[0.9, 1.2],
n_jobs=-1) # 建立组合评估模型
cv = StratifiedKFold(5) # 新版本代码,设置交叉检验方法
cv_score = cross_val_score(model_gdbc, x_smote_resampled, y_smote_resampled, cv=cv) # 交叉检验
print('{:*^60}'.format('Cross val scores:'),'\n',cv_score) # 打印每次交叉检验得分
print('Mean scores is: %.2f' % cv_score.mean()) # 打印平均交叉检验得分
新版本代码为:
# part1 各类别数据预处理
num_sets = cluster_pd.iloc[:6, :].T.astype(np.float64) # 获取要展示的数据
num_sets_max_min = model_scaler.fit_transform(num_sets) # 获得标准化后的数据
# part2 画布基本设置
fig = plt.figure(figsize=(6,6)) # 建立画布
ax = fig.add_subplot(111, polar=True) # 增加子网格,注意polar参数
labels = np.array(merge_data1.index) # 设置要展示的数据标签
cor_list = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'] # 定义不同类别的颜色
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False) # 计算各个区间的角度
angles = np.concatenate((angles, [angles[0]])) # 建立相同首尾字段以便于闭合
labels = np.concatenate((labels,[labels[0]])) # 新版本增加,对labels进行封闭
# part3 画雷达图
for i in range(len(num_sets)): # 循环每个类别
data_tmp = num_sets_max_min[i, :] # 获得对应类数据
data = np.concatenate((data_tmp, [data_tmp[0]])) # 建立相同首尾字段以便于闭合
ax.plot(angles, data, 'o-', c=cor_list[i], label=i) # 画线
# part4 设置图像显示格式
ax.set_thetagrids(angles * 180 / np.pi, labels, fontproperties="SimHei") # 设置极坐标轴
ax.set_title("各聚类类别显著特征对比", fontproperties="SimHei") # 设置标题放置
ax.set_rlim(-0.2, 1.2) # 设置坐标轴尺度范围
plt.legend(loc=0) # 设置图例位置
我也有过博客,不过那都是很多年前的事情了!
>>> print np.transpose(arr) [[0,3], [1,4], [3,5]] 其中arr[2,0]应该是2
很棒