简介:这份PDF为《基于BP神经网络的象征价值指标体系的构建》论文原文,适合管理学、市场营销及数据建模方向的研究者和学生参考。文章从象征价值的内涵与维度入手,系统梳理影响象征价值的消费者心理、产品、文化、情境与社会生态五类因素,并着重介绍消费者心理、产品、文化三方面的评价指标体系。在此基础上,利用BP神经网络对定性指标间的非线性关系建模,借助MATLAB完成数据仿真与实例应用,为量化评估象征价值提供可行方案。资源共1个PDF文件,压缩包大小约278KB,轻便易用。已有79人学习下载。文中包含指标体系表、BP神经网络模型构建与训练流程,可为撰写相关论文或开展数据建模实践提供直接参考。
1. 为什么象征价值评估绕不开BP神经网络
如今同质化商品越来越多,消费者购买决策已经明显从实用价值转向品牌承载的象征价值。象征价值又被称为符号价值,是消费者基于自我价值取向在消费过程中形成的外显性评价,包含声望、社会自我表达、独特性、享乐等维度。这些维度之间呈现典型非线性关系,传统的加权平均法、层次分析法和模糊综合评价都建立在指标线性叠加的假设上,很难刻画这种复杂映射。BP神经网络可以在不了解数据产生原因的情况下逼近任意非线性关系,因此用13个影响因素做输入、一个综合指数做输出,构建三层网络来评估象征价值,是更合理的选型。这篇文章会拆开指标体系设计、MATLAB实现、训练调参与实例应用,过程中会给出可复现代码和踩坑说明。
2. 象征价值指标体系:从五个因素到13个输入节点
2.1 影响因素分类与指标落地
象征价值不是一个可以直接问出来的数字,它由多个维度的感知共同决定。论文整理出五类影响因素:消费者心理、产品、文化、情境、社会生态,再细分到13个具体指标。这一步很关键:BP神经网络的输入维度从哪里来、每个指标怎么定义,直接决定模型能不能收敛,也决定后续输出结果能不能解释。
| 一级因素 | 二级指标 | 指标解释 |
|---|---|---|
| 消费者心理因素 | 参照群体 | 消费者在购买时参考白领、同事等群体的消费习惯 |
| 消费者心理因素 | 消费者体验 | 通过直接或间接使用产品建立的主观感受 |
| 消费者心理因素 | 种族认同 | 借助象征消费表达自身社会角色或身份认同 |
| 产品因素 | 产品内涵 | 产品被个人或群体认同的象征意义 |
| 产品因素 | 产品稀缺性 | 限量款、稀缺款式对购买决策的影响程度 |
| 产品因素 | 产品输出国形象 | 原产地或输出国带给产品的象征与情感意义 |
| 产品因素 | 产品的品牌显著性 | 产品外观中品牌标志的明显程度 |
| 文化因素 | 国家文化 | 消费者所处国家文化环境对购买行为的影响 |
| 文化因素 | 传统价值观念 | 儒家等传统观念对消费动机的驱动 |
| 文化因素 | 物质主义 | 物质主义倾向对象征性消费的影响 |
| 情境因素 | 公开消费情境 | 在公开场合消费时对象征意义传递的关注 |
| 情境因素 | 非公开消费情境 | 在私人场合消费时对产品象征意义的感知 |
| 社会生态因素 | 男女交往动机 | 出于社交或两性关系驱动象征消费的强度 |
这个表格来自论文原文,但直接套用还有一个风险:指标与指标之间并不是独立的。比如产品稀缺性与公开消费情境会互相影响,在公开场合使用稀缺产品,象征意义会被放大;传统价值观念也会调节品牌显著性的作用。这种交互效应恰好是线性加权模型最难处理的,也是最终选择BP神经网络结构而不是AHP的直接原因。
实际落地时,还需要把这些二级指标做成可操作化定义。以“产品稀缺性”为例,问卷里可以设计成“该品牌的限量款式是否经常让你产生购买冲动”;“男女交往动机”则可以是“购买这类产品时,你是否在意异性评价”。如果只写“稀缺程度打分”这种抽象表述,不同消费者理解差异会很大,最终得到的输入数据噪声也会很大。
2.2 打分标准与样本构造
论文采用10分制问卷,1分表示该指标在目标产品上“完全不体现”,10分表示“完全体现”,消费者对13个指标逐一打分。样本规模不大:22名消费者,每人的评分构成一条1×13的输入向量。其中前15组作为训练样本,后7组作为测试样本。
这里有一个容易被忽略的细节:网络的输出标签是怎么来的?论文的做法是,对于每一条样本,把所有评分按大小排列,去掉前后各3个,剩下加和取平均,再缩小10倍到[0,1]区间。去掉前后3个是一种截尾均值处理,相当于把最高分和最低分都剔除,减少极端偏好对标签的影响。你可以用一段简单脚本实现这个逻辑:
% scores: 某个样本对应的多轮原始评分向量 scores = [2 5 6 8 3 9 7 4 6 8 5 7 6]; scoresSorted = sort(scores); trimCount = 3; centralScores = scoresSorted(trimCount+1:end-trimCount); label = mean(centralScores) / 10;这段代码的核心是排序、裁剪、求均值。trimCount设为3,意味着这条样本至少要有7个有效评分,否则裁剪后为空。注意这里构造标签有一个隐含前提:每一条样本要有多份独立评分来源。论文请22名消费者打分,构造出多对一形式的样本对,最终训练时再缩小10倍转换到0-1范围。
关于训练集和测试集的划分,论文按顺序取前15条、后7条。我一般不会这样切小样本,因为顺序可能与问卷发放渠道、时间相关,容易出现系统性偏差。更稳妥的做法是随机划分,并确保两组标签分布接近。但为了复现论文数据流程,下文先沿用前15后7的切分方式,交叉验证的问题放到最后一章专门处理。
3. BP神经网络结构设计与MATLAB参数设置
3.1 网络结构图与节点数确定
先把BP神经网络结构图在脑子里面搭出来:输入层、隐含层、输出层,数据从输入层传到输出层,误差再从输出层反向传播,逐层更新权重。象征价值这个场景下,输入层节点数是13,对应13个指标;输出层节点数是1,对应象征价值指数。隐含层数量取1个就足够,因为一个三层的BP网络已经可以完成任意维度之间的映射。
隐含层节点数没有理论上的固定公式。论文用了三个经验公式缩小搜索范围:
- b = sqrt(a + c) + r,其中r取[1,10];
- b = log2(a);
- b = sqrt(a * c)。
这里a=13,c=1。代入计算:第一个公式的范围大约在4到15之间,第二个约3.7,第三个约3.6。所以候选隐含层节点数基本锁定在4到15之间。论文对比训练结果后,发现隐含层节点数为8时效果最佳。这个“8”只代表在固定样本和固定划分下的最优选择,换一份数据可能要重新试。
一个常见误区是隐含层节点数越多越好。节点数太少,网络拟合能力不足,训练误差降不下来;节点数太多,模型开始记忆训练样本里的噪声,测试误差反而上升。实际操作时,我会把4到15每个节点数都训练一遍,记录训练误差和测试误差,优先选测试误差最低的点,而不是训练误差最低的点。
3.2 训练函数、学习函数与传输函数的选择
论文在MATLAB R2013a神经网络工具箱里使用的关键参数是:训练函数TRAINGDM、自适应学习函数LEARNGDM、性能函数MSE和传输函数LOSIG,学习率0.05,其余参数默认。这里LOSIG在MATLAB中实际对应logsig,也就是S型对数传输函数。
先说训练函数为什么选traingdm。traingdm是带动量的梯度下降法,比普通梯度下降更平滑,可以抑制训练过程中的震荡。任务样本量只有22条,不需要用trainlm这类二阶优化算法,即使收敛快,也容易陷入过拟合。动量系数默认是0.9,早期论文里一般不动它。
传输函数的选择也要看清楚:logsig输出区间在(0,1),刚好匹配论文定义的输出值P取值范围[0,1]。输出层如果也用logsig,输出天然落在0到1之间;输出层如果改用purelin,输出可能超出范围,需要做阈值判断。两种组合都能跑,我一般在输出层用purelin,把最后的线性输出再映射到等级。
下面的代码给出网络创建过程:
% 输入层13个节点,隐含层8个节点,输出层1个节点 inputSize = 13; hiddenSize = 8; outputSize = 1; % newff输入格式:输入范围、每层节点数、传输函数、训练函数 net = newff([-ones(inputSize,1), ones(inputSize,1)], ... [hiddenSize outputSize], ... {'logsig','purelin'}, ... 'traingdm'); % 查看网络结构图 view(net);view(net)会在MATLAB中弹出网络结构图,直观显示13-8-1的连接关系。代码里第一个参数是输入范围矩阵,输入数据后面会归一化到[-1,1],所以这里直接用-1到1。如果你使用的是R2010a之前的版本,newff的输入参数格式略有不同,需要额外指定输入层范围;R2013a的写法没问题。
接下来设置训练参数:
net.trainParam.epochs = 110; % 最大训练次数,论文在110次达到精度 net.trainParam.lr = 0.05; % 学习率 net.trainParam.mc = 0.9; % 动量系数 net.performFcn = 'mse'; % 性能函数:均方误差训练次数110是论文给出的最优结果,但在复现时不要无脑照抄。你先把epochs设成110跑一次,看训练误差是否已经平坦;如果误差还在下降,说明110次不够,要加码到500或1000。学习率0.05在大多数小样本回归任务里合适,如果误差曲线震荡,把这学习率减半再试。
4. 模型训练、测试与结果分析
4.1 样本预处理:去极值平均与归一化
样本处理决定模型上限。先假设已经拿到22条原始评分矩阵rawScores,大小为22×13,以及对应标签label。按照论文的划分方式,前15条做训练,后7条做测试:
trainX = rawScores(1:15, :); testX = rawScores(16:22, :); trainY = label(1:15, :); testY = label(16:22, :);然后做归一化。原始13个指标都是十分制,但不同指标的打分分布差异很大,比如“产品稀缺性”可能出现很多1分和10分,“男女交往动机”可能集中在3到5分。如果直接输入网络,大数值指标会主导权重更新。用mapminmax把每维特征映射到[-1,1]:
% 用训练集计算归一化参数 [trainXn, PS] = mapminmax(trainX', -1, 1); % 测试集复用训练集的归一化参数 testXn = mapminmax('apply', testX', PS);mapminmax要求输入是“特征×样本”的矩阵,所以要对trainX做转置。注意PS里保存的是训练集每个特征的最小值和最大值,测试集必须复用同一套PS,不能单独重新归一化,否则训练集和测试集尺度不一致,测试误差完全没有参考价值。
4.2 训练过程与输出曲线
训练代码如下:
% 创建13-8-1网络 net = newff([-ones(13,1), ones(13,1)], [8 1], {'logsig','purelin'}, 'traingdm'); net.trainParam.epochs = 110; net.trainParam.lr = 0.05; rng(1); % 固定随机种子,让结果可复现 [net, tr] = train(net, trainXn, trainY');rng(1)这一步很容易漏掉。BP网络初始化权重是随机的,不固定种子,每次跑出来的误差都不一样。论文没有写明随机种子,所以严格意义上不能直接复现到完全一致的结果,但固定种子至少让实验可重复。
训练结束后,用plotperform绘制误差下降曲线:
plotperform(tr);这就是经常看到的BP神经网络拟合曲线:横轴是训练次数,纵轴是均方误差。正常情况曲线在110次前已经明显下降并趋于平坦。如果曲线像锯齿一样上下波动,说明学习率偏大,建议降到0.02或0.01;如果训练结束时曲线还在快速下降,说明110次迭代不够,需要增大epochs。
计算训练集预测误差:
trainOut = sim(net, trainXn); trainAbsErr = abs(trainOut - trainY'); trainRelErr = trainAbsErr ./ trainY'; disp(['训练集最大相对误差: ', num2str(max(trainRelErr))]);sim是模拟网络输出,相当于用训练好的网络做预测。相对误差用绝对误差除以真实标签,可以有效反映预测偏离程度。论文训练集最大相对误差为0.06495,也就是6.5%左右,在只有15条训练样本的前提下,属于可以接受的范围。
4.3 测试集误差与泛化判断
模型能不能用在没见过的消费者评分上,要看测试集表现:
testOut = sim(net, testXn); testAbsErr = abs(testOut - testY'); testRelErr = testAbsErr ./ testY'; disp(['测试集最大相对误差: ', num2str(max(testRelErr))]); for i = 1:length(testY) fprintf('样本%d: 目标=%.4f, 网络输出=%.4f, 相对误差=%.4f\n', ... i, testY(i), testOut(i), testRelErr(i)); end论文测试集最大相对误差为0.035878,即3.6%。这个误差比训练集还低,说明网络没有对训练集过拟合,至少在这7条测试样本上表现良好。下面汇总一下结果:
| 数据集 | 最大相对误差 | 样本数 |
|---|---|---|
| 训练集 | 0.06495 | 15 |
| 测试集 | 0.035878 | 7 |
数据来源是论文表4,这里只有相对误差,没有给出绝对误差。单看数值确实不错,但要注意7条测试样本的随机性太高,一次划分不能完全代表模型真实水平。这也是我在下一章重点强调交叉验证的原因。
5. 实例应用与落地里的技巧与坑
5.1 把训练好的网络保存并用于新评分
训练完成后,把网络和归一化参数保存到磁盘:
save('symbolic_value_model.mat', 'net', 'PS');后续遇到新品牌或新产品,只要按照同样的10分制对13个指标打分,比如论文里S集团手表的评分:
newScore = [8 3 9 5 7 8 8 7 8 6 5 8 8]; newScoreNorm = mapminmax('apply', newScore', PS); pred = sim(net, newScoreNorm); symbolicIndex = pred * 10; disp(symbolicIndex);输出结果是0.7329,还原成十分制就是7.329分,对应“中等”等级。一个知名度很高的手表集团,最终象征价值指数只有中等,原因在评分结构:第2项“消费者体验”只有3分,第11项“物质主义”只有5分,这些短板会把综合指数拉下来。象征价值是整体评价,不是单项加总,解释了为什么品牌声望高但综合输出并不高。
5.2 小样本训练的几个坑
论文样本只有22条,神经网络模型会面临很多实际问题。
第一个坑是样本划分。前15条训练、后7条测试的固定划分,受样本顺序影响太大。如果问卷发放有时间顺序,前面填的人集中在某个年龄段或渠道,测试结果就会失真。稳妥做法是用randperm随机打乱索引,再按比例切分,并固定随机种子。
第二个坑是标签构造。去头尾取平均的方法只适用于多评分源稳健汇总。如果一条样本就是一个产品、每个消费者只评一次,就不该用这种方法造标签。实践里我会在问卷里单独设计一题“整体象征价值评分”,让消费者直接打分作为监督标签,这样更直接,也省去复杂的去极值操作。
第三个坑是过拟合误判。训练误差低只是表象,如果测试误差明显高于训练误差,通常要减少隐含层节点数,或者提前停止训练。论文里测试误差低于训练误差,说明在当前划分下过拟合风险不高,但这个结论不能推广到所有数据。
5.3 用留一交叉验证检验模型可靠性
22条样本下,比固定划分更可靠的是留一交叉验证(LOOCV)。每轮拿出1条做测试、剩下21条做训练,重复22次,然后把所有测试误差汇总,这样每条样本都被验证一次。
n = 22; allErrors = zeros(n, 1); for i = 1:n trainIdx = setdiff(1:n, i); testIdx = i; trainXi = rawScores(trainIdx, :); testXi = rawScores(testIdx, :); trainYi = label(trainIdx); testYi = label(testIdx); [trainXni, PSi] = mapminmax(trainXi', -1, 1); testXni = mapminmax('apply', testXi', PSi); neti = newff([-ones(13,1), ones(13,1)], [8 1], {'logsig','purelin'}, 'traingdm'); neti.trainParam.epochs = 110; neti.trainParam.lr = 0.05; rng(i); [neti, ~] = train(neti, trainXni, trainYi'); predi = sim(neti, testXni); allErrors(i) = abs(predi - testYi); end meanError = mean(allErrors); stdError = std(allErrors);留一交叉验证的结果如果均值误差在0.05以内,且标准差不大,模型的可靠性就比单次测试误差0.035878更有说服力。如果某个样本单次误差特别大,说明该样本是异常点,需要回头检查原始评分是否填错。最后把隐含层节点数4到12全部用留一交叉验证跑一遍,画出一张节点数-平均误差柱状图,再挑误差最低的点。论文说8最佳,那只是固定划分下的8;换成LOOCV,最优节点数很可能就变了,别偷懒。
本文还有配套的精品资源,点击获取