案例沪深300指数成分股收益率的主成分分析案例背景本小节的内容讲解如何使用Python对数据进行PCA主成分分析使用到的数据有2022年4月到9月的沪深300成分股数据和沪深300指数数据沪深300成分股数据data.csv沪深300指数数据HS300.csv内容主要包括两个部分对沪深300成分股数据进行PCA分析得到各个成分股的线性组合系数可视化对比沪深300成分股经过线性组合系数加权求和后的整体行情趋势与沪深300指数数据读取与划分首先导入pandas库读取数据# 导入 pandas 库importpandasaspd# 读取股票数据stock_datapd.read_csv(data.csv)stock_dataTradedate12636669100157166301...68803668806568811168812668816968836368839668856168859968898102022-04-1215.9220.1722.2411.127.364.846.984.4713.61...87.8399.78179.3022.12528.10105.8048.6053.6349.9043.8912022-04-1315.8020.5022.0010.747.234.776.794.4213.30...86.0495.75177.7022.30511.02102.5046.8051.8048.7443.5122022-04-1416.0421.0022.3310.887.554.806.864.4514.07...89.0095.33184.1022.80533.00114.6848.2052.6848.3743.6732022-04-1516.4221.3022.6910.497.644.766.684.3913.76...87.4993.27181.3622.50516.61116.0048.6051.2148.2043.2542022-04-1815.9020.5323.1710.447.134.766.564.3313.66...94.6692.60185.4522.78531.17119.4349.7052.5553.9043.69..................................................................952022-08-2912.4215.5724.089.175.334.245.834.1421.01...70.6372.57163.0020.00316.00141.9752.1849.2473.6040.08962022-08-3012.4815.8924.509.235.404.205.844.1520.23...69.6470.03173.9620.17313.82145.4352.4049.2473.4440.10972022-08-3112.7516.6324.509.085.354.155.774.1819.26...68.2669.46180.1220.60320.03143.0552.4049.7771.4940.21982022-09-0112.6116.8424.039.135.324.085.824.2018.81...67.1369.40190.6120.05325.81139.9651.1649.7073.1239.95992022-09-0212.5116.8024.279.265.164.105.824.1619.16...67.2069.45188.3520.16313.36141.4851.6450.4672.8040.40100 rows × 301 columns接下来对数据进行清洗处理数据中的异常值。对于整列缺失的数据也就是全部数据丢失的股票整列删除对于其他列中缺失的个别数据用前一个非缺失的数据来填充。stock_datastock_data.dropna(axis1,howall)stock_data.fillna(methodpad,inplaceTrue)主成分分析PCAimportnumpyasnp前面所读取的数据是一段时间内沪深300成分股的收盘价我们通过某天和前一天的收盘价可以计算当天的对数收益率。将当天的收盘价记作pricetprice_{t}pricet前一天的收盘价记作pricet−1price_{t-1}pricet−1则对数收益率的计算公式为ln(pricetpricet−1)ln(pricet)−ln(pricet−1)ln(\frac{price_{t}}{price_{t-1}}) ln(price_{t}) - ln(price_{t-1})ln(pricet−1pricet)ln(pricet)−ln(pricet−1)stock_returnsstock_data.copy()stock_returns.iloc[:,1:]stock_returns.iloc[:,1:].apply(np.log).diff(1)导入sklearn库进行PCA分析fromsklearn.decompositionimportPCA# 数据的第一行是第一天的数据收益率无法计算为空值应该去掉stock_returnsstock_returns[1:]# 数据的第一列是日期进行PCA只需保留除了日期列之外的股票数据pcaPCA(1).fit(stock_returns.iloc[:,1:])数据可视化导入matplotlib库将PCA的结果可视化importmatplotlib.pyplotasplty_indexstock_data.columns[1:]以股票代码为横坐标各个股票的线性组合系数为纵坐标可以将各个股票所占的比重可视化数值越高的股票在沪深300成分股中的重要性越高pc1pd.Series(indexy_index,datapca.components_[0])pc1.plot(figsize(10,6),xticks[],gridTrue)plt.tight_layout()PCA主成分分析获得了沪深300成分股票各自的线性组合系数每个系数绝对值除以所有系数绝对值之和计算出各个股票在沪深300全体股票中的权重比例。对各个股票的收益率按照该权重比例进行加权求和结果可以反映沪深300全体股票的行情变化。之后按照日期先后顺序进行可视化。# 根据主成分分析结果计算各个股票的权重比例weightsabs(pc1)/sum(abs(pc1))# 对全体股票收益率进行加权求和myrs(weights*stock_returns[y_index]).sum(1)# 从求和结果计算收益情况并可视化myrs.cumsum().apply(np.exp).plot(figsize(10,6))结果验证沪深300指数是由中国证券指数公司基于上海证券交易所上市公司和深圳证券交易所上市公司股票数据编制的指数反映股票市场整体走势。其数值来自于证券指数公司的专家根据各只股票的重要性制定每只股票的权重参数并根据参数对成分股票的数据进行加权求和。影响力越大、越重要的股票对沪深300指数所起的作用越大。为了说明沪深300成分股按照线性组合系数加权求和后的整体行情趋势与沪深300指数的关系将沪深300指数收盘价可视化# 读取沪深300指数数据HS300pd.read_csv(HS300.csv)# 收盘价数据作为纵坐标y_dataHS300[close]# 可视化沪深300指数收盘价HS300_closepd.Series(indexrange(100),dataHS300[close])HS300_close.plot(figsize(10,6),xticks[])对比沪深300成分股经过线性组合系数加权求和后的整体行情趋势和沪深300指数的数据图像可以发现虽然数值单位不同但曲线各个部位的变化趋势、极点是相同的。这是因为经过PCA分析后得到的线性组合系数能够从数值上反映各个成分对总体指标所产生的影响因此根据线性组合系数对成分股进行加权求和能够表达沪深300指数中的大部分信息。但由于沪深300指数的实际计算过程还需要考虑其他因素因此两者并不完全相同而只是有着大致相近的变化趋势。
第十一章 降维 案例:沪深300指数成分股收益率的主成分分析
发布时间:2026/6/3 1:17:17
案例沪深300指数成分股收益率的主成分分析案例背景本小节的内容讲解如何使用Python对数据进行PCA主成分分析使用到的数据有2022年4月到9月的沪深300成分股数据和沪深300指数数据沪深300成分股数据data.csv沪深300指数数据HS300.csv内容主要包括两个部分对沪深300成分股数据进行PCA分析得到各个成分股的线性组合系数可视化对比沪深300成分股经过线性组合系数加权求和后的整体行情趋势与沪深300指数数据读取与划分首先导入pandas库读取数据# 导入 pandas 库importpandasaspd# 读取股票数据stock_datapd.read_csv(data.csv)stock_dataTradedate12636669100157166301...68803668806568811168812668816968836368839668856168859968898102022-04-1215.9220.1722.2411.127.364.846.984.4713.61...87.8399.78179.3022.12528.10105.8048.6053.6349.9043.8912022-04-1315.8020.5022.0010.747.234.776.794.4213.30...86.0495.75177.7022.30511.02102.5046.8051.8048.7443.5122022-04-1416.0421.0022.3310.887.554.806.864.4514.07...89.0095.33184.1022.80533.00114.6848.2052.6848.3743.6732022-04-1516.4221.3022.6910.497.644.766.684.3913.76...87.4993.27181.3622.50516.61116.0048.6051.2148.2043.2542022-04-1815.9020.5323.1710.447.134.766.564.3313.66...94.6692.60185.4522.78531.17119.4349.7052.5553.9043.69..................................................................952022-08-2912.4215.5724.089.175.334.245.834.1421.01...70.6372.57163.0020.00316.00141.9752.1849.2473.6040.08962022-08-3012.4815.8924.509.235.404.205.844.1520.23...69.6470.03173.9620.17313.82145.4352.4049.2473.4440.10972022-08-3112.7516.6324.509.085.354.155.774.1819.26...68.2669.46180.1220.60320.03143.0552.4049.7771.4940.21982022-09-0112.6116.8424.039.135.324.085.824.2018.81...67.1369.40190.6120.05325.81139.9651.1649.7073.1239.95992022-09-0212.5116.8024.279.265.164.105.824.1619.16...67.2069.45188.3520.16313.36141.4851.6450.4672.8040.40100 rows × 301 columns接下来对数据进行清洗处理数据中的异常值。对于整列缺失的数据也就是全部数据丢失的股票整列删除对于其他列中缺失的个别数据用前一个非缺失的数据来填充。stock_datastock_data.dropna(axis1,howall)stock_data.fillna(methodpad,inplaceTrue)主成分分析PCAimportnumpyasnp前面所读取的数据是一段时间内沪深300成分股的收盘价我们通过某天和前一天的收盘价可以计算当天的对数收益率。将当天的收盘价记作pricetprice_{t}pricet前一天的收盘价记作pricet−1price_{t-1}pricet−1则对数收益率的计算公式为ln(pricetpricet−1)ln(pricet)−ln(pricet−1)ln(\frac{price_{t}}{price_{t-1}}) ln(price_{t}) - ln(price_{t-1})ln(pricet−1pricet)ln(pricet)−ln(pricet−1)stock_returnsstock_data.copy()stock_returns.iloc[:,1:]stock_returns.iloc[:,1:].apply(np.log).diff(1)导入sklearn库进行PCA分析fromsklearn.decompositionimportPCA# 数据的第一行是第一天的数据收益率无法计算为空值应该去掉stock_returnsstock_returns[1:]# 数据的第一列是日期进行PCA只需保留除了日期列之外的股票数据pcaPCA(1).fit(stock_returns.iloc[:,1:])数据可视化导入matplotlib库将PCA的结果可视化importmatplotlib.pyplotasplty_indexstock_data.columns[1:]以股票代码为横坐标各个股票的线性组合系数为纵坐标可以将各个股票所占的比重可视化数值越高的股票在沪深300成分股中的重要性越高pc1pd.Series(indexy_index,datapca.components_[0])pc1.plot(figsize(10,6),xticks[],gridTrue)plt.tight_layout()PCA主成分分析获得了沪深300成分股票各自的线性组合系数每个系数绝对值除以所有系数绝对值之和计算出各个股票在沪深300全体股票中的权重比例。对各个股票的收益率按照该权重比例进行加权求和结果可以反映沪深300全体股票的行情变化。之后按照日期先后顺序进行可视化。# 根据主成分分析结果计算各个股票的权重比例weightsabs(pc1)/sum(abs(pc1))# 对全体股票收益率进行加权求和myrs(weights*stock_returns[y_index]).sum(1)# 从求和结果计算收益情况并可视化myrs.cumsum().apply(np.exp).plot(figsize(10,6))结果验证沪深300指数是由中国证券指数公司基于上海证券交易所上市公司和深圳证券交易所上市公司股票数据编制的指数反映股票市场整体走势。其数值来自于证券指数公司的专家根据各只股票的重要性制定每只股票的权重参数并根据参数对成分股票的数据进行加权求和。影响力越大、越重要的股票对沪深300指数所起的作用越大。为了说明沪深300成分股按照线性组合系数加权求和后的整体行情趋势与沪深300指数的关系将沪深300指数收盘价可视化# 读取沪深300指数数据HS300pd.read_csv(HS300.csv)# 收盘价数据作为纵坐标y_dataHS300[close]# 可视化沪深300指数收盘价HS300_closepd.Series(indexrange(100),dataHS300[close])HS300_close.plot(figsize(10,6),xticks[])对比沪深300成分股经过线性组合系数加权求和后的整体行情趋势和沪深300指数的数据图像可以发现虽然数值单位不同但曲线各个部位的变化趋势、极点是相同的。这是因为经过PCA分析后得到的线性组合系数能够从数值上反映各个成分对总体指标所产生的影响因此根据线性组合系数对成分股进行加权求和能够表达沪深300指数中的大部分信息。但由于沪深300指数的实际计算过程还需要考虑其他因素因此两者并不完全相同而只是有着大致相近的变化趋势。