【430722199705200072】第17位表示性别,奇数表示男性,偶数表示女性。
二、以下用 python 作答,数据源还是原来四张表
1.假设要关注门店质量分布情况,能根据门店质量情况制定运营政策,并且能监测运营政策驱动的门店质量变化。做一个满足上述需求的门店 RFM 模型设计,并写一下模型开发逻辑。
- 1、用sql语句'select orderno,saleamount,storeid,gmtpaid from order'取数,并导入pandas【暂不涉及缺失值和异常值处理】
- 2、以storeid为index,构造rfm(及R、F、M三列特征:分别用'gmtpaid','orderno','saleamount'三列特征代替)
#用sql语句'select orderno,saleamount,storeid,gmtpaid from order'取数,并导入pandas【暂不涉及缺失值和异常值处理】
import pymysql
import pandas as pd
from sqlalchemy import create_engine
sql='select orderno,saleamount,storeid,gmtpaid from order'
engine=create_engine('mysql+pymysql://root:mima@localhost:3306/data?charset=utf8')
df=pd.read_sql(sql,engine)
#以storeid为index,构造rfm(及R、F、M三列特征:分别用'gmtpaid','orderno','saleamount'三列特征代替)
rfm=df.pivot_table(index='storeid',values=['gmtpaid','orderno','saleamount'],
aggfunc={'gmtpaid':'max',
'orderno':'count',
'saleamount':'sum'})
rfm['R'] = -(rfm['gmtpaid']-rfm['gmtpaid'].max())/np.timedelta64(1,'D')
rfm.rename(columns={'orderno':'F','saleamount':'M'},inplace=True)
def rfm_func(x):
level=x.apply(lambda x:'1' if x>=0 else '0')
label=level.R + level.F +level.M
d={
'111':'重要价值客户',
'011':'重要保持客户',
'101':'重要挽留客户',
'001':'重要发展客户',
'110':'一般价值客户',
'010':'一般保持客户',
'100':'一般挽留客户',
'000':'一般发展客户'
}
result=d[label]
return result
rfm['label']=rfm[['R','F','M']].apply(lambda x : x-x.mean()).apply(rfm_func,axis = 1)
2.用 Kmeans 算法根据购买次数,购买金额,购买时间,门店名称,购买商品这几个指标去筛选出异常用户,异常用户举例:短时间内在同一个门店购买同一个商品很多次,或者累计购买次数或者金额严重异常等等
- 利用“手肘图拐点法”、“轮廓系数法”确定聚类(先经预处理:标准化)的个数K;
- 基于具体的K值,得到聚类的结果,并计算簇内每个点到簇中心的距离;
- 将距离跟阈值(采用基于箱线图的分位数法 或者 基于正态分布的参考线法)相比较,如果其大于阈值则认为是异常,否则正常;
#用sql语句取数,并导入pandas【暂不涉及缺失值和异常值处理】
import pymysql
import pandas as pd
from sqlalchemy import create_engine
sql='
select a.memberid,a.orderno,a.saleamount,a.gmtpaid,b.storename,c.drug_name
from order a
left join store b on a.storeid=b.id
left join order_item c on c.orderno=a.orderno
'
engine=create_engine('mysql+pymysql://root:mima@localhost:3306/data?charset=utf8')
df=pd.read_sql(sql,engine)
df = df.set_index('memberid')
##预处理
from sklearn.preprocessing import StandardScaler
st=StandardScaler()
st = st.fit(df)
st_df= st.transform(df)
##kmeans聚类:手肘法作图确定聚类个数K
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
% matplotlib inline
SSE_st = []
for k in range(1,21):
kmodel = KMeans(n_clusters=k) # 构造聚类器
kmodel.fit(st_df.astype('float32'))
SSE_st.append(kmodel.inertia_) # .inertia_获取聚类准则的总和
print('SSE_st',k,SSE_st)
fig = plt.figure(figsize=(10, 4))
ax1 = fig.add_subplot(1,1,1)
X = range(1,20)
ax1.set_xlabel('k')
ax1.set_ylabel('SSE_st')
ax1.plot(X,SSE_st,'o-')
plt.show()
##kmeans聚类:确定异常值
def kmeans_outliers(data, clusters, is_scale = True):
# 指定聚类个数,准备进行数据聚类
kmeans = KMeans(n_clusters=clusters)
# 用于存储聚类相关的结果
cluster_res = []
# 判断是否需要对数据做标准化处理
if is_scale:
std_data = scale(data) # 标准化
kmeans.fit(std_data) # 聚类拟合
# 返回簇标签
labels = kmeans.labels_
# 返回簇中心
centers = kmeans.cluster_centers_
for label in set(labels):
# 计算簇内样本点与簇中心的距离
diff = std_data[np.array(labels) == label,] - np.array(centers[label])
dist = np.sum(np.square(diff), axis=1)
# 计算判断异常的阈值
UL = dist.mean() + 3*dist.std()
# 识别异常值,1表示异常,0表示正常
OutLine = np.where(dist > UL, 1, 0)
raw_data = data.loc[np.array(labels) == label,]
new_data = pd.DataFrame({'Label':label,'Dist':dist,'OutLier':OutLine})
# 重新修正两个数据框的行编号
raw_data.index = new_data.index = range(raw_data.shape[0])
# 数据的列合并
cluster_res.append(pd.concat([raw_data,new_data], axis = 1))
else:
kmeans.fit(data) # 聚类拟合
# 返回簇标签
labels = kmeans.labels_
# 返回簇中心
centers = kmeans.cluster_centers_
for label in set(labels):
# 计算簇内样本点与簇中心的距离
diff = np.array(data.loc[np.array(labels) == label,]) - np.array(centers[label])
dist = np.sum(np.square(diff), axis=1)
UL = dist.mean() + 3*dist.std()
OutLine = np.where(dist > UL, 1, 0)
raw_data = data.loc[np.array(labels) == label,]
new_data = pd.DataFrame({'Label':label,'Dist':dist,'OutLier':OutLine})
raw_data.index = new_data.index = range(raw_data.shape[0])
cluster_res.append(pd.concat([raw_data,new_data], axis = 1))
# 返回数据的行合并结果
return pd.concat(cluster_res)
# 调用函数,返回异常检测的结果
res = kmeans_outliers(df,K,True)
sns.lmplot(x="x1", y="x2", hue='OutLier', data=res,
fit_reg=False, legend=False)
plt.legend(loc='best')
plt.show()
1、图形法(如箱线图、正态分布图:基于箱线图的分位数法和基于正态分布的参考线法):Python数据清洗--异常值识别与处理01
基于箱线图的分位数法和基于正态分布的参考线法都可以实现异常值【1.5(Q3-Q1)、偏离均值正负2倍标准差内】和极端异常值【3(Q3-Q1)、偏离均值正负3倍标准差内】的识别,但是在实际应用中,需要有针对性的选择。如果待判断的变量近似服从正态分布,建议选择正态分布的参考线法识别异常点,否则使用分位数法识别异常点。
2、建模法(如线性回归、聚类算法、K近邻算法):如何利用K均值聚类实现异常值的识别
3、使用python进行异常值(outlier)检测实战:KMeans + PCA + IsolationForest + SVM + EllipticEnvelope
1、计算每个数据点与其最近的聚类中心之间的距离。 最大的距离被认为是异常的。
2、设定一个异常值的比例outliers_fraction为1%,这样设置是因为在标准正太分布的情况下(N(0,1))我们一般认定3个标准差以外的数据为异常值,3个标准差以内的数据包含了数据集中99%以上的数据,所以剩下的1%的数据可以视为异常值。
3、根据异常值比例outliers_fraction,计算异常值的数量number_of_outliers
4、设定一个判定异常值的阈值threshold
5、通过阈值threshold来判定数据是否为异常值
6、对数据进行可视化(包含正常数据和异常数据)
3.假设用户表里有标识字段 type ,其中数据分为 normal 正常用户,doubt 可疑用户。用随机森林算法根据购买次数,购买金额,性别,年龄,购买时间,连锁名称,购买商品,type 这几个指标去预测新下单用户是正常用户还是可疑用户
#用sql语句取数,并导入pandas【暂不涉及缺失值和异常值处理】
import pymysql
import pandas as pd
from sqlalchemy import create_engine
sql='
select a.orderno,a.saleamount,a.gmtpaid,a.merchantname,c.drug_name,
substring(b.card_num,13,1) as sex,year(now())-substring(b.card_num,7,4) as age
b.type
from order a
left join member b on a.memberid=b.id
left join order_item c on a.orderno=c.orderno
'
engine=create_engine('mysql+pymysql://root:mima@localhost:3306/data?charset=utf8')
df=pd.read_sql(sql,engine)
#RF的实例化、fit、predict【省略调参】;不划分训练与测试集,而直接用袋外数据来预测。
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=100,oob_score=True) #袋外数据来预测
rf.fit(df.iloc[:,0:-1],df['type'])
参考
2、完整代码:使用python进行异常值(outlier)检测.ipynb
3、books
基于python的RFM模型和K-Means算法的用户特征分析
聚类、K-Means、例子、细节
【关于离群值?】答:离群值就是远离整体的,非常异常、非常特殊的数据点,在聚类之前应该将这些“极大”“极小”之类的离群数据都去掉,否则会对于聚类的结果有影响。但是,离群值往往自身就很有分析的价值,可以把离群值单独作为一类来分析。
【数据分析】通过异常数据找出薅羊毛用户
K-means算法分析航空公司客户价值
Python之使用K-Means算法聚类消费行为特征数据分析(异常点检测)
使用pandas 、numpy 、K-means算法、matplotlib分析航空公司客户价值
网友评论