个性化聚类推荐Kmeans实战

与内容无关

数据预处理

1. 去除不需要的数据

目标是:一个用户,后面全是用户的特征

  • 列数据中 Null 数据 > 80% 所有数据 isnull().sum()
  • 列数据中一样的数据 > 80%所有数据 value_counts()
  • 表示同一个意思的字段,只需要保留一个:如用户名、用户账号、支付账号、收货人姓名
  • 根据场景分析不需要的字段:如买家应付货款、应付邮费等

2. 只获取指定的列数据

df_order.ix[:, '订单编号', '买家会员名', '买家实际支付金额', '收货地址', '种类', '数量', '退款金额']
# ix是loc与iloc的合集,其中loc是按照列名来取数据,iloc是按照列的index来取数据

或者

df_order[['订单编号', '买家会员名', '买家实际支付金额', '收货地址', '种类', '数量', '退款金额']]

3. 对数据进行格式化

df_order['收货地址'] = df_order['收货地址'].apply(lambda x:x.split()[0])

4. 按照某列数据给整行数据打tag

def add_tag(info):
  if '月' in info:
    tag = '婴儿|'
  if '':
    tag = '幼儿|'
  if:
    tag = '学生|'
  return tag[:-1]
attrs['tag'] = attrs['适用年龄'].apply(add_tag)

5. 数据合并

pd.merge(items, attrs, on='标题', how='inner')

6. 对每个用户进行分组汇总

order_tag['购买次数'] = 1
test2 = order_tag.groupby(['买家会员名', 'tag2']).count()
test2.unstack('tag2').fillna(0) # unstack将会把索引数据中的一列转为列名

7. 对重复的数据取平均值

res1 = res1.groupby(['会员', '地址']).mean()
res1.reset_index(inplace=True)

8. 将字符串转为数值的方法有两种:

  1. 用数值表示具体值,如:好、一般、差就用相关数值表示
  2. unstack将它转为column,或者get_dummies方法将非数值型转为column
pd.get_dummies?
result2= pd.get_dummies(res1) ##只会对非数值型有效

最后得到的数据:

       买家实际支付金额  宝贝种类  宝贝总数量  退款金额  收货地址_上海  收货地址_云南省  收货地址_内蒙古自治区  收货地址_北京  \
买家会员名                                                                         
409       35.31     8     11   0.0        0         0            0        0   
2270      13.70     1      3   0.0        0         0            0        0   
1908      55.09     7      7   0.0        0         0            0        0   
1727      62.72    11     14   0.0        1         0            0        0   
1976      18.80     1      2   0.0        0         1            0        0   

       收货地址_吉林省  收货地址_四川省    ...      收货地址_湖北省  收货地址_湖南省  收货地址_甘肃省  收货地址_福建省  \
买家会员名                        ...                                               
409           0         0    ...             0         0         0         0   
2270          0         0    ...             0         0         0         0   
1908          0         0    ...             0         0         0         0   
1727          0         0    ...             0         0         0         0   
1976          0         0    ...             0         0         0         0   

       收货地址_贵州省  收货地址_辽宁省  收货地址_重庆  收货地址_陕西省  收货地址_青海省  收货地址_黑龙江省  
买家会员名                                                              
409           0         0        0         0         0          0  
2270          0         0        0         0         0          0  
1908          0         0        0         0         0          0  
1727          0         0        0         0         0          0  
1976          0         0        0         0         0          0  

基于用户聚类

目标:对用户进行标记分类

1. 数据标准化

from sklearn.preprocessing import MinMaxScaler
data = order_df.ix[:,1:].values  #去掉第一列数据,也就是用户id
mms=MinMaxScaler()
data_nore = mms.fit_transform(data)
print(data_nore)

2. 聚类

- 手肘法
from sklearn.cluster import KMeans
from matplotlib import pyplot as plt
sse = []
for k in range(1,15):
    km = KMeans(n_clusters=k)
    km.fit(data_nore)
    sse.append(km.inertia_)
