gpt4 book ai didi

c - 奇数 PIL 逊相关系数结果

转载 作者:行者123 更新时间:2023-12-02 07:53:43 27 4
gpt4 key购买 nike

我的 C 编程课上有一个作业要编写一个程序来获取 2 组实数的相关系数。我已经得到了方程式,它引用了维基百科,所以我仔细检查了那里的方程式。这是方程式的链接,从我的研究来看,它似乎是非常标准的:

alt text

我已经编写了程序,但是当我运行它时,我得到的结果数字大于 1,我知道这是不正确的。我多次查看了我的代码,但没有发现任何不合适的地方,所以我尝试在最后除以 n 而不是 n-1,这给了我预期的 -1 到 1 范围内的值,所以我测试了它与我在网上找到的数据值以及相关系数计算器 (http://easycalculation.com/statistics/correlation.php) 进行了比较,现在我输入的所有数字都得到了正确的结果。我不明白这是为什么,所以我想我可以在这里得到一些帮助。这是我的程序代码,如果还有其他明显的问题表明我在这里做错了,我很想听听一些建议,但主要是我想弄清楚为什么我会得到正确的结果是错误的等式。

然后它将读取两个数组(x 和 y)的值,然后计算两组数之间的相关系数。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void) {
int n; /* value to determine array length */
/* declare variables to hold results for each equation for x and y
initialize all to zero to prepare for summation */
float r = 0.0, xbar = 0.0, ybar = 0.0, sx = 0.0, sy = 0.0;

/*get number n input from user */
printf("Please enter a number n: ");
scanf("%d", &n);

if( n < 1) {
printf("n must be a positive number.\nPlease enter a new value: ");
scanf("%d", &n);
if( n < 1) {
printf("Invalid input, exiting...\n");
return 0;
}
}

/*initialize arrays x and y with length of n */
float x[n], y[n];
/*use for loop to read in values of x*/
int i;
for(i = 0; i < n; ++i) {
printf("Please enter a number for x: ");
scanf("%f", &x[i]);
}
/*use for loop to read in values of y*/
for(i = 0; i < n; ++i) {
printf("Please enter a number for y: ");
scanf("%f", &y[i]);
}

/*compute xbar */
for(i = 0; i < n; ++i) {
xbar += x[i];
}
xbar /= n;
/*compute ybar*/
for(i = 0; i < n; ++i) {
ybar += y[i];
}
ybar /= n;

/* compute standard deviation of x*/
for(i = 0; i < n; ++i) {
sx += (x[i] - xbar) * (x[i] - xbar);
}
sx = sqrt((sx / n));
/* compute standard deviation of y */
for(i = 0; i < n; ++i) {
sy += (y[i] - ybar) * (y[i] - ybar);
}
sy = sqrt((sy / n));

/*compute r, the correlation coefficient between the two arrays */
for( i = 0; i < n; ++i ) {
r += (((x[i] - xbar)/sx) * ((y[i] - ybar)/sy));
}
r /= (n); /* originally divided by n-1, but gave incorrect results
dividing by n instead produces the desired output */
/* print results */
printf("The correlation coefficient of the entered lists is: %6.4f\n", r);
return 0;

}

(看起来我的代码格式不工作,对此非常抱歉。尝试使用标签和按钮但无法弄清楚。看起来我让它工作了一些,比以前更好。)

最佳答案

您计算的标准偏差为:

sx = sqrt((sx / n));

sy 也是如此。

您使用的等式在分母中使用 n-1 来计算这个( reason :有 n-1 自由度,所以您应该除以通过 n-1)。所以,你的 sxsy 实际上是 sx'sy',其中 sx' = sx *sqrt(n-1)/sqrt(n),和 sy' = sy*sqrt(n-1)/sqrt(n)。所以,sx' * sy' = sx * sy * (n-1)/n。由于 sx*sy 在分母中,因此您的计算因 n/(n-1) 而偏离。将其除以 n 即可得到求和之​​外所需的因数。

因此,如果您更改代码以计算样本标准差(除以 n-1),您最终可以除以 n-1,您的代码将得到你期望的结果。为了提高效率,由于除法无论如何都会抵消,您可以通过在 sx 的计算中不除以 n-1 来节省一些计算并提高准确性code>sy,然后也省略最后的除法:

sx = sqrt((sx / n));
sy = sqrt((sy / n));

成为

sx = sqrt(sx);
sy = sqrt(sy);

和:

r /= (n);

完全消失了。

编辑:既然你问了......

  1. 没有理由使用 float 除非你必须这样做。 double 为您提供更高的精度。
  2. 默认情况下,stdout 在大多数系统上都是行缓冲的,因此在调用 scanf() 之前您的提示可能不会出现。为确保显示提示,请在调用 printf() 后执行 fflush(stdout);
  3. 很难安全地使用scanf()。对于读取数字,当有人输入不在数据类型范围内的数字时,scanf() 具有未定义的行为。此外,这对某些情况不利,例如当有人响应您的提示输入非整数时。对于您的情况,您可以将 n 作为命令行参数传递,然后使用 strtol(argv[1]) 来解析数字。如果您无论如何都想从 stdin 读取,请使用 fgets() + sscanf() 组合,或 fgets() + strtol()
  4. 您可以减少程序中的循环次数。一方面,您可以在同一个循环中计算 xbarybar。更好的是,您可以编写一个函数 double avg(double *data, int n),计算 n 值的平均值,然后执行:xbar=avg (x, n);, ybar=avg(y, n);
  5. 同样,您可以定义一个函数double std(double *data, int n),然后使用它来计算sxsy.
  6. 最后,虽然没关系,但是括号太多了:sqrt((sx/n)); 最好写成 sqrt(sx/n); . r/= (n); 也不需要括号。

关于c - 奇数 PIL 逊相关系数结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2153466/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com