机器学习练手(二):基于KMeans的股票分类

news2025/2/27 4:54:46

总结:本文为和鲸python 可视化探索训练营资料整理而来,加入了自己的理解(by GPT4o)

原活动链接

在前一关我们学习了逻辑回归,学会如何训练模型、数据基础性分析、如何处理空值等操作,下面我们开始新的一关 KMeans

目录

      • KMeans
      • 基于 `KMeans` 的股票分类
        • 引入依赖
        • 加载数据
        • 确定分类个数
        • 查看分类结果
        • 总结
      • 闯关题
        • STEP1:请根据要求完成题目

KMeans

KMeans 是我们最常用的基于欧式距离的聚类算法,其认为两个目标的距离越近,相似度越大。

KMeans 算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为 K 个簇,其目的是让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。

基于 KMeans 的股票分类

以往的量化投资中对于股票的划分分类,通常取决于行业、市值、地域等等指标划分,而这些分类指标并不能很好的区分公司的好坏。而现在可以通过每日的交易行情实时划分分类,通过计算当日前一个月的分类从而确定该股票分类,更好的降低投资风险,提供风险对冲。该数据集有 2024-05-06 的全部上市公司股票交易行情信息,其中包含日期、开盘价、收盘价、最高价、最低价、成交量、成交额等特征信息,另外该模型使用的数据为真实数据,可以在实际操作中使用。

股市有风险,入市需谨慎!

引入依赖
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.metrics import accuracy_score, silhouette_score
加载数据
# 1. 加载数据

stock = pd.read_csv('./data/stocks-2.csv', index_col='Unnamed: 0')
stock.head()
symbolcodenametradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountticktimeperpbmktcapnmcturnoverratio
0sz0000011平安银行10.890.100.92710.8810.8910.7910.9611.1110.84178410057195381749315:00:004.8400.5082.113304e+072.113264e+070.91938
1sz0000022万 科A7.460.050.6757.457.467.417.637.887.44524493788399692170315:00:007.2430.3558.900309e+067.248834e+065.39773
2sz0000044国华网安10.440.232.25310.4310.4410.219.9910.469.97988544010205984215:00:00-8.8217.4781.382050e+051.318448e+057.82769
3sz0000066深振业A3.870.000.0003.873.883.873.964.013.86231871869134876515:00:00-6.5090.7525.224481e+055.224451e+051.71759
4sz0000077*ST全新4.09-0.15-3.5384.094.104.244.264.264.0424405501002858915:00:0039.40311.2121.416972e+051.263597e+050.78995
stock.info()
<class 'pandas.core.frame.DataFrame'>
Index: 5360 entries, 0 to 5359
Data columns (total 20 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   symbol         5360 non-null   object 
 1   code           5360 non-null   int64  
 2   name           5360 non-null   object 
 3   trade          5360 non-null   float64
 4   pricechange    5360 non-null   float64
 5   changepercent  5360 non-null   float64
 6   buy            5360 non-null   float64
 7   sell           5360 non-null   float64
 8   settlement     5360 non-null   float64
 9   open           5360 non-null   float64
 10  high           5360 non-null   float64
 11  low            5360 non-null   float64
 12  volume         5360 non-null   int64  
 13  amount         5360 non-null   int64  
 14  ticktime       5360 non-null   object 
 15  per            5360 non-null   float64
 16  pb             5360 non-null   float64
 17  mktcap         5360 non-null   float64
 18  nmc            5360 non-null   float64
 19  turnoverratio  5360 non-null   float64
dtypes: float64(14), int64(3), object(3)
memory usage: 879.4+ KB
# 2. 删除与分类数无关的特征列

new_stock = stock.drop(['symbol', 'code', 'name', 'ticktime'], axis=1)
new_stock.head()
tradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountperpbmktcapnmcturnoverratio
010.890.100.92710.8810.8910.7910.9611.1110.8417841005719538174934.8400.5082.113304e+072.113264e+070.91938
17.460.050.6757.457.467.417.637.887.4452449378839969217037.2430.3558.900309e+067.248834e+065.39773
210.440.232.25310.4310.4410.219.9910.469.979885440102059842-8.8217.4781.382050e+051.318448e+057.82769
33.870.000.0003.873.883.873.964.013.862318718691348765-6.5090.7525.224481e+055.224451e+051.71759
44.09-0.15-3.5384.094.104.244.264.264.0424405501002858939.40311.2121.416972e+051.263597e+050.78995
确定分类个数
# 3. 利用肘部法则确定分类数

inertia = []
silhouette_scores = []
i_range = range(2, 11)
for i in i_range:
    kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)
    inertia.append(kmeans.inertia_)
    silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))

