スクリプトはこちら
prst1 <- read.csv("https://goo.gl/z5P8ce") #データの読み込み
summary(prst1) #記述統計
## Adaptable BestValue CuttingEdge Delightful Exciting
## Min. :1.000 Min. :1.000 Min. :1.00 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:3.000 1st Qu.:3.00 1st Qu.:3.000 1st Qu.:3.000
## Median :4.000 Median :4.000 Median :4.00 Median :4.000 Median :4.000
## Mean :4.255 Mean :3.849 Mean :4.07 Mean :3.983 Mean :3.892
## 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:5.00 3rd Qu.:5.000 3rd Qu.:5.000
## Max. :7.000 Max. :7.000 Max. :7.00 Max. :7.000 Max. :7.000
## Friendly Generous Helpful Intuitive
## Min. :1.000 Min. :1.000 Min. :1.000 Min. :1.000
## 1st Qu.:4.000 1st Qu.:3.000 1st Qu.:3.000 1st Qu.:3.000
## Median :4.000 Median :4.000 Median :4.000 Median :4.000
## Mean :4.246 Mean :4.031 Mean :3.894 Mean :3.724
## 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:5.000 3rd Qu.:4.000
## Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000
## Brand
## Length:3050
## Class :character
## Mode :character
##
##
##
str(prst1) #データの構造を確認
## 'data.frame': 3050 obs. of 10 variables:
## $ Adaptable : int 6 4 3 4 4 4 5 4 5 5 ...
## $ BestValue : int 5 3 2 1 1 3 3 2 4 3 ...
## $ CuttingEdge: int 4 4 3 4 3 4 5 7 4 5 ...
## $ Delightful : int 4 2 6 4 3 4 4 5 3 4 ...
## $ Exciting : int 3 4 5 5 3 3 6 4 3 5 ...
## $ Friendly : int 4 4 5 4 5 4 3 3 4 6 ...
## $ Generous : int 5 5 6 5 5 6 5 5 4 4 ...
## $ Helpful : int 4 2 4 3 4 2 3 4 3 5 ...
## $ Intuitive : int 3 5 3 3 4 4 4 4 3 5 ...
## $ Brand : chr "Sierra" "Romeo" "Sierra" "Sierra" ...
sc <- prst1
sc[, 1:9] <- data.frame(scale(prst1[, 1:9])) #1~9列目を標準化
summary(sc)
## Adaptable BestValue CuttingEdge Delightful
## Min. :-3.3414 Min. :-2.7323 Min. :-2.88159 Min. :-3.04151
## 1st Qu.:-0.2622 1st Qu.:-0.8139 1st Qu.:-1.00463 1st Qu.:-1.00202
## Median :-0.2622 Median : 0.1453 Median :-0.06616 Median : 0.01772
## Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.00000
## 3rd Qu.: 0.7643 3rd Qu.: 1.1045 3rd Qu.: 0.87232 3rd Qu.: 1.03746
## Max. : 2.8171 Max. : 3.0228 Max. : 2.74928 Max. : 3.07695
## Exciting Friendly Generous Helpful
## Min. :-2.8785 Min. :-3.2141 Min. :-3.20078 Min. :-2.67745
## 1st Qu.:-0.8881 1st Qu.:-0.2435 1st Qu.:-1.08908 1st Qu.:-0.82696
## Median : 0.1070 Median :-0.2435 Median :-0.03323 Median : 0.09829
## Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 Mean : 0.00000
## 3rd Qu.: 1.1022 3rd Qu.: 0.7467 3rd Qu.: 1.02262 3rd Qu.: 1.02353
## Max. : 3.0925 Max. : 2.7271 Max. : 3.13431 Max. : 2.87403
## Intuitive Brand
## Min. :-2.8282 Length:3050
## 1st Qu.:-0.7519 Class :character
## Median : 0.2863 Mode :character
## Mean : 0.0000
## 3rd Qu.: 0.2863
## Max. : 3.4007
library(corrplot)
## corrplot 0.95 loaded
corrplot(cor(sc[, 1:9]),
order = "hclust") #似た変数同士をまとめて表示
9つの属性が3つのグループに分類される。以降、これらをそれぞれ感情系(Generous, Delightful, CuttingEdge, Exciting)、実用系(Adaptable, BestValue)、使いやすさ系(Helpful, Friendly, Intuitive)とする。
library(gplots)
## Warning: package 'gplots' was built under R version 4.5.3
##
## ---------------------
## gplots 3.3.0 loaded:
## * Use citation('gplots') for citation info.
## * Homepage: https://talgalili.github.io/gplots/
## * Report issues: https://github.com/talgalili/gplots/issues
## * Ask questions: https://stackoverflow.com/questions/tagged/gplots
## * Suppress this message with: suppressPackageStartupMessages(library(gplots))
## ---------------------
##
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
##
## lowess
library(RColorBrewer)
prst1.mean <- aggregate(. ~ Brand, data = sc,
mean) #ブランドごとに平均を算出
prst1.mean.matrix <- as.matrix(prst1.mean[, -1]) #1列目を除いて行列変換
rownames(prst1.mean.matrix) <- prst1.mean[, 1] #1列目のブランドを行名に
heatmap.2(prst1.mean.matrix, #ヒートマップは行列を受け取る
col=brewer.pal(9, "GnBu"), #緑から青への9段階で表現
trace="none", #トレースラインは非表示
key=TRUE, #色と数値の対応を表示
dend="none", #樹形図の非表示
main="\n\n\nBrand attributes") #/nは改行
この図は属性スコアの平均をブランドごとに表示したものである。濃い青が高評価、薄い緑は低評価を意味し、9つのグラデーションを設けている。感情系(Generous, Delightful, CuttingEdge, Exciting)ではTango・Sierra、使いやすさ系(Helpful, Friendly, Intuitive)ではRomeo・Papaが高評価を得ているとが分かる。
prst.pc <- prcomp(sc[, 1:9]) #1~9列目を指定して分析
summary(prst.pc)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6 PC7
## Standard deviation 1.3990 1.3577 1.1115 0.91215 0.84742 0.83450 0.77850
## Proportion of Variance 0.2175 0.2048 0.1373 0.09245 0.07979 0.07738 0.06734
## Cumulative Proportion 0.2175 0.4223 0.5595 0.65200 0.73179 0.80917 0.87651
## PC8 PC9
## Standard deviation 0.76278 0.72774
## Proportion of Variance 0.06465 0.05885
## Cumulative Proportion 0.94115 1.00000
plot(prst.pc, type="l") #折れ線グラフで固有値をプロット
主成分とは複数の変数をまとめた新しい指標を指す。主成分分析とは、説明変数を要約する手法で、情報量をできる限り減らさず、次元(変数の数)を減らすことが目的である。今回の場合だと、9つの属性を2次元に圧縮し、ブランドの立ち位置を可視化していく。固有値とは各主成分が持つばらつきの大きさを指し、主成分が持つ情報量の指標である。
rownames(prst1.mean) <- prst1.mean[, 1] #ブランド名を行名に
prst.mu.pc <- prcomp(prst1.mean[, -1], scale = TRUE) #1列除いて主成分分析
biplot(prst.mu.pc,
main = "Brand positioning", #タイトル
cex = c(1.0, 0.7), #文字の大きさ
col = c("black", "blue"), #色の指定
xlim = c(-0.8, 0.8), #軸の調整
ylim = c(-0.8, 0.8)
) #expandで矢印の長さを変えられる
軸は2つの主成分、左下のメモリは主成分スコア、右上のメモリは主成分負荷量、青い矢印と文字は属性と対応する主成分負荷量を指す。主成分スコアとは属性評価を主成分負荷量で重みづけて合計したものである。PC1の軸から見ると、0.0を中心に右側の属性(主に感情系)と正の関係、左側の属性(使いやすさ系)とは負の関係であることを示す。
PC2の軸から見ると、どの属性も0.0付近に集中しており、負荷量の絶対値が低い。しかし、実用系(Adaptable, BestValue)の負荷量が高く、PC2にそれらの変数が強い影響を及ぼしていることが分かる。
各ブランドを主成分スコアで見ると、いずれも0.0付近に集中しており、ブランド間の差が微々たるものであると読み取れる。PC1を軸にしてSierraを見ると、属性評価を主成分負荷量で重みづけした合計は正の値を取った。つまり、負荷量の絶対値に大きな差が見られないため、属性評価で感情系の評価が使いやすさ系を上回っていたことが推論される。
ところが、負荷量の絶対値にばらつきがある場合、特定の属性が主成分スコアを支配する。よって、負荷量の絶対値が大きい属性を重点的に強化していけば、主成分スコアは大きく変わる。つまり、プロット上で大きく座標が変わり、空白領域への移動や他社ブランドと距離をとることで、差別化につながる。
prst.mu.pc$rotation[, 1:2]
## PC1 PC2
## Adaptable -0.3249726 0.666519230
## BestValue 0.3235628 0.709203551
## CuttingEdge 0.3366189 -0.002848791
## Delightful 0.3340600 0.026823293
## Exciting 0.3365956 0.031687364
## Friendly -0.3360906 0.136248881
## Generous 0.3359019 0.130004276
## Helpful -0.3357895 0.120451765
## Intuitive -0.3360855 -0.032821482
主成分負荷量は各変数が主成分にどれだけ影響を及ぼしているを示す。scale = TRUEは変数を標準化してからPCAを行う設定で、単位や分散の大きさが異なる変数を同じ基準で比較できる。このとき負荷量は相関係数と同じ感覚で読める。正の値が大きいほどその主成分と同じ方向、負の値が大きいほど逆方向の関係を示す。
prst1.mean["Papa", -1] - prst1.mean["Romeo", -1]
## Adaptable BestValue CuttingEdge Delightful Exciting Friendly
## Papa 0.09844577 -0.1019352 -0.4119292 -0.4100553 -0.3808321 0.3096705
## Generous Helpful Intuitive
## Papa -0.1970958 0.3474463 0.3182752
colMeans(prst1.mean[c("Papa","Romeo"),-1]) - prst1.mean["Papa",-1]
## Adaptable BestValue CuttingEdge Delightful Exciting Friendly
## Papa -0.04922289 0.05096758 0.2059646 0.2050277 0.1904161 -0.1548352
## Generous Helpful Intuitive
## Papa 0.09854789 -0.1737231 -0.1591376
colMeans(prst1.mean[c("Papa","Sierra"),-1]) - prst1.mean["Papa",-1]
## Adaptable BestValue CuttingEdge Delightful Exciting Friendly
## Papa -0.1167683 0.07875469 0.3905468 0.2953398 0.3491926 -0.3143105
## Generous Helpful Intuitive
## Papa 0.1981832 -0.298416 -0.3408995
1行目では、PapaとRomeoにおける平均属性評価の差を取っている。主に使いやすさ系(Helpful, Friendly, Intuitive)ではPapa、感情系(Generous, Delightful, CuttingEdge, Exciting)ではRomeoが相対的に高い評価を得ている。しかし、実用系は分かれており、AdaptableではPapa、BestValueではRomeoが高い評価を得ている。
2・3行目ではPapaと競合ブランドの中間点を算出している。これはバイプロット上の空白領域、つまり既存ブランドが占めていないポジションを狙う際に、どの属性をどれだけ強化・抑制すればいいかを定量的に把握するためのものである。正の値が大きい属性は、競合と比較したときのPapaの弱点であり、強化の余地があることを示す。
biplot(prst.mu.pc,
choices = c(2,3),
main = "Brand positioning PC2 vs PC3",
cex = c(1,0.7),
xlim = c(-0.9,0.9),
ylim = c(-0.9,0.9))
prst.mu.pc$rotation[,2:3]
## PC2 PC3
## Adaptable 0.666519230 0.22792759
## BestValue 0.709203551 -0.14732265
## CuttingEdge -0.002848791 -0.03520907
## Delightful 0.026823293 0.77806121
## Exciting 0.031687364 0.02819116
## Friendly 0.136248881 0.12350429
## Generous 0.130004276 -0.26500833
## Helpful 0.120451765 -0.33383561
## Intuitive -0.032821482 0.34928849
PC2を軸に主成分負荷量を見ていくと、実用系(Adaptable, BestValue)が高く、これはPapaやTangoにとってさらなる強みとして訴求できるチャンスである。Romeoは突出した評価がなく、印象を創れる可能性がある。Sierraは実用系との関連が低いと主成分スコアから推論され、Adaptable, BestValueで差別化しようとすると、商品と顧客の持つイメージとの乖離が懸念される。しかし、負の主成分負荷量は少ないため、負の方向での差別化は現状厳しいと言える。
PC3を軸に主成分負荷量を見ていくと、Delightfulが突出して高く、これはRomeoにとって強みとして訴求できるチャンスである。SierraとTangoは中立であり、Delightful方向への展開の余地がある。しかし、SierraはPC2を軸に見ると、明確なアピールポイントを持ちにくい状況のため、PC3におけるDelightful方向への展開が現実的な差別化の選択肢であると考えられる。
本分析では、ブランドポジショニングを主成分分析とバイプロットを用いて可視化した。PC1では感情系(Generous, Delightful, CuttingEdge, Exciting)と使いやすさ系(Helpful, Friendly, Intuitive)の対立軸が確認され、PC2では実用系(Adaptable, BestValue)、PC3ではDelightfulが主要な差別化軸として示された。PapaやTangoは実用系での訴求余地、RomeoはDelightfulでの強化が現実的な選択肢として挙げられる。SierraはPC1・PC2において明確なポジションを築きにくいが、PC3ではDelightful方向へのシフトが現実的な差別化戦略であると考えられる。