day07-means算法(上)

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)

发布了132 篇原创文章 · 获赞 24 · 访问量 5187

猜你喜欢

转载自blog.csdn.net/return_min/article/details/103975216