inertia, silhouette_scores
([4.1450149552461185e+20,
  2.189263003520667e+20,
  1.6730094412041477e+20,
  9.618885942140525e+19,
  6.943786093529641e+19,
  5.561627387942571e+19,
  4.014992267655058e+19,
  3.2416675726264095e+19,
  2.4597061039181627e+19],
 [0.8944521948807374,
  0.8260147612056037,
  0.7907694574915884,
  0.7490320699906337,
  0.6649888612149094,
  0.6339363805356698,
  0.6338265053972817,
  0.6300107391392652,
  0.6195255140687659])

这段代码使用肘部法则和轮廓分数(silhouette score)来确定数据集的最佳分类数(簇数)。下面是对代码的详细解析:

导入必要的库

from sklearn.cluster import KMeans  
from sklearn.metrics import silhouette_score  

初始化变量

inertia = []  
silhouette_scores = []  
i_range = range(2, 11)  
  • inertia:用来存储不同簇数下的簇内误差平方和(SSE)。
  • silhouette_scores:用来存储不同簇数下的轮廓分数。
  • i_range:簇数的范围,从2到10(包括2和10)。

迭代不同的簇数

for i in i_range:  
    kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)  
    inertia.append(kmeans.inertia_)  
    silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))  
  • for i in i_range:遍历簇数范围,从2到10。
  • kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock):为每个簇数创建并训练一个KMeans模型。
    • n_clusters=i:设置当前簇数。
    • random_state=10:设置随机种子,以确保结果可复现。
    • fit(new_stock):对数据集 new_stock 进行聚类训练。
  • inertia.append(kmeans.inertia_):将当前簇数下的簇内误差平方和(SSE)添加到 inertia 列表中。
  • silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_)):计算当前簇数下的轮廓分数,并添加到 silhouette_scores 列表中。

输出结果

inertia, silhouette_scores  
  • 这将输出不同簇数下的簇内误差平方和(SSE)和轮廓分数。

肘部法则
肘部法则(Elbow Method)通过绘制簇数与SSE的关系图来帮助确定最佳簇数。最佳簇数通常是在SSE曲线开始明显变平的位置,即肘部位置。

轮廓分数
轮廓分数(Silhouette Score)用于评估聚类的质量,其值在-1到1之间。值越高表示聚类效果越好。通过比较不同簇数下的轮廓分数,可以选择分数最高的簇数作为最佳簇数。

总结
这段代码的目的是通过计算不同簇数下的簇内误差平方和(SSE)和轮廓分数,帮助选择数据集的最佳分类数。结合肘部法则和轮廓分数可以更全面地评估聚类效果,从而确定最合适的簇数。

# 4. 确定分类数
plt.figure(figsize=(15,5))

plt.subplot(1, 2, 1)
plt.plot(i_range, inertia, marker='o')

plt.subplot(1, 2, 2)
plt.plot(i_range, silhouette_scores, marker='o')

plt.tight_layout()
plt.show()

# 左图在 2 到 5 的时候,曲线下降速率明显下降。
# 右图在 2,3,4,5 时,轮廓系数比较高。
# 结合两图,选择 3 作为聚类数。


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

# 5. 分类

kmeans_final = KMeans(n_clusters=3, random_state=10).fit(new_stock)

labels = kmeans_final.labels_
new_stock['cluster'] = labels
new_stock.head()
tradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountperpbmktcapnmcturnoverratiocluster
010.890.100.92710.8810.8910.7910.9611.1110.8417841005719538174934.8400.5082.113304e+072.113264e+070.919382
17.460.050.6757.457.467.417.637.887.4452449378839969217037.2430.3558.900309e+067.248834e+065.397731
210.440.232.25310.4310.4410.219.9910.469.979885440102059842-8.8217.4781.382050e+051.318448e+057.827690
33.870.000.0003.873.883.873.964.013.862318718691348765-6.5090.7525.224481e+055.224451e+051.717590
44.09-0.15-3.5384.094.104.244.264.264.0424405501002858939.40311.2121.416972e+051.263597e+050.789950
查看分类结果
# 6. 查看分类情况

new_stock['cluster'].value_counts()
cluster
0    4998
2     332
1      30
Name: count, dtype: int64
总结

KMeans 在确定分类个数计算时,无法使用 object 类型的数据,应当提前删除或对特征进行 one-hot 处理。