x = range(1, 15)
y = sse
plt.plot(x,y)
plt.show()

- 轮廓法
from sklearn.metrics import silhouette_score
score = []
for k in range(2, 15):
    km=KMeans(n_clusters=k)
    res_km = km.fit(data_nore)
    score.append(silhouette_score(data_nore, res_km.labels_))
plt.plot(range(2, 15), score, marker='o')

#根据上面的值取得最优n_clusters值,例如为8
from sklearn.cluster import KMeans
km=KMeans(n_clusters=8)
res_km = km.fit(data_nore)
km.labels_ # 这个就是聚类结果,也是最终需要的结果

3. 将类别添加到分析数据中

result2['类别'] = km.labels_ #对原始用户进行类别标记

基于用户聚类进行推荐

目标:向用户推荐产品

同一类群中,大多数人喜欢的商品,用户也喜欢

order_df['商品购买次数'] = 1
data = order_df.groupby(['类别','商品'].count()) #不同类别人对商品的关注程度
data.reset_index(inplace=True)
print(data.ix[:, ['类别','商品', '商品购买次数']]) #得到类别->商品->购买次数

推荐给用户同一个类别,而没有购买过的商品,按照购买次数排序推荐。

基础知识

pandas.DataFrame基本方法

df.info() #查看数据信息
df.shape #获得数据行列数
del(df['a']) #删除某列数据
df['col'].values #查看数据
df.columns #查看列名
df.reset_index(inplace=True) #重置索引
df.index = df['index'] #创建索引
df = df.set_index('index') #将某列设置为索引

df合并

merged_df = left_df.merge(right_df, how="left", left_on=u'主机配置', right_on=u'主机说明')

根据某条数据的属性添加新的数据列

df['b'] = 0
df['b'][df['a']==1] = 8 ##注意先选完整的列,再过滤才能赋值

读取文件时,默认是utf8格式,也可以指定编码

常见的编码方式有:ascii/utf8/unicode/utf-16/gb2312/gbk/gb18030

pd.read_csv('file_path.csv', encoding='gb2312')

将一列数据转为多列数据

df = pd.DataFrame([{"a": 1, "name":"1|2|4"}, {"a": 2, "name":"1|5|9"}])
df[["b", "c", "d"]] = df['name'].str.split('|', expand=True)  # 多名字分列
# 或者
df = df.join(df['name'].str.split('|', expand=True))

result:
   a   name  b  c  d
0  1  1|2|4  1  2  4
1  2  1|5|9  1  5  9

将DataFrame中的tuple分割成数据框的多列

df = pd.DataFrame({'a':[1,2], 'b':[(1,2), (3,4)]})
df[['b1', 'b2']] = df['b'].apply(pd.Series)
# 或者
df = df.join(df['b'].apply(pd.Series))

result:
     a       b  0  1
0  1  (1, 2)  1  2
1  2  (3, 4)  3  4

stack与unstack使用说明:python pandas stack和unstack函数

利用当前数据的多列数据得到新的数据列

df['new_column'] = df.apply(lambda row: row['column1'] * row['column2'], axis=1)
# 或者
df['new_column']  = df['column1'] * df['column2']
# 或者
df.ix[:, 'new_column'] = df['column1'] * df['column2']

得到类型中有关系数据库的数据

df[df[u'类型'].str.contains(u'关系数据库')]

apply函数返回多列数据

def parse(item):
    return pd.Series([item*2, item*4])

a = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
a[['2倍', '4倍']] = a['a'].apply(parse)

result:
   a  b  2倍  4倍
0  1  4   2   4
1  2  5   4   8
2  3  6   6  12

过滤逻辑类型

np.logical_and

data = df[np.logical_and(df['col1'].notnull(), df['col1'].str.contains('item'))]

更改列名

data = df.rename(columns={'col1': u'列1', 'col2': u'列2'})

将数据转化为常用类型

col1_data = df['col1'].tolist()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容