day07-k_means算法自实现
01-数据转化
import pandas as pd
import numpy as np
# 将非数值型类别型数据转化为数值型
# 哑变量转化---将数据转化为哑变量矩阵
# 加载数据
data = pd.read_excel('./meal_order_detail.xlsx')
# print('data:\n',data)
# print('data的列索引:\n',data.columns)
# print('data :\n', data.loc[:, "dishes_name"])
print('data :\n', data.loc[:, "amounts"])
print('data 中amounts列的最大值:', data.loc[:, "amounts"].max())
print('data 中amounts列的最小值:', data.loc[:, "amounts"].min())
print('*' * 100)
#
# # 将detail 中的 dishes_name 进行哑变量转化
# res = pd.get_dummies(
# data=data.loc[:, 'dishes_name'], # 数据
# prefix='菜品', # 前缀
# prefix_sep=':' # 连接符
# )
# print('哑变量之后的结果:\n', res)
# 将连续型数据离散成类别数据 ---数据离散化
# 将连续的数据进行划分区间
# 将 detail 中 amounts单价列进行离散化
# 1、默认进行分组
# 2、自定义等宽分组
# # (1)确定分组个数
# group_num = 5
# # (2)确定极差
# # 确定最大值
# max_amounts = data.loc[:, "amounts"].max()
# # 确定最小值
# min_amounts = data.loc[:, "amounts"].min()
# # 确定极差
# ptp = max_amounts - min_amounts
# # (3)确定步长
# step = int(np.ceil(ptp / group_num))
# # (4)确定bins
# bins = np.arange(min_amounts, max_amounts + step, step)
# print('自定义等宽分组:', bins)
# 3、自定义等频分组 --利用分位数进行分组
# (1)确定分组个数
group_num = 5
# (2)确定bins
bins = data.loc[:, 'amounts'].quantile(q=np.arange(0, 1 + 1 / group_num, 1 / group_num))
# [0,0.2,0.4,0.6,0.8,1.0]
print('bins:', bins)
data.loc[:, 'amounts'] = pd.cut(
x=data.loc[:, 'amounts'], # 需要离散化的数据
# bins=5, # 默认分组
bins=bins,
include_lowest=True, # 包含最小值,自定义分组默认是不包含最小值的
)
print('离散化之后的结果:\n', data.loc[:, 'amounts'])
print('*' * 100)
# value_counts --可以统计落在各个区间内的数量
res = pd.value_counts(data.loc[:, 'amounts'])
print('res:\n', res)
02-相关性计算
import pandas as pd
# 相关性,相似性
# 用相关性系数---corr
# 加载数据 ---amounts counts
data = pd.read_excel('./meal_order_detail.xlsx')
print('data:\n', data)
print('data 的列索引:\n', data.columns)
print('*' * 100)
# 只能用于 数值型数据
# 计算amounts counts 两列之间的相关性系数
# method --->{'pearson', 'kendall', 'spearman'} 相关计算的算法
res = data.loc[:, ['amounts', 'counts']].corr()
print('res:\n', res)
# 负相关---一个增大,另外减小 -----菜品价格越高,买的数量越少
# 正相关---一个增大,另外增大 -----身高越高,体重越大
data = data.loc[:, ['detail_id', 'order_id', 'dishes_id', 'counts', 'amounts']]
# 计算两两之间的相关性系数
for c1 in data.columns:
for c2 in data.columns:
if c1 != c2:
print('%s与%s:' % (c1, c2), end='')
print('相关性系数为:', data.loc[:, [c1, c2]].corr())
03-k_means算法原理自实现
import numpy as np
def build_data():
"""
加载数据
:return:data
"""
# 加载.txt文件
# python ---with open
# numpy ----loadtxt ---数组类型的txt
# pandas ---read_table
data = np.loadtxt('./test.txt', delimiter='\t')
# 将数组转化为矩阵
data = np.mat(data)
print('data:\n', data)
print('data:\n', type(data))
return data
def center_init(data, k):
"""
初始化聚类中心
:param data: 数据
:param k: 聚类的类别
:return: 初始化的center
"""
# 法一:
# # 随机初始化
# # 获取样本的行数
# index_num = data.shape[0]
# # 获取样本数据的列数
# column_num = data.shape[1]
# # # 初始化一个占位的聚类中心
# center = np.zeros(shape=(k, column_num))
# # 在样本数据里面随机选择4个点作为聚类中心
# # 先构建一个存储 r的列表
# r_list = []
# # 再来一个计数因子i
# i = 0
# while True:
# # 随机在 所有的样本中找出 4个 样本
# r = np.random.randint(low=0, high=index_num)
# print('r:\n', r)
# # 如果随机初始化的r是第一次出现,那么添加到r_list,赋值给center
# if r not in r_list:
# r_list.append(r)
# center[i, :] = data[r, :]
# # 如果不是,重新进行随机并赋值
# else:
# continue
# # 退出条件
# if len(r_list) == k:
# break
# i += 1
# 法二:
# 获取样本的行数
index_num = data.shape[0]
# 构建所有样本的 行下标列表
index_arr = np.arange(index_num)
# 随机选择 k 个行的下标 --组成一个行下标列表
# replace=False --不重复的选择
index = np.random.choice(index_arr, k, replace=False)
print(index)
# 将样本数据里面 index 所在的行数据赋值给聚类中心
center = data[index, :]
return center
def distance(v1, v2):
"""
距离计算
:param v1:点1
:param v2: 点2
:return: 距离
"""
# # 法一:
# # v1 = v1[0]
# # 把矩阵转化为数组
# v1 = v1.A[0]
# v2 = v2.A[0]
# print('v1:\n', v1)
# print('v2:\n', v2)
#
# sum_dist = 0
# for i in range(v1.shape[0]):
# sum_dist += (v1[i] - v2[i]) ** 2
#
# # 计算距离
# dist = np.sqrt(sum_dist)
# 法二
x = np.power(v1 - v2, 2)
# print('x:\n', x)
dist = np.sqrt(np.sum(x))
# print('dist:\n', dist)
return dist
def k_means_owns(data, k):
"""
k-means算法自实现
:param data: data
:param k: 聚类的类别
:return:
"""
# 1、随机初始化聚类中心
center = center_init(data, k)
# print('center:\n', center)
# 获取样本的行数
index_num = data.shape[0]
# 构建一个保存样本与聚类中心最短距离及所属的聚类中心的数组
new_data = np.zeros(shape=(index_num, 2))
# 开关
flag = True
while flag:
flag = False
# 2、计算每一个样本与每一个聚类中心的距离
for i in range(index_num):
min_dist = 10000000000
min_index = -1
for j in range(k):
# 计算距离
dist = distance(data[i, :], center[j, :])
if dist < min_dist:
# 赋值给最小距离
min_dist = dist
# 赋值给min_index
min_index = j
# 如果所有样本聚类类别不发生变化,则表示聚类结束
# 如果一旦发生变化,继续调整聚类中心,重新计算
if new_data[i, 1] != min_index:
flag =True
new_data[i, :] = min_dist, min_index
if flag:
# 计算簇的中心
# 分别计算各个簇的中心
for p in range(k):
# 找出各个簇的样本--bool_index
bool_index = new_data[:, 1] == p
# 找出各个簇的样本
p_cluster = data[bool_index, :]
# 调整聚类中心
center[p, :] = p_cluster[:, 0].mean(), p_cluster[:, 1].mean()
return new_data,center
def show_res():
"""
结果展示
:return:
"""
pass
def main():
"""
主函数
:return: None
"""
# 加载数据
data = build_data()
# 自实现k_means
# 确定聚类的类别数目
k = 4
new_data,center = k_means_owns(data, k)
print('new_data:\n',new_data)
print('center:\n',center)
# 结果展示
show_res()
if __name__ == '__main__':
main()
测试
import numpy as np
# 点1
v1 = np.array([[1, 2]]) # 一维数组,2维空间的点
v2 = np.array([[3, 4]])
# v ==[a,b,c,d,e,f] # 一维数组,六维空间的点
# 根号 ((x1-x2) **2 + (y1 -y2)**2)
# 法一:
# sum_dist = 0
# for i in range(len(v1)):
#
# sum_dist += (v1[i] - v2[i]) ** 2
#
# # 计算距离
# dist = np.sqrt(sum_dist)
# 法二:
x = np.power(v1-v2, 2)
print('x:\n', x)
dist = np.sqrt(np.sum(x))
print('dist:\n', dist)
day07-means算法(上)
猜你喜欢
转载自blog.csdn.net/return_min/article/details/103975216
今日推荐
周排行