闯关题

STEP1:请根据要求完成题目

Q1. KMeans 中某个参数的含义是正确的?
A. n_clusters 分类个数
B. inertia_ 轮廓系数
C. silhouette_scores 曲线下降速率

Q2. 修改KMeans的划分集群个数为 4个,那么 002829 股票的分类是哪个?
A. 0
B. 1
C. 2
D. 3

kmeans_final2 = KMeans(n_clusters=4, random_state=10).fit(new_stock)

labels = kmeans_final2.labels_
stock['cluster'] = labels
stock[stock['symbol'] == 'sz002829']['cluster']
1304    0
Name: cluster, dtype: int32

Q3. 前300个股票数据集划分集群的最优个数是多少?
A. 1
B. 3
C. 5
D. 10

new_stock = new_stock[0:300]

inertia = []
silhouette_scores = []
i_range = range(2, 11)
for i in i_range:
    # 计算分类并保存指标
    kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)
    inertia.append(kmeans.inertia_)
    silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))
inertia, silhouette_scores
([2.5308780913486823e+19,
  1.3473879858220839e+19,
  7.413489715471633e+18,
  6.109726555261718e+18,
  3.463054550988757e+18,
  2.604280833562603e+18,
  2.0732638975060705e+18,
  1.6982759851707302e+18,
  1.5100566906400458e+18],
 [0.8998406279029784,
  0.7527373456851054,
  0.692685627034619,
  0.6892926502877917,
  0.6522651603158817,
  0.6047949381607308,
  0.5696962854320331,
  0.5676513528559564,
  0.5655907482205398])
plt.figure(figsize=(15,5))

plt.subplot(1, 2, 1)
plt.plot(i_range, inertia, marker='o')

plt.subplot(1, 2, 2)
plt.plot(i_range, silhouette_scores, marker='o')

plt.tight_layout()
plt.show()


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#填入你的答案并运行,注意大小写
a1 = 'A'  # 如 a1= 'A'
a2 = 'A'  # 如 a2= 'A'
a3 = 'B'  # 如 a3= 'A'

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI+生命科学第二课:入门RNA和特征学习 【Datawhale AI夏令营】

教程链接&#xff1a;Task2&#xff1a;深入理解赛题&#xff0c;入门RNN和特征工程 打卡;https://linklearner.com/activity/12/4/4 在大佬讲解的基础上&#xff0c;带上一些我自己的理解 分析训练流程 从原始特征到输入模型 初始数据转换为tensor后&#xff0c;将x通过fo…

【C++】初识引用

目录 概念引用的五大特性引用在定义时必须初始化一个变量可以有多个引用一个引用可以继续有引用引用了一个实体就不能再引用另一个实体可以对任何类型做引用(包括指针) 引用使用的两种使用场景做参数交换两数单链表头结点的修改 做返回值优化传递返回值 常引用权限放大这时候进…

【前端学习笔记二】CSS基础二

一、颜色模型 1.颜色设置 颜色名称 https://www.w3schools.com/colors/colors_names.asp 这里是一些颜色的名称&#xff08;关键字&#xff09;&#xff0c;比如red、black、green等&#xff0c;可以直接指定名称来设置颜色。名称不区分大小写。 color:red;transparent tr…

OCC 网格化(三)-网格划分算法原理

目录 一、简介 二、基本原理 三、工作流程 四、BRepMesh模块与网格化流程 4.1 BRepMesh 主要组件 4.2 工作流程 4.3 网格生成示例 五、关键参数总结 一、简介 BRepMesh_IncrementalMesh 是一种基于迭代细分的网格划分算法,通过设置线性偏转和角偏转参数,可以生成高精…

利用Python爬虫实现数据收集与挖掘

Python爬虫通常使用requests、selenium等库来发送HTTP请求&#xff0c;获取网页内容&#xff0c;并使用BeautifulSoup、lxml等库来解析网页&#xff0c;提取所需的数据。 以下是一个简单的Python爬虫示例&#xff0c;用于从某个网页上抓取数据&#xff1a; import requests …

免费【2024】springboot 大学生志愿者管理系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

Executing an update/delete query,解决Hibernate更新数据库报错

问题描述 在使用Hibernate更新数据库中一条记录时,发送如下错误: javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractShare…

HCIA基础回顾

