技术问询:如何通过调整权重w优化皮尔逊相关系数的R平方值?
Alright, let's tackle this problem step by step—you want to adjust weights w to optimize both the R-squared value (from Pearson correlation) and the Pearson correlation coefficient itself, using your existing code as a starting point. Let's break this down clearly.
1. First, Clarify Your Current Setup
From your code snippet, you're calculating weighted sums of your raw x1_raw, x2_raw, x3_raw arrays using weights w, then creating a new x array to correlate with y. Our goal is to find the w values that either maximize the R-squared (which is just the square of the Pearson correlation coefficient) or maximize/minimize the Pearson coefficient directly.
2. Mathematical Background
To formalize this:
- Let
X_rawbe a matrix where each row is one of your raw x arrays (x1_raw,x2_raw,x3_raw). - The weighted
xvector is calculated asx = X_raw @ w(matrix multiplication, equivalent to your currentsum(w * xj_raw)for each x element). - Optimizing R-squared: We want to maximize
(r)^2, whereris the Pearson correlation betweenxandy. Since optimization tools typically minimize functions, we'll instead minimize-r². - Optimizing Pearson Correlation: We want to maximize (or minimize, if negative correlation is desired)
r—so we'll minimize-r(for maximization) orr(for minimization).
We'll also add practical constraints (like weights summing to 1, or non-negative weights) to avoid meaningless extreme values for w.
3. Full Implementation Code
Let's build out your code with optimization using scipy.optimize.minimize:
import numpy as np from scipy import stats from scipy.optimize import minimize # Your raw data x1_raw = np.array([277, 115, 196]) x2_raw = np.array([263, 118, 191]) x3_raw = np.array([270, 114, 191]) y = np.array([71.86, 71.14, 70.76]) # Organize raw x data into a matrix (rows = x1_raw, x2_raw, x3_raw) X_raw = np.vstack([x1_raw, x2_raw, x3_raw]) # -------------------------- # Optimize for Maximum R-squared # -------------------------- def objective_r_squared(w): # Calculate weighted x vector x = X_raw @ w # Get Pearson correlation coefficient r, _ = stats.pearsonr(x, y) # Return negative R-squared to convert maximization to minimization return -(r ** 2) # Constraints: sum of weights = 1 (adjust if you need different constraints) constraints = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}] # Bounds: non-negative weights (remove if negative weights are allowed) bounds = [(0, None) for _ in range(len(x1_raw))] # Initial guess for weights (uniform distribution) initial_weights = np.array([1/3, 1/3, 1/3]) # Run optimization result_r2 = minimize(objective_r_squared, initial_weights, method='SLSQP', bounds=bounds, constraints=constraints) print("=== Optimized for R-squared ===") print(f"Optimal weights: {np.round(result_r2.x, 4)}") print(f"Maximum R-squared value: {np.round(-result_r2.fun, 4)}") # -------------------------- # Optimize for Maximum Pearson Correlation # -------------------------- def objective_pearson(w): x = X_raw @ w r, _ = stats.pearsonr(x, y) # Return negative r to maximize the correlation (use 'return r' to minimize it) return -r result_pearson = minimize(objective_pearson, initial_weights, method='SLSQP', bounds=bounds, constraints=constraints) print("\n=== Optimized for Pearson Correlation ===") print(f"Optimal weights: {np.round(result_pearson.x, 4)}") print(f"Maximum Pearson correlation: {np.round(-result_pearson.fun, 4)}")
4. Key Things to Keep in Mind
- Constraints Matter: Without constraints, the optimizer might return extreme weights (like very large positive/negative values) that inflate the correlation but are useless in practice. The
sum(w) = 1constraint is standard for weighted averages, and non-negative bounds make sense if weights represent contributions (e.g., proportions). - Optimization Method: We used
SLSQPbecause it handles both bounds and equality constraints well. For unconstrained problems, you could useBFGSinstead. - Local Optima: The objective function might not be convex, so try a few different initial weight guesses to ensure you're getting a good solution.
内容的提问来源于stack exchange,提问作者lanselibai

