python客户价值分析_[Python数据挖掘]第7章、航空公司客户价值分析
一、背景和挖掘目標
二、分析方法與過程
客戶價值識別最常用的是RFM模型(最近消費時間間隔Recency,消費頻率Frequency,消費金額Monetary)
1、EDA(探索性數據分析)
#對數據進行基本的探索
importpandas as pd
data= pd.read_csv('data/air_data.csv', encoding = 'utf-8') #讀取原始數據,指定UTF-8編碼(需要用文本編輯器將數據裝換為UTF-8編碼)
explore= data.describe(percentiles = [], include = 'all').T #包括對數據的基本描述,percentiles參數是指定計算多少的分位數表(如1/4分位數、中位數等);T是轉置,轉置后更方便查閱
explore['null'] = len(data)-explore['count'] #describe()函數自動計算非空值數,需要手動計算空值數
explore= explore[['null', 'max', 'min']]
explore.columns= [u'空值數', u'最大值', u'最小值'] #表頭重命名
'''這里只選取部分探索結果。
describe()函數自動計算的字段有count(非空值數)、unique(唯一值數)、top(頻數最高者)、freq(最高頻數)、mean(平均值)、std(方差)、min(最小值)、50%(中位數)、max(最大值)'''explore.to_excel('tmp/explore.xls') #導出結果
2、數據預處理
1.數據清洗
data = data[data['SUM_YR_1'].notnull()&data['SUM_YR_2'].notnull()] #票價非空值才保留
#只保留票價非零的,或者平均折扣率與總飛行公里數同時為0的記錄。
index1 = data['SUM_YR_1'] !=0
index2= data['SUM_YR_2'] !=0
index3= (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0) #該規則是“與”
data = data[index1 | index2 | index3] #該規則是“或”
票價為空表示該值缺失,票價為0表示飛這一趟沒花錢,二者概念不同
2.屬性規約
原始數據屬性太多,根據之前提出的LRFMC模型,只保留6個與之相關的屬性
3.數據變換
方法1:EXCEL手動操作(方便簡單)
data_select.to_excel('tmp/data_select.xls', index = False) #數據寫入
方法2:代碼操作(方便新增信息的抽取)
from datetime importdatetime#使用匿名函數將LOAD_TIME數據轉換成datetime格式,然后才能進行日期加減(匿名函數比for循環效率高)
data_select['LOAD_TIME_convert'] = data_select['LOAD_TIME'].apply(lambda x: datetime.strptime(x, '%Y/%m/%d'))
data_select['FFP_DATE_convert'] = data_select['FFP_DATE'].apply(lambda x: datetime.strptime(x, '%Y/%m/%d'))#構造一個Series序列接收 (LOAD_TIME-FFP_DATE)
data_select['L']=pd.Series()#(LOAD_TIME-FFP_DATE)得到兩個日期之間的天數間隔,然后除以30得到月份間隔 這一步相當費時
for i inrange(len(data_select)):
data_select['L'][i] =(data_select['LOAD_TIME_convert'][i]-data_select['FFP_DATE_convert'][i]).days/30data_select= data_select.rename(columns = {'LAST_TO_END': 'R','FLIGHT_COUNT':'F','SEG_KM_SUM':'M','avg_discount':'C'})
data_selected=data_select[['L','R','F','M','C']]
data_selected
接下來進行數據標準化
#標準差標準化
importpandas as pd
data= pd.read_excel('data/zscoredata.xls', index =False)
data= (data - data.mean(axis = 0))/(data.std(axis = 0)) #簡潔的語句實現了標準化變換,類似地可以實現任何想要的變換。
data.columns=['Z'+i for i in data.columns] #表頭重命名。
data.to_excel('tmp/zscoreddata.xls', index = False) #數據寫入
3、模型構建
1.客戶聚類
#K-Means聚類算法
importpandas as pdfrom sklearn.cluster import KMeans #導入K均值聚類算法
k= 5 #需要進行的聚類類別數
#讀取數據并進行聚類分析
data = pd.read_excel('data/zscoreddata.xls')#調用k-means算法,進行聚類分析
kmodel = KMeans(n_clusters = k, n_jobs = 4) #n_jobs是并行數,一般等于CPU數較好
kmodel.fit(data) #訓練模型
#kmodel.cluster_centers_ #查看聚類中心#kmodel.labels_ #查看各樣本對應的類別
#簡單打印結果
s = pd.Series(['客戶群1','客戶群2','客戶群3','客戶群4','客戶群5'], index=[0,1,2,3,4]) #創建一個序列s
r1 = pd.Series(kmodel.labels_).value_counts() #統計各個類別的數目
r2 = pd.DataFrame(kmodel.cluster_centers_) #找出聚類中心
r = pd.concat([s,r1,r2], axis = 1) #橫向連接(0是縱向),得到聚類中心對應的類別下的數目
r.columns =[u'聚類名稱'] +[u'聚類個數'] + list(data.columns) #重命名表頭
print(r)
2.客戶價值分析
#雷達圖代碼摘自 https://blog.csdn.net/Just_youHG/article/details/83904618
defplot_radar(data):'''the first column of the data is the cluster name;
the second column is the number of each cluster;
the last are those to describe the center of each cluster.'''kinds=data.iloc[:, 0]
labels= data.iloc[:, 2:].columns
centers= pd.concat([data.iloc[:, 2:], data.iloc[:,2]], axis=1)
centers=np.array(centers)
n=len(labels)
angles= np.linspace(0, 2*np.pi, n, endpoint=False)
angles=np.concatenate((angles, [angles[0]]))
fig=plt.figure()
ax= fig.add_subplot(111, polar=True) #設置坐標為極坐標
#畫若干個五邊形
floor = np.floor(centers.min()) #大于最小值的最大整數
ceil = np.ceil(centers.max()) #小于最大值的最小整數
for i in np.arange(floor, ceil + 0.5, 0.5):
ax.plot(angles, [i]* (n + 1), '--', lw=0.5 , color='black')#畫不同客戶群的分割線
for i inrange(n):
ax.plot([angles[i], angles[i]], [floor, ceil],'--', lw=0.5, color='black')#畫不同的客戶群所占的大小
for i inrange(len(kinds)):
ax.plot(angles, centers[i], lw=2, label=kinds[i])#ax.fill(angles, centers[i])
ax.set_thetagrids(angles* 180 / np.pi, labels) #設置顯示的角度,將弧度轉換為角度
plt.legend(loc='lower right', bbox_to_anchor=(1.5, 0.0)) #設置圖例的位置,在畫布外
ax.set_theta_zero_location('N') #設置極坐標的起點(即0°)在正北方向,即相當于坐標軸逆時針旋轉90°
ax.spines['polar'].set_visible(False) #不顯示極坐標最外圈的圓
ax.grid(False) #不顯示默認的分割線
ax.set_yticks([]) #不顯示坐標間隔
plt.show()
plot_radar(r)#調用雷達圖作圖函數
4、決策支持
三、【拓展思考】客戶流失分析
1、目標
2、數據預處理
參考自https://blog.csdn.net/zhouchen1998/article/details/85113535
importpandas as pdfrom datetime importdatetimedefclean(data):'''數據清洗,去除空記錄'''data= data[data['SUM_YR_1'].notnull() & data['SUM_YR_2'].notnull()] #票價非空值才保留
#只保留票價非零的,或者平均折扣率與總飛行公里數同時為0的記錄。
index1 = data['SUM_YR_1'] !=0
index2= data['SUM_YR_2'] !=0
index3= (data['SEG_KM_SUM'] == 0) & (data['avg_discount'] == 0) #該規則是“與”
data = data[index1 | index2 | index3] #該規則是“或”
#取出需要的屬性列
data = data[['LOAD_TIME', 'FFP_DATE', 'LAST_TO_END', 'FLIGHT_COUNT', 'avg_discount', 'SEG_KM_SUM', 'LAST_TO_END','P1Y_Flight_Count', 'L1Y_Flight_Count']]returndatadefLRFMCK(data):'''經過計算得到我的指標數據'''
#其中K為標簽標示用戶類型
data2 = pd.DataFrame(columns=['L', 'R', 'F', 'M', 'C', 'K'])
time_list=[]for i in range(len(data['LOAD_TIME'])):
str1= data['LOAD_TIME'][i].split('/')
str2= data['FFP_DATE'][i].split('/')
temp= datetime(int(str1[0]), int(str1[1]), int(str1[2])) - datetime(int(str2[0]), int(str2[1]), int(str2[2]))
time_list.append(temp.days)
data2['L'] =pd.Series(time_list)
data2['R'] = data['LAST_TO_END']
data2['F'] = data['FLIGHT_COUNT']
data2['M'] = data['SEG_KM_SUM']
data2['C'] = data['avg_discount']
temp= data['L1Y_Flight_Count'] / data['P1Y_Flight_Count']for i inrange(len(temp)):if temp[i] >=0.9:#未流失客戶
temp[i] = 'A'
elif 0.5 < temp[i] < 0.9:#準流失客戶
temp[i] = 'B'
else:
temp[i]= 'C'data2['K'] =temp
data2.to_csv('data/data_changed.csv', encoding='utf-8')defstandard():'''標準差標準化'''data= pd.read_csv('data/data_changed.csv', encoding='utf-8').iloc[:, 1:6]#簡潔的語句實現了標準化變換,類似地可以實現任何想要的變換
data = (data - data.mean(axis=0)) / (data.std(axis=0))
data.columns= ['Z' + i for i indata.columns]
data2= pd.read_csv('data/data_changed.csv', encoding='utf-8')
data['K'] = data2['K']
data.to_csv('data/data_standard.csv', index=False)if __name__ == '__main__':
data= pd.read_csv('data/air.csv', encoding='utf-8', engine='python')
data=clean(data)
data.to_csv('data/data_filter.csv', index = False, encoding='utf-8')
data= pd.read_csv('data/data_filter.csv', encoding='utf-8') #不重新讀取的話,調用LRFMCK會報錯,我也不知道為什么
LRFMCK(data)
standard()
不知道為什么,總是要反復寫入文件和讀取文件,不然會莫名其妙的報錯。猜測可能是csv文件與xls文件不同導致
3、模型構建
importpandas as pdfrom sklearn importtreefrom sklearn.model_selection importtrain_test_splitfrom sklearn.metrics import confusion_matrix #導入混淆矩陣函數
importpydotplus#讀取數據
defgetDataSet(fileName):
data=pd.read_csv(fileName)
dataSet=[]for item indata.values:
dataSet.append(list(item[:5]))
label= list(data['K'])returndataSet, label#作圖評估
defcm_plot(y, yp):
cm= confusion_matrix(y, yp) #混淆矩陣
plt.matshow(cm, cmap=plt.cm.Greens) #畫混淆矩陣圖,配色風格使用cm.Greens,更多風格請參考官網。
plt.colorbar() #顏色標簽
for x in range(len(cm)): #數據標簽
for y inrange(len(cm)):
plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
plt.ylabel('True label') #坐標軸標簽
plt.xlabel('Predicted label') #坐標軸標簽
returnplt
data, label= getDataSet('data/data_standard.csv')
train_data, test_data, train_label, test_label= train_test_split(data, label, test_size=0.2)#使用決策樹
clf = tree.DecisionTreeClassifier(max_depth=5)
clf=clf.fit(train_data, train_label)#可視化
dataLabels = ['ZL', 'ZR', 'ZF', 'ZM', 'ZC', ]
data_list=[]
data_dict={}for each_label indataLabels:for each indata:
data_list.append(each[dataLabels.index(each_label)])
data_dict[each_label]=data_list
data_list=[]
lenses_pd=pd.DataFrame(data_dict)#print(lenses_pd.keys())
#畫決策樹的決策流程
dot_data =StringIO()
tree.export_graphviz(clf, out_file=dot_data, feature_names=lenses_pd.keys(),
class_names=clf.classes_, filled=True, rounded=True, special_characters=True)
graph=pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_pdf("tree.pdf")
cm_plot(test_label, clf.predict(test_data)).show()
總結
以上是生活随笔為你收集整理的python客户价值分析_[Python数据挖掘]第7章、航空公司客户价值分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本升级加固态到光驱系统启动不了光驱改
- 下一篇: 重装系统找不到硬盘戴尔笔记本重装系统找不