這是一份正式的市場調查專案,主要協助業主(左岸咖啡)了解市場產品定位
Label No ="問卷代碼"
A101="左岸頻率" A102="伯朗頻率" A103="廣場頻率" A104="輕鬆頻率"
A2 ="咖啡偏好" A3 ="偏好口味"
A401="提神醒腦" A402="習慣飲用" A403="抒解口渴" A404="換喝飲料" A405="特殊口感" A406="享受感覺"
A501="知名度高" A502="廣告感覺" A503="價格合理" A504="包裝美觀" A505="整體口感"
A611="左岸知名" A612="左岸廣告" A613="左岸價格" A614="左岸包裝" A615="左岸口感"
A621="伯朗知名" A622="伯朗廣告" A623="伯朗價格" A624="伯朗包裝" A625="伯朗口感"
A631="廣場知名" A632="廣場廣告" A633="廣場價格" A634="廣場包裝" A635="廣場口感"
A641="輕鬆知名" A642="輕鬆廣告" A643="輕鬆價格" A644="輕鬆包裝" A645="輕鬆口感"
A701="猶豫程度" A702="後悔程度" A703="詢問程度" A704="關心程度" A705="注意程度" A706="選對重要"
A801="產品重要" A802="自我概念" A803="象徵價值" A804="商店忠誠(逆)" A805="品牌忠誠" A806="品牌信念(逆)"
A901="產品質佳" A902="積極開發" A903="重視權益"
B1 ="訊息接觸"
B201="口味香醇" B202="浪漫生活" B203="提振精神" B204="氣質優雅"
B301="廣告印象" B302="廣告說服" B303="廣告吸引" B304="廣告訊息"
B401="左岸意義" B402="左岸口味" B403="左岸價格" B404="左岸包裝"
B501="產品優質" B502="令人喜歡" B503="正面評價"
B6 ="促銷方案"
C01 ="閱讀報章" C02 ="戶外活動" C03="價格敏感"
C04 ="偏好家居" C05 ="經常運動" C06="流行資訊"
C07 ="獨自工作" C08 ="重視休閒" C09="重視品牌"
C10 ="希望讚美" C11 ="朋友聚會" C12="重視外觀"
C13 ="工作時長" C14 ="政治冷漠" C15="社會憂心"
Sex ="性別" AGE ="年齡" Occupatn="職業"
Edu ="教育程度" Income0="所得" Income ="調整後所得"
Area="居住地區" Intenst="產品強度";
[標準開始動作]. 如果你用python的目標是科學計算或數值分析,基本是引⼊三個套件¶
%matplotlib inline
##將後續畫圖的結果直接顯現在網頁中
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd #
[PART 1].輸入資料與資料檢查¶
import xlrd #讀取excel檔的模板
excel_file = 'Pycafe.xlsx'
Cafe = pd.read_excel(excel_file)
print(Cafe.shape)# 印出資料維度
print(Cafe.info())# 印出 DataFrame 資料概況, 順便check有沒有missing value
Cafe.head() #看前五筆資料
Cafe.tail() #看後面幾筆
Cafe.sample(10)#隨機取10行
[PART 2].基本敘述性統計¶
一般而言,一開始我們會從人口統計資料開始看起
Cafe.describe() #基本統計量, 但這種方法只能看全部,無法只看你想看的欄位(同時只會顯示量化資料)
Cafe['Sex'].value_counts() #計算一下男女的分佈
Cafe['Edu'].value_counts() #計算一下學歷的分佈
result = Cafe['IncomeMd'].describe() #計算調整後的所得之敘述統計量
pd.DataFrame(result ) #格式化成DataFrame
Cross0 = pd.crosstab(Cafe['Sex'], Cafe['Edu']) #建立交叉列聯表
Cross0
Cross1 = pd.crosstab(Cafe['Sex'], Cafe['A3偏好口味']) #建立交叉列聯表
Cross1
Cross2 = pd.crosstab(Cafe['Area'], Cafe['A3偏好口味']) #建立交叉列聯表
Cross2
#我們可以採取一些更進階的交叉分析表
Cross3 = pd.crosstab(index=[Cafe['Area'], Cafe['Sex']],
columns=Cafe["A3偏好口味"]
)
Cross3
通常一般敘述性統計我們就只能看看單一變數的基本狀況,若我們想要倆倆比較一下,則比較適合用樞紐分析表
Cafe.pivot_table('IncomeMd', index='Sex', columns='Occupatn') #樞紐分析表
Cafe.pivot_table('IncomeMd', index='Occupatn', columns='Area') #樞紐分析表
matplotlib
幾乎是標準 Python 畫圖套件! 在有 matplotlib
之前, Python 要畫圖不那麼方便, 和 Python 很多套件一樣, 有許多方案, 但各家有不同的優缺點, 也沒有一套是大家都在用的。
而 matplotlib
仿 Matlab 式的畫圖方式, 讓很多人很快入手、並且功能相當完整。原作者是 John D. Hunter, 和很多 Python 的套件作者一樣, 他有博士學位。非常令人遺憾的是他在 2012 年因大腸直腸癌治療併發症過逝, 過逝時才 44 歲!
他在過逝前不久, 還被邀請到 SciPy 研討會的 Keynote, 回去之後就被檢查出有大腸直腸癌。因此這部影片大概就是他最後一次的 Keynote, 時間是 2012 年 7 月 18 日 (他在同年 8 月 28 日過逝)
#基礎設定
from matplotlib.font_manager import FontProperties
import seaborn as sns
myfont=FontProperties(fname=r'C:\Users\user\Anaconda3\lib\site-packages\matplotlib\mpl-data\fonts\ttf\msj.ttf',size=14)
sns.set(font=myfont.get_family())
sns.set_style("whitegrid",{"font.sans-serif":['Microsoft JhengHei']})
sns.jointplot(x = "A101左岸頻率", y = "Intenst", data = Cafe)#散佈圖
sns.scatterplot(x="Occupatn", y="Intenst",
hue="A101左岸頻率",
data=Cafe)
#distplot的變數只能放數量資料
sns.distplot(Cafe['Intenst']) #產品強度的次數分佈
# countplot放屬質資料
sns.countplot(x = "A3偏好口味", data=Cafe)
sns.countplot(x = "Income0", data=Cafe)
sns.barplot(x="Occupatn", y="Intenst", data=Cafe)
sns.barplot(x="Occupatn", y="Intenst", hue="Sex", data=Cafe)
from numpy import median
sns.barplot(x="Occupatn", y="A101左岸頻率", data=Cafe, estimator=median) #用每天的中位數去估計小費的高低
sns.boxplot(x = 'Area', y= 'Intenst', data = Cafe)
sns.boxplot(x = 'Area', y= 'Intenst', data = Cafe, hue = 'Sex') # hue = 'sex'以性別當圖標
#這是進階語法,可一次看多個
sns.catplot(x="Area", y="Intenst",
hue="Sex", col="Occupatn",
data=Cafe, kind="bar",
height=4, aspect=.7)
colormap = plt.cm.viridis
plt.figure(figsize=(14,12))
plt.title('Pearson Correlation of Features', y=1.05, size=15)
sns.heatmap(Cafe[['IncomeMd', 'A101左岸頻率', 'Intenst', 'A2咖啡偏好', 'AGE']].astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, cmap=colormap, linecolor='white', annot=True)
Cafe.A101左岸頻率.describe()
Cafe.A102伯朗頻率.describe()
# two sample student t test
import numpy as np
from scipy import stats
mean1 = 0.9 #左岸頻率
mean2 = 0.825 #伯朗頻率
std1 = 0.981887
std2 = 0.873763
nobs1 = 40 #觀察值
nobs2 = 40
modified_std1 = np.sqrt(np.float64(nobs1)/np.float64(nobs1-1)) * std1
modified_std2 = np.sqrt(np.float64(nobs2)/np.float64(nobs2-1)) * std2
(statistic, pvalue) = stats.ttest_ind_from_stats(mean1=mean1, std1=modified_std1, nobs1=40, mean2=mean2, std2=modified_std2, nobs2=40)
print("t statistic is: ", statistic)
print("pvalue is: ", pvalue)
sns.barplot(x="Sex", y="C01閱讀報章", data=Cafe) #以"閱讀報章"為範例
Cafe["Gender"] = Cafe[["Sex"]] #新增一個 Gender欄位,內容是Sex的內容
Cafe.Gender.sample(10)#隨機取10行
from scipy.stats import ttest_ind
males = Cafe[Cafe['Gender']=='男']
females = Cafe[Cafe['Gender']=='女']
stats.ttest_ind(males['C01閱讀報章'], females['C01閱讀報章'])
#ttest_ind(males['C01閱讀報章'], females['C01閱讀報章'], nan_policy='omit')
[PART 4]. 左岸咖啡之市場區隔及目標選擇決策¶
sns.countplot(x = "Occupatn", data=Cafe)
#create an Ordinary Least Squares (OLS) model as a precursor to the ANOVA.
from scipy import stats
import statsmodels
import statsmodels.api as sm
from statsmodels.formula.api import ols
model = ols('Intenst ~ Occupatn', Cafe).fit() #builds the OLS model, predicting weight loss with diet type.
resids = statsmodels.regression.linear_model.RegressionResults.resid(model) # grabs the residual values from the OLS model
hist2 = plt.hist(resids, bins = 'auto', color='dodgerblue') # check for variable normality in weight loss dependent variable.
#Data looks normally distributed.
plt.title("Figure . Distribution of OLS Model Residuals")
plt.xlabel("Residual Values")
plt.ylabel("Count", rotation = 0, labelpad = 40)
plt.show()
table = sm.stats.anova_lm(model, typ=2) # Type 2 ANOVA DataFrame
print(table)
from statsmodels.stats.multicomp import pairwise_tukeyhsd
from statsmodels.stats.multicomp import MultiComparison
mc = MultiComparison(Cafe['Intenst'], Cafe['Occupatn'])
tkresult = mc.tukeyhsd()
print(tkresult)
grouped2 = Cafe['Intenst'].groupby(Cafe['Occupatn']) #以 Occupatn 為分組看 Intenst 的平均數
print(grouped2.mean()) #計算各組均值
import pandas as pd
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
from statsmodels.graphics.factorplots import interaction_plot #產生交互作用圖
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
model = ols('Intenst ~ C(Sex)*C(Occupatn)', Cafe).fit()
res = sm.stats.anova_lm(model, typ= 2) #
res
sns.pointplot(x="Occupatn", y="Intenst", hue="Sex", data=Cafe, linestyles=["-", "--"])#交互作用圖
sns.factorplot(x="Occupatn", y="Intenst", hue="Sex", data=Cafe,
kind="box")
model.summary()
## 各群不同的平均值是多少
pd.crosstab(Cafe.Occupatn, Cafe.Sex, values=Cafe.Intenst, aggfunc='mean').round(2) #取不同組別的平均數,小數點以下兩位
#Our model fit (the linear model fitted with the OLS method) and get a Quantile-Quantile (QQplot):
res = model.resid
fig = sm.qqplot(res, line='s')
plt.show()
[補充:為將來做準備 ]. 我們新建一個分群變數!¶
- Segment
- 1.自營企業
- 2.白領階層
- 3.學生、籃領、其它
Cafe["Segment"] = Cafe[["Occupatn"]] #新增一個 Segment欄位,內容是Occupatn的內容
Cafe.sample(10)#隨機取10行
Cafe["Segment"] = Cafe["Segment"].str.replace("學生","其他")
Cafe["Segment"] = Cafe["Segment"].str.replace("藍領階層","其他")
Cafe.sample(10)#隨機取10行
#所以現在Segment只有三種類別: 自營企業、白領階層、其他
[PART 5]. 左岸咖啡之所得定位 (Multiple Regression)¶
Cafe.IncomeMd.mean() #所得均值
Cafe.A101左岸頻率.mean() #左岸頻率均值
import statsmodels.api as sm
import statsmodels.formula.api as smf
results = smf.ols('A101左岸頻率 ~ IncomeMd', data=Cafe).fit() #簡單迴歸
print(results.summary())
Cafe.A2咖啡偏好.mean() #咖啡偏好均值
results2 = smf.ols('A101左岸頻率 ~ A2咖啡偏好', data=Cafe).fit() #簡單迴歸
print(results2.summary())
results3 = smf.ols('A101左岸頻率 ~ A2咖啡偏好 + IncomeMd', data=Cafe).fit() #複迴歸
print(results3.summary())
[PART 6]. 左岸咖啡之口味差異化策劃¶
- 在本小節,我們要採用卡方獨立性檢定!
你應該還記得,之前我們曾經新建一個Segment(目標市場)的變數
- 1.自營企業
- 2.白領階層
- 3.學生、籃領、其它
目標市場、性別對口味偏好的影響
- 變數定義
- 1.反應變量: A3偏好口味
- 2.解釋變數: Sex、Segment
contingency_table1 = pd.crosstab(index=[Cafe['Occupatn'], Cafe['Sex']],
columns=Cafe["A3偏好口味"]
)
contingency_table1
#我們會發現有些格子的數值<5,表示要併組處理
contingency_table2 = pd.crosstab(Cafe['Sex'], Cafe['A3偏好口味'])
contingency_table2
contingency_table3 = pd.crosstab(Cafe['Segment'], Cafe['A3偏好口味'])
contingency_table3
#因為本次練習的 Sample size只有40個,一定會有所不足,建議在大樣本的情況下應滿足 >5 之條件
import pandas as pd
import researchpy as rp
from scipy import stats
table1, results1 = rp.crosstab(Cafe['Sex'], Cafe['A3偏好口味'], prop= 'col', test= 'chi-square')
table1
results1
table2, results2 = rp.crosstab(Cafe['Segment'], Cafe['A3偏好口味'], prop= 'col', test= 'chi-square')
table2
results2
[最後說明]¶
- 此份資料僅供教學用途,主要用以說明敘述統計及應用統計在Python之應用
- 後續仍然可以用在其他的市場調查議題,若有興趣之同學,可於碩士班時修習"多變量分析",會對市場調查及行銷研究會有更深的體驗
- 本程式碼僅由本人撰寫,若有任何錯誤,請不吝提出,謝謝