-
使用飞桨构建波士顿房价预测模型
2020-05-17 12:11:38使用飞桨构建波士顿房价预测模型当读者习惯使用飞桨框架后会发现程序呈现出“八股文”的形态,即不同的程序员、使用不同模型、解决不同任务的时候,他们编写的建模程序是极其相似的。只要通过一个示例程序掌握使用飞桨的方法,编写不同任务的多种建模程序将变得容易。
使用飞桨构建波士顿房价预测模型
图1 使用飞桨框架构建神经网络过程
在数据处理之前,需要先加载飞桨框架的相关类库。
#加载飞桨、Numpy和相关类库 inport paddle import paddle.fluid as fluid import paddle.fluid.dygraph as dygraph #动态图 from paddle.fluid.dygraph import FC #全连接层 import numpy as np import os import random
代码中参数含义如下:
paddle/fluid:飞桨的主库,目前大部分的实用函数均在paddle.fluid包内。dygraph:动态图的类库,用户无需预先定义完整的网络结构,每写一行网络代码,即可同时获得结果。
FC:神经网络的全连接层函数,即包含所有输入权重相加和激活函数的基本神经元结构。在房价预测任务中,使用只有一层的神经网络(全连接层)来实现线性回归模型。
数据处理:
数据处理的代码不依赖于框架实现。
def load_data(): #从文件导入数据 datafile = './work/housing.data' data = np.formfile(datafile, sep='') #每条数据包括14项,其中前面13项是影响因素,第14项是相应的房屋价格中位数 feature_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', \ 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] feature_num = len(feature_names) #将原始数据进行Reshape,变成[N,14]这样的形状 data = data.reshape([data.shape[0] // feature_num, feature_num]) #将原数据集拆成训练集和测试集 #这里使用80%的数据做训练,20%的数据做测试 #测试集和训练集必须是没有交集的 ratio = 0.8 offset = int(data.shape[0] * ratio) training_data = data[:offset] #计算train数据集的最大值,最小值,平均值 maximums, minimums,avgs = training_data.max(axis=0),training_data.min(axis=0),\ training_data.sum(axis=0) / training_data.shape[0] #记录数据的归一化参数,在预测时对数据做归一化 global max_values global min_values global avg_values max_values = maxmums min_values = minmums avg_values = avgs #对数据进行归一化处理 for i in range(feature_num): data[:,1] = (data[:i] - avgs[i]) / (maximums[i] - minimums[i]) #训练集和测试集的划分比例 training_data = data[:offset] test_data = data[offset:] return training_data, test_data
模型设计:
模型定义的实质是自定义线性回归的网络结构,飞桨通过创建python类的方式完成模型网络的定义,即定义init函数和forward函数。forward函数是框架指定实现前向计算逻辑的函数,程序在调用模型实例时会自动执行forward方法。在forward函数中使用的网络层需要在init函数中声明。
实现过程分如下两步:
1.定义init函数:在类的初始化函数中声明每一层网络的实现函数。在房价预测模型中,只需定义一层全连接层FC.
2.定义forward函数:构建神经网络结构,实现前向计算过程,并返回预测结果,在本次任务中返回的是房价预测结果。
class Regressor(fluid.dygraph.Layer): def_init_(self, name_scope): super(Regressor, self)._init_(name_scope) name_scope = self.full_name() #定义一层全连接层,输出维度是1,激活函数是None,既不是用激活函数 self.fc = Linear(input_dim=13, output_dim=1, act=None) #网络的前向计算函数 def forward(self,inputs): x = self.fc(inputs)#把输入做全连接层 return x
训练配置:
训练配置过程包含四步,如图所示:
#定义飞桨动态图的工作环境,以grard函数指定运行训练的机器资源,表明在with作用域下的程序均执行在本机的CPU资源上。 #dygraph.guard表示在with作用域下的程序会以飞桨动态图的模式执行 with fluid.dygraph.guard(): #声明定义好的线性回归模型, model =Regressor("Regressor") #开启模型训练模式 model.train() #load_data函数加载训练数据和测试数据 training_data, test_data = load_data() #定义优化算法,这里使用随机梯度下降——SGD #学习率设置为0.01 opt = fluid.optimizer.SGD(learning_rate=0.01,parameter_list=model.parameters())
我们实现梯度下降法编写了大量代码,而使用飞桨框架只需要定义SDG就可以实现优化器设置。
训练过程:
训练过程采用二层循环嵌套方式:
内层循环:负责整个数据集的一次遍历,采用分批次方式(batch).假设数据集样本数量为1000,一个批次有10个样本,则遍历一次数据集的批次数量是1000/10=100,即内层循环需要执行100次。
外层循环:定义遍历数据集的次数,通过参数epoch_num设置
batch的取值会影响模型训练效果。batch过大,会增加内存消耗和计算时间,且效果不会明显提升。batch过小,每个batch的样本数据将会没有意义。由于房价预测模型的训练数据集较小,这里我们设置batch的数量为10.
每次内循环都需要执行如下四个步骤,如图
图 内循环计算过程
1.数据准备:将一个批次的数据转变成np.array和内置格式。
2.前向计算:将一个批次的样本数据装入网络,计算输出结果
3.计算损失函数:以前向计算的结果和真实结果,通过损失函数square_error_cost计算出损失函数值(Loss)
4.反向传播:执行梯度反向传播backward函数,即从后到前逐层计算每一层的梯度,并根据设置的优化算法更新参数opt.minimize.
with dygraph.guard(fluid.CPUPlace()): EPOCH_NUM = 10 # 设置外层循环次数 BATCH_SIZE = 10 # 设置batch大小 # 定义外层循环 for epoch_id in range(EPOCH_NUM): # 在每轮迭代开始之前,将训练数据的顺序随机的打乱 np.random.shuffle(training_data) # 将训练数据进行拆分,每个batch包含10条数据 mini_batches = [training_data[k:k+BATCH_SIZE] for k in range(0, len(training_data), BATCH_SIZE)] # 定义内层循环 for iter_id, mini_batch in enumerate(mini_batches): x = np.array(mini_batch[:, :-1]).astype('float32') # 获得当前批次训练数据 y = np.array(mini_batch[:, -1:]).astype('float32') # 获得当前批次训练标签(真实房价) # 将numpy数据转为飞桨动态图variable形式 house_features = dygraph.to_variable(x) prices = dygraph.to_variable(y) # 前向计算 predicts = model(house_features) # 计算损失 loss = fluid.layers.square_error_cost(predicts, label=prices) avg_loss = fluid.layers.mean(loss) if iter_id%20==0: print("epoch: {}, iter: {}, loss is: {}".format(epoch_id, iter_id, avg_loss.numpy())) # 反向传播 avg_loss.backward() # 最小化loss,更新参数 opt.minimize(avg_loss) # 清除梯度 model.clear_gradients() # 保存模型 fluid.save_dygraph(model.state_dict(), 'LR_model')
结果如下
epoch: 0, iter: 0, loss is: [0.2289829] epoch: 0, iter: 20, loss is: [0.09159696] epoch: 0, iter: 40, loss is: [0.03548922] epoch: 1, iter: 0, loss is: [0.05100339] epoch: 1, iter: 20, loss is: [0.07086861] epoch: 1, iter: 40, loss is: [0.08796145] epoch: 2, iter: 0, loss is: [0.03347154] epoch: 2, iter: 20, loss is: [0.13305981] epoch: 2, iter: 40, loss is: [0.05589986] epoch: 3, iter: 0, loss is: [0.07707483] epoch: 3, iter: 20, loss is: [0.08691163] epoch: 3, iter: 40, loss is: [0.069935] epoch: 4, iter: 0, loss is: [0.03368948] epoch: 4, iter: 20, loss is: [0.01867739] epoch: 4, iter: 40, loss is: [0.04288226] epoch: 5, iter: 0, loss is: [0.09595467] epoch: 5, iter: 20, loss is: [0.05239206] epoch: 5, iter: 40, loss is: [0.01245855] epoch: 6, iter: 0, loss is: [0.01723538] epoch: 6, iter: 20, loss is: [0.04102365] epoch: 6, iter: 40, loss is: [0.02536126] epoch: 7, iter: 0, loss is: [0.0421977] epoch: 7, iter: 20, loss is: [0.0456106] epoch: 7, iter: 40, loss is: [0.01641047] epoch: 8, iter: 0, loss is: [0.04945276] epoch: 8, iter: 20, loss is: [0.0992526] epoch: 8, iter: 40, loss is: [0.10382986] epoch: 9, iter: 0, loss is: [0.02595497] epoch: 9, iter: 20, loss is: [0.01914127] epoch: 9, iter: 40, loss is: [0.00614125]
保存并测试模型:
将模型当前的参数数据
model.state_dict()
保存到文件中(通过参数指定保存的文件名 LR_model),以备预测或校验的程序调用,代码如下所示。#定义飞桨动态图工作环境 with fluid.dygraph.guard(): #保存模型参数,文件名为LR_model fluid.save_dygraph(model.state_dict, 'LR_model') print("模型保存成功,模型参数保存在LR_model中")
模型测试:
下面我们选择一条数据样本,测试下模型的预测效果。测试过程和在应用场景中使用模型的过程一致,主要可分成如下三个步骤:
- 配置模型预测的机器资源。本案例默认使用本机,因此无需写代码指定。
- 将训练好的模型参数加载到模型实例中。由两个语句完成,第一句是从文件中读取模型参数;第二句是将参数内容加载到模型。加载完毕后,需要将模型的状态调整为
evalueation
(校验)。上文中提到,训练状态的模型需要同时支持前向计算和反向传导梯度,模型的实现较为臃肿,而校验和预测状态的模型只需要支持前向计算,模型的实现更加简单,性能更好。 - 将待预测的样本特征输入到模型中,打印输出的预测结果。
通过
load_one_example
函数实现从数据集中抽一条样本作为测试样本,具体实现代码如下所示。def load_one_example(data_dir): f = open(data_dir, 'r') datas = f.readlines() # 选择倒数第10条数据用于测试 tmp = datas[-10] tmp = tmp.strip().split() one_data = [float(v) for v in tmp] # 对数据进行归一化处理 for i in range(len(one_data)-1): one_data[i] = (one_data[i] - avg_values[i]) / (max_values[i] - min_values[i]) data = np.reshape(np.array(one_data[:-1]), [1, -1]).astype(np.float32) label = one_data[-1] return data, label
with dygraph.guard(): # 参数为保存模型参数的文件地址 model_dict, _ = fluid.load_dygraph('LR_model') model.load_dict(model_dict) model.eval() # 参数为数据集的文件地址 test_data, label = load_one_example('./work/housing.data') # 将数据转为动态图的variable格式 test_data = dygraph.to_variable(test_data) results = model(test_data) # 对结果做反归一化处理 results = results * (max_values[-1] - min_values[-1]) + avg_values[-1] print("Inference result is {}, the corresponding label is {}".format(results.numpy(), label))
结果如下所示:
-
思维模型 波士顿矩阵
2021-03-16 10:20:021 模型故事 以白酒市场为例,能经久不衰的酒品牌并不多,能维持三年五载的品牌已经是不错了,“一年喝倒一个牌子”成为白酒品牌中常有的事。酒类商品作为快速消品,近年品牌链不断延长,一个酒品牌往往有高中低档...1 模型故事
@1 波士顿矩阵在白酒市场中酒类营销中的运用
以白酒市场为例,能经久不衰的酒品牌并不多,能维持三年五载的品牌已经是不错了,“一年喝倒一个牌子”成为白酒品牌中常有的事。酒类商品作为快速消品,近年品牌链不断延长,一个酒品牌往往有高中低档全部的品种,同时为了实现品牌的差异化,总会有新品推出,这些变化就连“茅五剑”这些名牌,也在不断采用。某一酒类经销公司经营A、B 、C 、D 、E、F、G7个品牌的酒品,公司可用资金50万。经对前半年的市场销售统计分析,发现:
- A、B品牌业务量为总业务量的70%,两个品牌的利润占到总利润的75%,在本地市场占主导地位。但这两个品牌是经营了几年的老品牌,从去年开始市场销售增长率已成下降趋势,前半年甚至只能维持原来业务量;
- C、D、E三个品牌是新开辟的新品牌。其中C、D两个品牌前半年表现抢眼,C品牌销售增长了 20%,D品牌增长了18%,且在本区域内尚是独家经营。E品牌是高档产品,利润率高,销售增长也超过了10%,但在本地竞争激烈,该品牌其它两家主要竞争对手所占市场比率达到70%,而公司只占到10%左右;
- F、G两个品牌市场销售下降严重,有被C、D品牌替代的趋势,且在竞争中处于下风,并出现了滞销和亏损现象。
针对上述情况,根据波士顿矩阵原理,采取如下措施:
- 确认C、D品牌为新星品牌,虽然目前不是公司的主要利润来源,但发展潜力很大,决定加大资金投放力度,加快发展步伐,扩大与竞争对手的差距,力争成为公司新的利润增长点。决定先期投入资金10万元。
- 确认E 为 问题品牌,对E品牌投入研究力量,寻找竞争对手薄弱方面,整合资源,争取扩大市场份额,使E品牌成为新星品牌。决定投入资金5万元。余下5万元作为机动资金,以便在特殊情况下,对某品牌作侧重支持。
- 确认A、B品牌为金牛品牌,维持原来的资金投入30万元,以保证市场占有率和公司的主要利润来源,同时也认识到A、B品牌已经出现了衰退现象,要认真找出原因,一方面寻找替代品牌,一方面尽可能地延长其生命力。
- 确认 F、G为 瘦狗品牌,对F、G品牌果断采取撤退战略,不再投入资金,着手清理库存,对滞销商品降价处理,尽快回笼资金。
@2 使用波士顿矩阵明确产品定位和发展方向
上海和达汽车零部件有限公司是由某国内上市公司与外商合的生产汽车零部件的企业。公司于1996年正式投产.配套厂海大众发、一汽大众、上海通用、东风柳汽、吉利、湖南长风武等。和达公司的主要产品分成五类,一是挤塑和复合挤塑类(密封嵌条、车顶饰条等);二是滚压折弯类(车门导槽、滑轨、车架管;三是普通金属焊接类(汽车仪表板横梁模块);四是激光焊接镁合金横梁模块);五是排档杆类(手动排档总成系列)。和达公司产品波士顿矩阵分析如下:
BCG Matrix 解读如下:
- 明星型业务(Stars,指高增长、高市场份额):这个领域中的产品处于快速增长的市场中并且占有支配地位份额。但也许不会产生正现金流量。但因为市场还在高速成业必须继续投资,以保持与市场同步增长,并击退竞争对手。对于和达公司来说,铝横梁的真空电子束焊接系统是国内第一家。具有技术上的领先优势。因此企业应该加大对这一产品的投入.以继续保持技术上的领先地位。对于排档杆类产品.由于国内在这个领域的竞争程度还不太激烈,因此可以考虑进入。和达公司应该把这类产品作为公司的明星业务来培养.要加大对这方面的资金支持。在技术上应充分利用和寻找国外已具有同等类似产品的厂商进行合作。
- 问题型业务(Question Marks.指高增长、低市场份额):处在这个领域中的是一些投机性产品。这些产品可能利润率但占有的市场份额很小。公司必须慎重回答“是否继续投资.业务?”这个问题。只有那些符合企业发展长远目标、企业具优势、能够增强企业核心竞争力的业务才得到肯定的回答。从和达公司的情况来看。滚压折弯类产品由于技术含量不高、槛低,未来市场竞争程度必然加剧。所以对于这类产品.最好就是舍弃。由于目前还能带来利润,不必迅速退出,只要目前持必要的市场份额,公司不必再增加投入。当竞争对手大举,可以舍弃。
- C 现金牛业务(Cash COWS,指低增长、高市场份额):处在这个领域中的产品产生大量的现金。但未来的增长前景是有限的。由于市场已经成熟。企业不必大量投资来扩展市场规模.同时作为市场中的领导者。该业务享有规模经济和高边际利润的优势,因而给企业带来大量现金流。对于和达公司来说,其普通金属焊接类产品即是现金牛类产品。由于进入市场的时机较早。产品价格不错.每年能够给企业带来相当的利润。因此对于和达公司来说,对于金属焊接类产品,应该保持住目前的市场份额.把从这个产品中获取的利润投入到铝横梁和排档杆的产品中去。
- D 瘦狗型业务(Dogs,指低增长、低市场份额):这个剩下的领域中的产品既不能产生大量的现金,也不需要投入大量现金,这些产品没有希望改进其绩效。瘦狗型业务通常要占用很多资源。多数时候是得不偿失的。对于和达公司来说,普通塑料异型挤出和异型体复合挤出类产品因设备陈旧等原因。在国内已落后于主要竞争对手。从公司战略的角度出发,应该不断对这一块进行收缩.不必再投入更大的精力和财力,逐渐把注意力集中在激光焊接和排档杆的业务上去。
通过运用波士顿矩阵分析,使和达公司明确了产品定位和发展方向,对于企业投资的选择起到了举足轻重的作用。但波士顿矩阵仅仅是一个工具.问题的关键在于要解决如何使企业的产品品种及其结构适合市场需求的变化。只有这样企业的生产才有意义。同时,如何将企业有限的资源有效地分配到合理的产品结构中去。以保证企业收益。是企业在激烈竞争中能否取胜的关键。
@3 产品分析
波士顿矩阵分析乳业产品如下所示:
波士顿矩阵分析 肯德基产品 如下所示:
2 模型 波士顿矩阵
@1 波士顿矩阵简介
制定公司层战略最流行的方法之一就是BCG Matrix(Boston Consulting Group, BCG,波士顿矩阵)。该方法是由波士顿咨询集团在上世纪70年代初开发的。BCG矩阵将组织的每一个战略事业单位(SBUs)标在一种2维的矩阵图上,从而显示出哪个SBUs提供高额的潜在收益,以及哪个SBUs是组织资源的漏斗。BCG矩阵的发明者、波士顿公司的创立者布鲁斯认为“公司若要取得成功,就必须拥有增长率和市场份额各不相同的产品组合。组合的构成取决于现金流量的平衡。”如此看来,BCG的实质是为了通过业务的优化组合实现企业的现金流量平衡。BCG矩阵区分出4种业务组合。
- 明星型业务(Stars,指高增长、高市场份额):这个领域中的产品处于快速增长的市场中并且占有支配地位的市场份额,但也许会或也许不会产生正现金流量,这取决于新工厂、设备和产品开发对投资的需要量。明星型业务是由问题型业务继续投资发展起来的,可以视为高速成长市场中的领导者,它将成为公司未来的现金牛业务。但这并不意味着明星业务一定可以给企业带来源源不断的现金流,因为市场还在高速成长,企业必须继续投资,以保持与市场同步增长,并击退竞争对手。企业如果没有明星业务,就失去了希望,但群星闪烁也可能会闪花企业高层管理者的眼睛,导致做出错误的决策。这时必须具备识别行星和恒星的能力,将企业有限的资源投入在能够发展成为现金牛的恒星上。同样的,明星型业务要发展成为现金牛业务适合于采用增长战略。
- 问题型业务(Question Marks,指高增长、低市场份额):处在这个领域中的是一些投机性产品,带有较大的风险。这些产品可能利润率很高,但占有的市场份额很小。这往往是一个公司的新业务。为发展问题业务,公司必须建立工厂,增加设备和人员,以便跟上迅速发展的市场,并超过竞争对手,这些意味着大量的资金投入。“问题”非常贴切地描述了公司对待这类业务的态度,因为这时公司必须慎重回答“是否继续投资,发展该业务?”这个问题。只有那些符合企业发展长远目标、企业具有资源优势、能够增强企业核心竞争力的业务才得到肯定的回答。得到肯定回答的问题型业务适合于采用战略框架中提到的增长战略,目的是扩大SBUs的市场份额,甚至不惜放弃近期收入来达到这一目标,因为问题型要发展成为明星型业务,其市场份额必须有较大的增长。得到否定回答的问题型业务则适合采用收缩战略。如何选择问题型业务是用BCG矩阵制定战略的重中之重,也是难点,这关乎企业未来的发展。对于增长战略中各种业务增长方案来确定优先次序,BCG也提供了一种简单的方法。通过下图权衡选择ROI相对高然后需要投入的资源占的宽度不太多的方案。
- 现金牛业务(Cash cows,指低增长、高市场份额):处在这个领域中的产品产生大量的现金,但未来的增长前景是有限的。这是成熟市场中的领导者,它是企业现金的来源。由于市场已经成熟,企业不必大量投资来扩展市场规模,同时作为市场中的领导者,该业务享有规模经济和高边际利润的优势,因而给企业带来大量现金流。企业往往用现金牛业务来支付帐款并支持其他三种需大量现金的业务。现金牛业务适合采用战略框架中提到的稳定战略,目的是保持SBUs的市场份额。
- 瘦狗型业务(Dogs,指低增长、低市场份额):这个剩下的领域中的产品既不能产生大量的现金,也不需要投入大量现金,这些产品没有希望改进其绩效。一般情况下,这类业务常常是微利甚至是亏损的,瘦狗型业务存在的原因更多的是由于感情上的因素,虽然一直微利经营,但象人养了多年的狗一样恋恋不舍而不忍放弃。其实,瘦狗型业务通常要占用很多资源,如资金、管理部门的时间等,多数时候是得不偿失的。瘦狗型业务适合采用战略框架中提到的收缩战略,目的在于出售或清算业务,以便把资源转移到更有利的领域。
@2 为什么要使用波士顿矩阵?
它的精髓在于把战略规划和资本预算紧密结合了起来,把一个复杂的企业行为用两个重要的衡量指标来分为四种类型,用四个相对简单的分析来应对复杂的战略问题。该矩阵帮助多种经营的公司确定哪些产品宜于投资,宜于操纵哪些产品以获取利润,宜于从业务组合中剔除哪些产品,从而使业务组合达到最佳经营成效。
@3 应对策略
波士顿矩阵对于企业产品所处的四个象限具有不同的定义和相应的战略对策。
- 明星产品(stars)。它是指处于高增长率、高市场占有率象限内的产品群,这类产品可能成为企业的现金牛产品,需要加大投资以支持其迅速发展。采用的发展战略是:积极扩大经济规模和市场机会,以长远利益为目标,提高市场占有率,加强竞争地位。发展战略以及明星产品的管理与组织最好采用事业部形式,由对生产技术和销售两方面都很内行的经营者负责。
- 问题产品(question marks)。它是处于高增长率、低市场占有率象限内的产品群。前者说明市场机会大,前景好,而后者则说明在市场营销上存在问题。其财务特点是利润率较低,所需资金不足,负债比率高。例如在产品生命周期中处于引进期、因种种原因未能开拓市场局面的新产品即属此类问题的产品。对问题产品应采取选择性投资战略。因此,对问题产品的改进与扶持方案一般均列入企业长期计划中。对问题产品的管理组织,最好是采取智囊团或项目组织等形式,选拔有规划能力,敢于冒风险、有才干的人负责。
- 现金牛产品(cash cow),又称厚利产品。它是指处于低增长率、高市场占有率象限内的产品群,已进入成熟期。其财务特点是销售量大,产品利润率高、负债比率低,可以为企业提供资金,而且由于增长率低,也无需增大投资。因而成为企业回收资金,支持其它产品,尤其明星产品投资的后盾。①把设备投资和其它投资尽量压缩;②采用榨油式方法,争取在短时间内获取更多利润,为其它产品提供资金。对于这一象限内的销售增长率仍有所增长的产品,应进一步进行市场细分,维持现存市场增长率或延缓其下降速度。对于现金牛产品,适合于用事业部制进行管理,其经营者最好是市场营销型人物。现金牛业务指低市场成长率、高相对市场份额的业务,这是成熟市场中的领导者,它是企业现金的来源。由于市场已经成熟,企业不必大量投资来扩展市场规模,同时作为市场中的领导者,该业务享有规模经济和高边际利润的优势,因而给企业带来大量财源。企业往往用现金牛业务来支付帐款并支持其他三种需大量现金的业务。图中所示的公司只有一个现金牛业务,说明它的财务状况是很脆弱的。因为如果市场环境一旦变化导致这项业务的市场份额下降,公司就不得不从其他业务单位中抽回现金来维持现金牛的领导地位,否则这个强壮的现金牛可能就会变弱,甚至成为瘦狗。
- 瘦狗产品(dogs),也称衰退类产品。它是处在低增长率、低市场占有率象限内的产品群。其财务特点是利润率低、处于保本或亏损状态,负债比率高,无法为企业带来收益。对这类产品应采用撤退战略:首先应减少批量,逐渐撤退,对那些销售增长率和市场占有率均极低的产品应立即淘汰。其次是将剩余资源向其它产品转移。第三是整顿产品系列,最好将瘦狗产品与其它事业部合并,统一管理。
@4 波士顿矩阵应用法则
按照波士顿矩阵的原理,产品市场占有率越高,创造利润的能力越大;另一方面,销售增长率越高,为了维持其增长及扩大市场占有率所需的资金亦越多。这样可以使企业的产品结构实现产品互相支持,资金良性循环的局面。按照产品在象限内的位置及移动趋势的划分,形成了波士顿矩阵的基本应用法则。
- 第一法则:成功的月牙环。在企业所从事的事业领域内各种产品的分布若显示月牙环形,这是成功企业的象征,因为盈利大的产品不只一个,而且这些产品的销售收入都比较大,还有不少明星产品。问题产品和瘦狗产品的销售量都很少。若产品结构显示的散乱分布,说明其事业内的产品结构未规划好,企业业绩必然较差。这时就应区别不同产品,采取不同策略。
- 第二法则:黑球失败法则。如果在第三象限内一个产品都没有,或者即使有,其销售收入也几乎近于零,可用一个大黑球表示。该种状况显示企业没有任何盈利大的产品,说明应当对现有产品结构进行撤退、缩小的战略调整,考虑向其它事业渗透,开发新的事业。
- 第三法则:西北方向大吉。一个企业的产品在四个象限中的分布越是集中于西北方向,则显示该企业的产品结构中明星产品越多,越有发展潜力;相反,产品的分布越是集中在东南角,说明瘦狗类产品数量大,说明该企业产品结构衰退,经营不成功。
- 第四法则:踊跃移动速度法则。从每个产品的发展过程及趋势看,产品的销售增长率越高,为维持其持续增长所需资金量也相对越高;而市场占有率越大,创造利润的能力也越大,持续时间也相对长一些。按正常趋势,问题产品经明星产品最后进入现金牛产品阶段,标志了该产品从纯资金耗费到为企业提供效益的发展过程,但是这一趋势移动速度的快慢也影响到其所能提供的收益的大小。
3 模型简图
-
波士顿房价预测python决策树_机器学习·波士顿房价预测模型
2020-12-15 11:13:43本文以波士顿房价为例,说明如何训练数据以及对模型做评估,辨别模型的优劣。第一步:导入数据将数据的Features和Values分开,以便后续步骤可以分开使用(训练时只使用Features,验证时二者都要使用)。数据集来自[UCI...模型评估与验证
当我们的机器学习模型建立好之后,如何训练数据以获得最优的模型参数,又用什么指标来评价模型的优劣呢?本文以波士顿房价为例,说明如何训练数据以及对模型做评估,辨别模型的优劣。
第一步:导入数据
将数据的Features和Values分开,以便后续步骤可以分开使用(训练时只使用Features,验证时二者都要使用)。数据集来自[UCI机器学习知识库]。
import pandas as pd
import numpy as np
import visuals as vs
data = pd.read_csv('housing.csv')
features = data.drop('MEDV',axis=1)
prices = data['MEDV']
print data.head()
下面是运行结果
RM LSTAT PTRATIO MEDV
0 6.575 4.98 15.3 504000.0
1 6.421 9.14 17.8 453600.0
2 7.185 4.03 17.8 728700.0
3 6.998 2.94 18.7 701400.0
4 7.147 5.33 18.7 760200.0
数据解释如下:
RM表示该地区中每个房屋的平均房间数量;
LTSAT表示有多少百分比的业主属于低收入阶层;
PARATIO表示该地区的中学和小学里,学生和老师的数目比(学生/老师);
MEDV表示当地的房价。
其中RM,LTSAT,PARATIO三个是Features,MEDV是我们需要预测的Values。
第二步:分析数据
特征观察,观察数据,分析每个变量与预测值之间的关系(正相关,负相关);
将数据分割为训练集(train set)和验证集(validation set),使用以下方法:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features, prices, test_size=0.2,random_state=1)
print X_train.head()
下面是运行结果
RM LSTAT PTRATIO
307 6.382 10.36 18.4
58 6.145 6.86 19.7
424 6.406 19.52 20.2
78 6.232 12.34 18.7
439 5.976 19.01 20.2
下面来解释train_test_split()中的用到的参数:
features 表示数据中的‘特征’,在第一步中已经划分为单独的变量
prices 表示数据的‘值’,在第一步中已经划分为单独的变量
test_size 是0~1之间的数字,表示使用多少数据进行验证,如test_size=0.2表示使用20%的数据进行验证,使用80%的数据进行训练
random_state 表示是否随机划分训练集与测试集,若ransom_state=0,则会随机划分测试集与训练集。随机划分的结果就是会使每次训练的分数不同,程序每运行一次,训练分数就会变化。若使random_state =1(或其他非零数),则无论程序运行多少次,分数都是相同的。
训练集会把特征和结果同时给到模型,让模型找到一个可以比较好的拟合参数,训练集的目的就是就是使模型的Features和Values尽可能的拟合。
验证集只会把特征给到模型,模型会产生预测值,再将预测值与实际值相比较,通过得分(第三步会涉及到)判定模型对于验证集的拟合情况,来看模型的好坏。
模型对于数据的拟合情况不好,可以分为两类:过拟合与欠拟合,这两种情况在后文中会涉及。
第三步:模型衡量标准
本例中的房价预测属于回归问题,要判断模型预测值与实际值的拟合程度,可以使用**R2**分数进行评价。R2是决定系数(coefficient of determination),在统计学中,它表征回归方程多大程度上解释了因变量的变化,可用来表示表示对模型拟合程度的好坏,其取值范围是0~1,R2等于1表示模型可以100%解释目标值变化,R2等于0表示模型完全不能解释目标值的变化,下面是R2分数的推导过程:
1.Sum of square due to error(残差平方和):
对于第i个观察点,真实数据
与估算出的
之间的差称为第i个残差(residual),SSE就是所有点的残差的和。
2.Total sum of squares(总平方和):
SST的值与数据的方差(variance)成比例。
3.Sum of squares due to regression(回归平方和):
从公示可以看出他们的关系:
R2决定系数是判断回归方程的拟合程度,假设R2 = 0.6,表示房价60%的变化是模型可以解释的,其余40%模型无法解释,
用代码计算R2分数:
from sklearn.metrics import r2_score
def performance_metric(y_true,y_predict):
'''计算实际值与预测值的R2分数'''
score = r2_score(y_true,y_predict)
return score
第四步 分析模型表现
使用决策树回归算法,控制算法的max_depth参数,得到不同的学习曲线。
vs.ModelLearning(X_train,y_train)
当max_depth=1时,训练集和验证集的分数都比较低,此时模型欠拟合;
当max_depth=3时,随着训练样本数的增加,Training Score与Validation Score不断接近,R2分数稳定在0.8左右,说明模型拟合情况较好;
当max_depth=10时,Training Score接近1.0,而Validation Score只有0.7左右,此时模型过拟合。
欠拟合
欠拟合表示模型对训练集和验证集的拟合程度都比较低,本例中表现为其R2分数都比较低。
欠拟合表示模型虽然有充足的数据,但因不够复杂而无法捕捉到基本关系,模型会一直错误地表示数据,解决欠拟合的方法有:
– 使用更多特征训练数据
– 更改模型
过拟合
过拟合表示数据过于追求队训练集每一个点方差最小,而泛化能力不强,在验证集上表现较差。其表现就是训练集的R2分数较高,而验证集的R2分数较低。过拟合的可以理解为模型对数据过于关心,会推断出一些在数据实际中并不存在的关系,通常因为模型过于复杂或没有足够的数据训练,解决过拟合的方法有:
– 使用更多的数据进行训练
– 限制模型的复杂度
复杂度曲线
vs.ModelComplexity(X_train,y_train)
从上图的复杂度曲线可以看出,max_depth = 5时,Validation Score最高。当最大深度为1时训练模型,Training Score和Validation Score都较低,出现了欠拟合的情况,模型出现了比较大的偏差(bias);以最大深度为10训练模型,Tarining Score较高而Validation Score较低,模型出现过拟合的情况,有比较大的方差(variance)。
训练误差与测试误差相差较远时(训练集R2分数较高,而验证集R2分数较低),模型有方差(variance),方差较大表示模型过拟合。
训练误差与测试误差相差都比较大时(训练集与验证集R2分数都较低),模型有偏差(bias),偏差较大表示模型欠拟合。
为了权衡模型的偏差(bias)与方差(variance),观察图中Tarin Score与Validation Score,我们认为Max_depth=5时模型拟合度最好。
第五步 选择最优参数
在上一步中,我们从复杂度曲线可以看出,max_depth=5时拟合程度最好仅是我们观察得出的猜测,如何计算出模型的最优参数(max_depth=5)呢?计算得出的结论是否与我们的猜测一致呢?
网格搜索(Grid Search)
本例我们使用网格搜索来寻找最优参数。网格搜索类似于穷举法,会将全部参数计算一遍,并根据评分方法(R2分数)计算得分,最后找出最优的参数。本例的参数是max_depth。
交叉验证
本例使用k折交叉验证(k-fold cross-validation)。k折交叉验证法是将数据集分为k个相等的部分,k-1份作为训练集,1份作为验证集,这个过程会进行k次,然后会计算每个参数(max_depth=1~10)的R2分数,并对k次结果取平均数,然后找出R2分数最高的一个参数。
GridSearchCV的cv_result属性可以看到,k折交叉验证中每个split在不同max_depth下Training Score和test Score。下面的代码是使用决策树算法训练模型,使用10折交叉验证,使用网格搜索法,以找到最佳的max_depth。
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import make_scorer
def fit_model(X,y):
cross_validator = KFold(n_splits=10,shuffle=False) #使用10折交叉验证
regressor = DecisionTreeRegressor()
params = {'max_depth':[1,2,3,4,5,6,7,8,9,10]}
scoring_fnc = make_scorer(score_func = performance_metric)
grid = GridSearchCV(estimator = regressor,
param_grid = params,
scoring = scoring_fnc,
cv = cross_validator)
grid = grid.fit(X,y) #基于数据X,y进行网格搜索
return grid.best_estimator_ #返回网格搜索后的最优模型
optimal_reg = fit_model(X_train,y_train) #使用数据对模型进行训练,找出最优参数
print 'The best parameter is max_depth={}'.format(optimal_reg.get_params()['max_depth'])
代码输出:
The best parameter is max_depth=4
GridSearchCV参数
cross_validator参数表示使用的交叉验证方法,本例中定义为10折交叉验证,默认为3折交叉验证;
regressor参数表示使用的回归函数,本例使用决策树回归;
params参数表示要使用交叉验证的参数,本例中的参数为决策树的最大深度(max_depth)使用字典表示;
scoring_fnc表示评分函数,本例使用R2分数
从结果来看,使用网格搜索所得出的最优参数是max_depth=4。
第六步 做出预测
我们已经训练好一个模型,现在我们想知道模型的预测能力怎样,使用在第二步分割好的X_test与y_test对模型的预测能力评分。
predicted_test = optimal_reg.predict(X_test) #将X_test放入模型进行预测,并将预测结果放在变量predicted_test中
test_set_scoring = performance_metric(predicted_test,y_test) #将预测值predicted_test与实际值y_test计算R2分数
print 'The test set score is {}'.format(test_set_scoring)
代码输出:
The test set score is 0.740662174161
最终测试集R2分数为0.74。这个分数表示,房价74%的价格模型可以解释,还有26%的房价模型无法解释。
总结
本文以波士顿房价数据为例,先将数据集分割,分割为训练集与验证集,同时将Features与Values分开,再进一步确定要使用的模型评分标准,本例中使用R2分数,然后使用了决策树回归算法(当然这个算法不是重点啦),以决策树的最大深度max_depth作为参数,得出在参数取不同值时的模型表现,接着使用训练集训练数据,并做交叉验证,找出了R2分数最高的参数,这个参数就是我们想要的结果。
-
-
深度学习应用6.3波士顿房价模型改进
2020-03-05 23:16:51文章目录1特征数据归一化模型应用 1特征数据归一化 特征数据各个特征之间有所差距,需要平衡权重,而标签只有列。归一化用于消除各个特征变量的量纲 完整代码 %matplotlib notebook import tensorflow as tf import...1特征数据归一化
特征数据各个特征之间有所差距,需要平衡权重,而标签只有列。归一化用于消除各个特征变量的量纲
完整代码%matplotlib notebook import tensorflow as tf import matplotlib.pyplot as plt import numpy as np import pandas as pd # read file kit from sklearn.utils import shuffle #洗牌 # read file df=pd.read_csv("data/boston.csv",header=0) # show data summary数据摘要 print(df.describe()) # 获取df的值 df=df.values #把df转换为np的数组格式 df=np.array(df) #对特征数据0-11做(0-1)的归一化 for i in range(12): df[:,i]=df[:,i]/(df[:,i].max()-df[:,i].min()) # x_data前12列特征数据 x_data=df[:,:12] #y_data为最后一列标签数据 y_data=df[:,12] #None行的数量位置,可以强化适应性 x=tf.placeholder(tf.float32,[None,12],name='X') y=tf.placeholder(tf.float32,[None,1],name='Y') #定义了一个命名空间 with tf.name_scope("Model"): #w初始化为shape=(12,1)的随机数 w=tf.Variable(tf.random_normal([12,1],stddev=0.01),name="W") # b初始化 b=tf.Variable(1.0,name='b') #w和x矩阵相乘 def model(x,w,b): return tf.matmul(x,w)+b #预测计算操作,前向计算节点 pred=model(x,w,b) # 设置训练参数 #迭代轮数 train_epochs=50 #学习率 learning_rate=0.01 #定义均方差损失函数 with tf.name_scope("LossFunction"): loss_function=tf.reduce_mean(tf.pow(y-pred,2))#均方差 #创建优化器 optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function) sess=tf.Session() #定义初始化变量操作 init=tf.global_variables_initializer() sess.run(init) for epoch in range(train_epochs): loss_sum=0.0 for xs,ys in zip(x_data,y_data): xs=xs.reshape(1,12) ys=ys.reshape(1,1) _,loss=sess.run([optimizer,loss_function],feed_dict={x:xs,y:ys}) loss_sum=loss_sum+loss xvalues,yvalues=shuffle(x_data,y_data) b0temp=b.eval(session=sess) w0temp=w.eval(session=sess) loss_average=loss_sum/len(y_data) xprint("epoch=",epoch+1,"loss=",loss_average,"b=",b0temp,"w=",w0temp)
2模型应用
n=348 x_test=x_data[n] x_test=x_test.reshape(1,12) predict=sess.run(pred,feed_dict={x:x_test}) print("预测值是%f"%predict) target=y_data[n] print("实际值是%f"%target)
3 改进可视化过程中的损失值
4加上tensorboard可视化代码
完整代码间github -
线性回归模型预测波士顿房价并绘图
2020-12-22 12:56:53波士顿房价 这是 sklearn.datasets 里的一种 Toy Dataset ,包含503个美国波士顿房价的观测值,是内置的小数据集,也是研究回归算法的优秀数据集。 Python编程实现 import matplotlib.pyplot as plt import ... -
波士顿会议支持激光退火熔化模型
2021-02-25 03:08:4111月16日至20日在波士顿材料研究学会年会期间召开的激光和电子束与固体相互作用专题讨论会,是至今为止该领域的一次最大集会。来自14个国家的代表提交了128篇论文,内容包括基本作用机理,束加工技术应用于半导体器件... -
数据分析模型篇—波士顿矩阵
2019-09-03 23:21:11今天给大家介绍一个跟企业市场增长率和市场份额有关的数据分析模型—波士顿矩阵。 波士顿矩阵是通过使用企业市场吸引力以及所处的市场竞争位置来比较不同的产品(也可说不同战略经营单元)之间的具体情况。企业市场...