OSI参考模型 OSI&#xff08;Open System Interconnect&#xff09;参考模型&#xff0c;即为开放式系统互连参考模型。 应用层&#xff1a;人机交互&#xff0c;提供网络服务。 表示层&#xff1a;将逻辑语言转换为二进制语言&#xff0c;定义数据格式。 会话层&#xff1…

Linux 安装gradle

1.下载 下载地址&#xff1a; 下载地址&#xff1a; Gradle | ReleasesFind binaries and reference documentation for current and past versions of Gradle.https://gradle.org/releases/ 2. 解压 unzip gradle-7.6.2-all.zip 3.修改配置文件 #1.进入配置文件 vim /etc/…

【探索Linux】P.44(数据链路层 —— 以太网的帧格式 | MAC地址 | MTU | ARP协议)

阅读导航 引言一、认识以太网二、以太网的帧格式三、MAC地址四、MTU五、ARP协议温馨提示 引言 在深入探讨了网络层的IP协议之后&#xff0c;本文将带领读者进一步深入网络的底层——数据链路层。我们将详细解析以太网的帧格式&#xff0c;这是数据链路层传输数据的基本单元&am…

漏洞复现:Apache solr

目录 漏洞简述 环境搭建 漏洞复现 漏洞检测 漏洞修复 漏洞简述 Apache Solr是一个开源的搜索服务&#xff0c;使用Java编写、运行在Servlet容器的一个独立的全文搜索服务器&#xff0c;是Apache Lucene项目的开源企业搜索平台。 该漏洞是由于没有对输入的内容进行校验&…

深度体验:IntelliJ Idea自带AI Assistant,开启面向AI编程新纪元!

首发公众号&#xff1a; 赵侠客 引言 JetBrains AI Assistant 是 JetBrains 集成开发环境&#xff08;IDE&#xff09;中嵌入的一款智能开发助手工具&#xff0c;旨在通过人工智能技术来简化和提升软件开发过程&#xff0c;我深度体验了一下在IntelliJ IDEA 2024.2 Beta (Ulti…

JAVA项目基于SSM的学生成绩管理系统

目录 一、前言 二、技术介绍 三、项目实现流程 四、论文流程参考 五、核心代码截图 专注于大学生实战开发、讲解和毕业答疑等辅导&#xff0c;获取源码后台 一、前言 二、技术介绍 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端…

全球氢化双酚A (HBPA)市场规划预测:2030年市场规模将接近1330亿元,未来六年CAGR为2.7%

一、引言 随着全球化工行业的持续发展&#xff0c;氢化双酚A (HBPA)作为重要的化工原料&#xff0c;其市场重要性日益凸显。本文旨在探索HBPA行业的发展趋势、潜在商机及其未来展望。 二、市场趋势 全球HBPA市场的增长主要受全球化工行业增加、消费者对高性能化工产品要求提高…

vue3内置组件Suspense

给多个异步组件提供一个统一的状态管理 使用前&#xff0c;有两个loading... 使用后&#xff0c; 只有一个loading... Index.vue: <script setup lang"ts"> import { onMounted, ref, defineAsyncComponent } from vue import { useRouter } from vue-router…

CTF入门教程(非常详细)从零基础入门到竞赛,看这一篇就够了!

一、CTF简介 CTF&#xff08;Capture The Flag&#xff09;中文一般译作夺旗赛&#xff0c;在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。…

什么是网络安全?一文了解网络安全究竟有多重要!

随着互联网的普及和数字化进程的加速&#xff0c;网络安全已经成为我们生活中不可或缺的一部分。然而&#xff0c;很多人对于网络安全的概念仍然模糊不清。 ​ 那么&#xff0c;什么是网络安全&#xff1f;它究竟有多重要呢&#xff1f; 一、网络安全的定义 网络安全是指通过…

【Java】/* JDK 新增语法 */

目录 一、yield 关键字 二、var 关键字 三、空指针异常 四、密封类 五、接口中的私有方法 六、instanceof 一、yield 关键字 yield关键字&#xff0c;从Java13开始引⼊。yield关键字⽤于从case的代码块中返回值。 原本的switch语句写法&#xff1a; public static void …

Notion爆红背后,笔记成了AI创业新共识?

在数字化时代&#xff0c;笔记软件已成为我们记录、整理和创造知识的得力助手。本文将带您深入了解Notion以及其他五个AI笔记产品&#xff0c;它们如何通过AI重塑笔记体验&#xff0c;满足我们快速记录、捕捉灵感、智能整理、情感陪伴和自动撰写文章的五大核心需求。 ———— …

NC 在两个长度相等的排序数组中找到上中位数

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定两个递增…