SpringBoot整合MybatisPlus多数据源

article/2025/9/30 22:43:50

相信在很多使用MybatisPlus框架的小伙伴都会遇到多数据源的配置问题,并且官网也给出了推荐使用多数据源 (dynamic-datasource-spring-boot-starter) 组件来实现。由于最近项目也在使用这个组件来实现多数据源切换,因此想了解一下该组件是如何运行的,经过自己的调试,简单记录一下这个组件的实现,也以便日后组件如果出问题了或者某些地方需要开次开发时有个参考。

1 简单实现数据源切换

1.1 数据库demo

本例子使用的是同一个MYSQL服务,不同数据库来进行调试的,具体如图所示

建表语句如下:

CREATE TABLE `class_t` (`name` varchar(30) DEFAULT NULL,`number` varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;CREATE TABLE `user_t` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_name` varchar(30) DEFAULT NULL,`user_sex` varchar(30) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

1.2 SpringBoot demo

1.2.1 添加依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.4.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version><scope>provided</scope></dependency>

1.2.2 配置YML文件

spring:datasource:type: com.zaxxer.hikari.HikariDataSourcehikari:minimum-idle: 5maximum-pool-size: 15idle-timeout: 30000max-lifetime: 1800000connection-timeout: 30000pool-name: OasisHikariCPconnection-test-query: SELECT 1dynamic:primary: db1    #默认主数据源datasource:db1:                 #配置主数据源url: jdbc:mysql://127.0.0.1:3306/test?useSSL=true&requireSSL=false&serverTimezone=UTC&characterEncoding=UTF-8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverdb2:                #配置其他数据源url: jdbc:mysql://127.0.0.1:3306/test2?useSSL=true&requireSSL=false&serverTimezone=UTC&characterEncoding=UTF-8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver

1.2.3 实体层

UserEntity.java

/*** @description: DB1中的实体* @date: 2021/7/13 13:38 <br>* @author: wuKeFan <br>* @version: 1.0 <br>*/
@TableName("user_t")
public class UserEntity {private long id;private String userName;private String userSex;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserSex() {return userSex;}public void setUserSex(String userSex) {this.userSex = userSex;}
}

ClassEntity.java

/*** @description: DB2中的实体* @date: 2021/7/13 13:40 <br>* @author: wuKeFan <br>* @version: 1.0 <br>*/
@TableName("class_t")
public class ClassEntity {private String name;private String number;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}
}

1.2.4 mapper层

UserMapper.java(使用默认数据源)

/*** @description: UserMapper <br>* @date: 2021/7/13 13:41 <br>* @author: wuKeFan <br>* @version: 1.0 <br>*/
public interface UserMapper extends BaseMapper<UserEntity> {
}

ClassMapper.java(使用另外一个数据源)

/*** @description: ClassMapper <br>* @date: 2021/7/13 13:41 <br>* @author: wuKeFan <br>* @version: 1.0 <br>*/
@DS("db2")     //使用另外一个数据源
public interface ClassMapper extends BaseMapper<ClassEntity> {
}

1.2.5 单元测试

结果已经是可以完美运行多数据源。

2 源码解析

在我们搞项目中,不仅要学会用这些组件,更重要的是 要知其所以然,知道他是如何实现的,其实原理也就是网上能搜到的基于切面的代理处理方式,但是其中有些内容还是值得去学习。

2.1 自动装配

首先我们从 dynamic-datasource组件的自动装配开始

接下来让我们来看一下 这个自动装配类,所装配的Bean

@Slf4j
@Configuration
//启动SpringBoot 自动装配 DynamicDataSourceProperties外部化配置
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
//声明装配加载顺序,在 DataSourceAutoConfiguration 之前加载
@AutoConfigureBefore(value = DataSourceAutoConfiguration.class, name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure")
//当自动装配时,引入并自动装配下列三个自动装配类
@Import(value = {DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class, DynamicDataSourceHealthCheckConfiguration.class})
//自动装配加载条件 当 spring.datasource.dynamic = true时 进行自动装配的加载,默认缺省为true
@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
public class DynamicDataSourceAutoConfiguration implements InitializingBean {//注入外部化配置private final DynamicDataSourceProperties properties;private final List<DynamicDataSourcePropertiesCustomizer> dataSourcePropertiesCustomizers;//构造函数注入public DynamicDataSourceAutoConfiguration(DynamicDataSourceProperties properties,ObjectProvider<List<DynamicDataSourcePropertiesCustomizer>> dataSourcePropertiesCustomizers) {this.properties = properties;this.dataSourcePropertiesCustomizers = dataSourcePropertiesCustomizers.getIfAvailable();}//多数据源加载接口,默认的实现为从yml信息中加载所有数据源 @Beanpublic DynamicDataSourceProvider ymlDynamicDataSourceProvider() {return new YmlDynamicDataSourceProvider(properties.getDatasource());}//实现DataSource JAVA JNDI 后期Spring 容器中 所有的数据库连接都从该实现Bean 中获取@Bean@ConditionalOnMissingBeanpublic DataSource dataSource() {DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();dataSource.setPrimary(properties.getPrimary());dataSource.setStrict(properties.getStrict());dataSource.setStrategy(properties.getStrategy());dataSource.setP6spy(properties.getP6spy());dataSource.setSeata(properties.getSeata());return dataSource;}//设置动态数据源转换切换配置器@Role(value = BeanDefinition.ROLE_INFRASTRUCTURE)@Beanpublic Advisor dynamicDatasourceAnnotationAdvisor(DsProcessor dsProcessor) {DynamicDataSourceAnnotationInterceptor interceptor = new DynamicDataSourceAnnotationInterceptor(properties.isAllowedPublicOnly(), dsProcessor);DynamicDataSourceAnnotationAdvisor advisor = new DynamicDataSourceAnnotationAdvisor(interceptor);advisor.setOrder(properties.getOrder());return advisor;}//数据库事务的切面配置类@Role(value = BeanDefinition.ROLE_INFRASTRUCTURE)@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "seata", havingValue = "false", matchIfMissing = true)@Beanpublic Advisor dynamicTransactionAdvisor() {AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression("@annotation(com.baomidou.dynamic.datasource.annotation.DSTransactional)");return new DefaultPointcutAdvisor(pointcut, new DynamicLocalTransactionAdvisor());}//DynamicDataSourceAnnotationInterceptor 切面配置器中所需要的执行链,//主要用来确定使用哪个数据源@Bean@ConditionalOnMissingBeanpublic DsProcessor dsProcessor(BeanFactory beanFactory) {DsHeaderProcessor headerProcessor = new DsHeaderProcessor();DsSessionProcessor sessionProcessor = new DsSessionProcessor();DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));headerProcessor.setNextProcessor(sessionProcessor);sessionProcessor.setNextProcessor(spelExpressionProcessor);return headerProcessor;}//Bean注入后所执行的方法,本Demo中目前暂无使用@Overridepublic void afterPropertiesSet() {if (!CollectionUtils.isEmpty(dataSourcePropertiesCustomizers)) {for (DynamicDataSourcePropertiesCustomizer customizer : dataSourcePropertiesCustomizers) {customizer.customize(properties);}}}}

大体上的自动装配已经介绍完了,接下来我们逐个将重要的代码段或者类来进行解释

2.2 DynamicDataSourceCreatorAutoConfiguration类分析

这个类主要是进行数据源加载的 主要代码如下

@Slf4j
@Configuration
@AllArgsConstructor
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
public class DynamicDataSourceCreatorAutoConfiguration {//描述Bean的 注入顺序public static final int JNDI_ORDER = 1000;public static final int DRUID_ORDER = 2000;public static final int HIKARI_ORDER = 3000;public static final int BEECP_ORDER = 4000;public static final int DBCP2_ORDER = 5000;public static final int DEFAULT_ORDER = 6000;private final DynamicDataSourceProperties properties;//默认的数据源创造器@Primary@Bean@ConditionalOnMissingBeanpublic DefaultDataSourceCreator dataSourceCreator(List<DataSourceCreator> dataSourceCreators) {DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator();defaultDataSourceCreator.setProperties(properties);defaultDataSourceCreator.setCreators(dataSourceCreators);return defaultDataSourceCreator;}//省略部分代码/*** 存在Hikari数据源时, 加入创建器*/@ConditionalOnClass(HikariDataSource.class)@Configurationpublic class HikariDataSourceCreatorConfiguration {@Bean@Order(HIKARI_ORDER)@ConditionalOnMissingBeanpublic HikariDataSourceCreator hikariDataSourceCreator() {return new HikariDataSourceCreator(properties.getHikari());}}//省略部分代码}

当Spring 容器注入 DefaultDataSourceCreator 实例后 ,接下来就被 DynamicDataSourceProvider 这个类所使用。

2.3 DynamicDataSourceProvider 分析

@Slf4j
@AllArgsConstructor
public class YmlDynamicDataSourceProvider extends AbstractDataSourceProvider {/*** 所有数据源*/private final Map<String, DataSourceProperty> dataSourcePropertiesMap;//通过构造函数注入所有的 数据源 然后调用该父类方法创建数据源集合@Overridepublic Map<String, DataSource> loadDataSources() {return createDataSourceMap(dataSourcePropertiesMap);}
}
@Slf4j
public abstract class AbstractDataSourceProvider implements DynamicDataSourceProvider {//从Spring 容器中获取注入好的 DefaultDataSourceCreator @Autowiredprivate DefaultDataSourceCreator defaultDataSourceCreator;//创建数据源集合protected Map<String, DataSource> createDataSourceMap(Map<String, DataSourceProperty> dataSourcePropertiesMap) {Map<String, DataSource> dataSourceMap = new HashMap<>(dataSourcePropertiesMap.size() * 2);for (Map.Entry<String, DataSourceProperty> item : dataSourcePropertiesMap.entrySet()) {DataSourceProperty dataSourceProperty = item.getValue();String poolName = dataSourceProperty.getPoolName();if (poolName == null || "".equals(poolName)) {poolName = item.getKey();}dataSourceProperty.setPoolName(poolName);dataSourceMap.put(poolName, defaultDataSourceCreator.createDataSource(dataSourceProperty));}return dataSourceMap;}
}

2.4 DynamicDataSourceAnnotationAdvisor 分析

这个其实就是Spring AOP的切面配置器 主要代码如下

public class DynamicDataSourceAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {//切面增强方法private final Advice advice;private final Pointcut pointcut;//构造方法注入public DynamicDataSourceAnnotationAdvisor(@NonNull DynamicDataSourceAnnotationInterceptor dynamicDataSourceAnnotationInterceptor) {this.advice = dynamicDataSourceAnnotationInterceptor;this.pointcut = buildPointcut();}@Overridepublic Pointcut getPointcut() {return this.pointcut;}@Overridepublic Advice getAdvice() {return this.advice;}//省略部分代码//当有类或者方法中有 DS.class 注解时 进行 切面增强private Pointcut buildPointcut() {Pointcut cpc = new AnnotationMatchingPointcut(DS.class, true);Pointcut mpc = new AnnotationMethodPoint(DS.class);return new ComposablePointcut(cpc).union(mpc);}//省略部分代码 
}

2.5 DynamicDataSourceAnnotationInterceptor 分析

该类为切面增强,即当上面的DynamicDataSourceAnnotationAdvisor 拦截到类或者方法中有 DS.class 注解时 ,调用该增强类进行处理

public class DynamicDataSourceAnnotationInterceptor implements MethodInterceptor {/*** The identification of SPEL.*/private static final String DYNAMIC_PREFIX = "#";private final DataSourceClassResolver dataSourceClassResolver;private final DsProcessor dsProcessor;public DynamicDataSourceAnnotationInterceptor(Boolean allowedPublicOnly, DsProcessor dsProcessor) {dataSourceClassResolver = new DataSourceClassResolver(allowedPublicOnly);this.dsProcessor = dsProcessor;}//AOP拦截后进行 切面增强方法@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {//选择数据源String dsKey = determineDatasourceKey(invocation);//使用基于ThreadLocal的实现切换数据源DynamicDataSourceContextHolder.push(dsKey);try {return invocation.proceed();} finally {DynamicDataSourceContextHolder.poll();}}//通过调用 DsProcessor 来链式调用进行 数据源的确认private String determineDatasourceKey(MethodInvocation invocation) {String key = dataSourceClassResolver.findDSKey(invocation.getMethod(), invocation.getThis());return (!key.isEmpty() && key.startsWith(DYNAMIC_PREFIX)) ? dsProcessor.determineDatasource(invocation, key) : key;}
}

2.6 DefaultPointcutAdvisor 分析

该切面增强为事务增强,设置此增强类后,不能与Spring 源事务或者 @Transactional 注解共用。

@Slf4j
public class DynamicLocalTransactionAdvisor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {if (!StringUtils.isEmpty(TransactionContext.getXID())) {return methodInvocation.proceed();}boolean state = true;Object o;String xid = UUID.randomUUID().toString();TransactionContext.bind(xid);try {o = methodInvocation.proceed();} catch (Exception e) {state = false;throw e;} finally {ConnectionFactory.notify(state);TransactionContext.remove();}return o;}
}

2.7 DynamicDataSourceContextHolder 核心切换类

public final class DynamicDataSourceContextHolder {/*** 为什么要用链表存储(准确的是栈)* <pre>* 为了支持嵌套切换,如ABC三个service都是不同的数据源* 其中A的某个业务要调B的方法,B的方法需要调用C的方法。一级一级调用切换,形成了链。* 传统的只设置当前线程的方式不能满足此业务需求,必须使用栈,后进先出。* </pre>*/private static final ThreadLocal<Deque<String>> LOOKUP_KEY_HOLDER = new NamedThreadLocal<Deque<String>>("dynamic-datasource") {@Overrideprotected Deque<String> initialValue() {return new ArrayDeque<>();}};private DynamicDataSourceContextHolder() {}/*** 获得当前线程数据源** @return 数据源名称*/public static String peek() {return LOOKUP_KEY_HOLDER.get().peek();}/*** 设置当前线程数据源* <p>* 如非必要不要手动调用,调用后确保最终清除* </p>** @param ds 数据源名称*/public static String push(String ds) {String dataSourceStr = StringUtils.isEmpty(ds) ? "" : ds;LOOKUP_KEY_HOLDER.get().push(dataSourceStr);return dataSourceStr;}/*** 清空当前线程数据源* <p>* 如果当前线程是连续切换数据源 只会移除掉当前线程的数据源名称* </p>*/public static void poll() {Deque<String> deque = LOOKUP_KEY_HOLDER.get();deque.poll();if (deque.isEmpty()) {LOOKUP_KEY_HOLDER.remove();}}/*** 强制清空本地线程* <p>* 防止内存泄漏,如手动调用了push可调用此方法确保清除* </p>*/public static void clear() {LOOKUP_KEY_HOLDER.remove();}
}

大致核心的代码已经介绍完了,接下来我们逐步debugger,摸清其执行流程。

2.8 数据源切换执行流程

现在当我们执行上面的SpringBoot demo中的 调用注解 @DS("db2") 的 Mapper 查询数据库时,他的顺序如下(只给出涉及到该组件的相关类)

  1. ClassMapper#selectList() : 执行Mybatis查询操作

  1. DynamicDataSourceAnnotationInterceptor#invoke() : Spring AOP 拦截到带有 @DS("db2") 并执行代理增强操作

  1. DataSourceClassResolver#findDSKey() : 查找有注解@DS() 的 类或方法,获取对应的数据源Key 值 也就是 db2。

  1. DynamicDataSourceContextHolder#push() : 设置当前线程数据源

  1. DynamicRoutingDataSource#getConnection(): 调用父类方法获取数据库连接 这里两种处理方式 如下所示

    public Connection getConnection() throws SQLException {String xid = TransactionContext.getXID();//无事务时 即当前操作为 查询if (StringUtils.isEmpty(xid)) {return determineDataSource().getConnection();} else {//有事物时 ,先从 之前DynamicDataSourceContextHolder 中获取数据源 先进先出原则String ds = DynamicDataSourceContextHolder.peek();ds = StringUtils.isEmpty(ds) ? "default" : ds;ConnectionProxy connection = ConnectionFactory.getConnection(ds);//创建数据源return connection == null ? getConnectionProxy(ds, determineDataSource().getConnection()) : connection;}}
  1. DynamicRoutingDataSource#getDataSource 设置数据源

 public DataSource getDataSource(String ds) {//如果当前无 数据源声明 则使用默认数据源if (StringUtils.isEmpty(ds)) {return determinePrimaryDataSource();} else if (!groupDataSources.isEmpty() && groupDataSources.containsKey(ds)) {log.debug("dynamic-datasource switch to the datasource named [{}]", ds);return groupDataSources.get(ds).determineDataSource();} else if (dataSourceMap.containsKey(ds)) {//如果当前存在数据源则取出该数据源返回log.debug("dynamic-datasource switch to the datasource named [{}]", ds);return dataSourceMap.get(ds);}if (strict) {throw new CannotFindDataSourceException("dynamic-datasource could not find a datasource named" + ds);}return determinePrimaryDataSource();}
  1. 执行剩余的数据库操作至结束。

3 小结

大体上写的略微混乱,但是只要我们知道其自动装配时 ,实例化了哪些Bean,并且知道这些Bean 是干什么的 ,合适调用的,根据执行流程逐步Debugger调试,就可以明白dynamic-datasource组件是如何进行数据源切换的,在流程中我认为比较经典也是比较核心的地方已经标注出源码。我们可以借鉴 DynamicDataSourceContextHolder 这个公共类的思想,扩展和优化我们现有的项目中某些跨资源调用的问题。


http://chatgpt.dhexx.cn/article/T3WeTDMD.shtml

相关文章

Springboot/MybatisPlus动态切换数据源

1.1 简述 最近项目中有动态切换数据源需求&#xff0c;主要是要动态切换数据源进行数据的获取&#xff0c;现将项目中实现思路及代码提供出来&#xff0c;供大家参考。当然切换数据源还有其他的方式比如使用切面的方式&#xff0c;其实大体思路是一样的。 1.2 设计思路与代码…

Spring数据源配置

目录 Spring相关的API ApplicationContext的继承体系 ApplicationContext的实现类 getBean()方法使用 Spring配置数据源(连接池) 数据源的开发步骤 加载配置文件方式创建 将DateSource的创建权交给Spring容器去完成 抽取jdbc配置文件 Spring相关的API ApplicationContex…

Java 动态数据源配置

目录 一、动态数据源介绍 1. AbstractRoutingDataSource 2. 实现逻辑 二、源代码 1. 修改配置文件类 2. 创建数据源枚举 3. 数据源切换处理 4. 继承AbstractRoutingDataSource 5. 注入数据源 6. 自定义多数据源切换注解 7. AOP拦截类的实现 8. 使用切换数据源注解 …

SpringBoot实现多数据源配置

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot实现多数据源配置 ⏱️ 创作时间&#xff1a; 2022年06月13…

SAP 数据源

SAP BW或者BI作为数据仓库会抽取SAP系统数据和非SAP系统数据&#xff0c;源系统的主要类型有以下几种&#xff1a; 1、SAP系统&#xff1a;R/3、S/4、CRM、等&#xff0c; 2、文本文件&#xff1a;将数据库转化为XML或者CSV文件放在FTP上&#xff0c;然后去读取数据&#xf…

Python使用tsne进行高维数据可视化实战:二维可视化、三维可视化

Python使用tsne进行高维数据可视化实战:二维可视化、三维可视化 # 绘制二维可视化图像并添加标签字符函数 def plot_embedding(data, label, title):x_min, x_max = np.min(data, 0), np.max(data, 0)data = (data - x_min) / (x_max - x_min)fig = plt.figure()ax = plt.s…

降维算法PCA的应用----高维数据的可视化

文章目录 序言废话不多说看代码导入相关模块数据提取降维降维后数据信息展示新的特征矩阵 可视化关于X_dim2[yi, 0]的解释 总结 序言 当我们拿到一堆数据的时候&#xff0c;几乎不可能通过我们的肉眼分辨出数据的分布情况&#xff0c;这时候就想要通过图展示数据的分布&#x…

学习笔记 | 用距离之距离(DoD)变换改进高维数据可视化

文章目录 一、论文关键信息二、主要内容三、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、论文关键信息 论文标题:Improved visualization of high-dimensional data using the distance-of-distance transformation 论文地址:https://doi.org/10.1371/journal.…

数据可视化的历史

数据可视化的历史 可视化发展史与测量、绘画、人类现代文明的启蒙和科技的发展一脉相承。在地图、科学与工程制图、统计图表中&#xff0c;可视化理念与技术已经应用和发展了数百年。 17世纪之前&#xff1a;图表萌芽 16世纪时&#xff0c;人类已经掌握了精确的观测技术和设…

【数据可视化】复杂高维多元数据的可视化

1 高维多元数据 每个数据对象有两个或两个以上独立或者相关属性的数据。高维指数据具有多个独立属性&#xff0c;多元指数据具有多个相关属性。由于研究者在很多情况下不确定数据的属性是否独立&#xff0c;因此通常简单地称之为多元数据。例如&#xff1a;电脑配置。 高维多元…

平行坐标图:高维数据可视化必备图形

关于数据可视化&#xff0c;我们之前分享过很多基础图表和进阶图表&#xff0c;都是一些我们常见的图表&#xff0c;如折线图&#xff0c;柱状图&#xff0c;饼图等等。今天分享一个大家应该见过但是不那么熟悉的图表-平行坐标图。 平行坐标图的定义 平行坐标图可以说是折线图…

Umap高维数据可视化与降维

Umap解决高维数据可视化的问题&#xff0c;以及高效降维。 Umap地址:https://github.com/lmcinnes/umap 文档地址&#xff1a;UMAP: Uniform Manifold Approximation and Projection for Dimension Reduction — umap 0.5 documentation 1.pip通过清华镜像安装方式&#xff…

【数据艺术科技1】基于pyhon的高维数据可视化。(1、2维)

引言 描述性分析是与数据科学项目甚至特定研究相关的任何分析生命周期的核心组成部分之一。数据聚合、汇总和可视化是支持这一数据分析领域的一些主要支柱。从传统商业智能时代到如今的人工智能时代&#xff0c;数据可视化一直是一种强大的工具&#xff0c;并因其在提取正确信…

python高维数据可视化_【机器学习】(十六)主成分分析PCA:高维数据可视化、特征提取...

主成分分析(PCA)是一种旋转数据集的方法,旋转后的特征在统计上不相关。 用PCA做数据变换 首先,算法在原始数据点集中,找到方差最大的方向(包含最多信息),标记为‘成分1’。->找到与“成分1”正交(成直角)且包含最多信息的方向,标记为“成分2”。利用这一过程找到的方向…

TSNE 高维数据可视化

TSNE 高维数据可视化 标签&#xff1a; python 机器学习 神经网络 在神经网络中&#xff0c;我们最后一层一般都是高纬度的数据&#xff0c;但是有时候我们可能想看一下这些高纬度数据的分布情况&#xff0c;这个时候就需要用TSNE&#xff0c;其实TSNE本质上就是先利用PCA降维…

PCA实现高维数据可视化

1 简介 PCA&#xff08;Principal Component Analysis&#xff09;即主成分分析是最常见的降维方法&#xff0c; 它是一种统计方法。用于高维数据集的探索与可视化&#xff0c;还可用于数据的压缩和预处理。可通过正交变换把具有相关性的高维变量转换为线性无关的低维变量&…

高维数据可视化之t-SNE算法

https://blog.csdn.net/hustqb/article/details/78144384 t-sne数学原理https://zhuanlan.zhihu.com/p/57937096 什么是t-SNE&#xff1f; t-SNE的主要用途是可视化和探索高维数据。 它由Laurens van der Maatens和Geoffrey Hinton在JMLR第九卷(2008年)中开发并出版。 t-SNE…

Python 数据可视化学习笔记 之高维数据可视化及其方法

一、高维数据 高维数据泛指高维&#xff08;multidimensional&#xff09; 和多变量&#xff08;multivariate&#xff09;数据 -- 高维是指数据具有多个独立属性 -- 多变量是指数据具有多个相关属性 高维数据可视化的挑战&#xff1a; 如何呈现单个数据点的各属性的数据值分…

高维数据可视化示例

高维数据可视化示例 文中代码均在Jupyter Notebook中运行 文中所需两个数据文件在下面给出。 文中数据集下载1 文中数据集下载2 目录 高维数据可视化示例单变量分析多变量分析可视化二维数据可视化三维数据可视化四维数据可视化 5 维数据可视化 6 维数据&#xff08;6-D&#…

python科学计算库安装

python科学计算相关的库包括numpy&#xff0c;scipy&#xff0c;matplotlib等&#xff0c;但是自己安装比较不容易&#xff0c;倒不是安装过程有多难&#xff0c;而是会出现各种各样的问题&#xff0c;现在做一记录 安装顺序numpy -> scipy - > matplotlib&#xff0c; …