如何获取 Fry Graph 可读性公式的级别?

发布于 2024-08-24 18:40:26 字数 755 浏览 5 评论 0原文

我正在开发一个应用程序 (C#),它将一些可读性公式应用于文本,例如 Gunning-Fog、Precise SMOG、Flesh-Kincaid。

现在,我需要在我的程序中实现基于 Fry 的评分公式,我理解公式的逻辑,几乎需要 3 100 个单词的样本并计算每 100 个单词的句子和每 100 个单词的音节的平均值,然后,您可以使用图表来绘制值。

此处更详细地解释了此公式的工作原理。

我已经有了平均值,但我不知道如何告诉我的程序“检查图表并绘制值并给我一个水平”。我不必向用户显示图表,我只需向他显示级别。

我想也许我可以把所有的值都记在记忆里,分成不同的级别,例如:

级别 1:句子平均值在 10.0 到 25+ 之间,音节平均值在 108 到 132 之间的值。 级别 2:句子平均值在 10.0 到 25+ 之间

的值。句子平均值在 7.7 和 10.0 之间,等等。

但问题是,到目前为止,我找到定义级别的值的唯一地方是在图表本身中,而且它们并不是太非常准确,所以如果我应用上面评论的方法,尝试从图表中获取值,我的水平估计会太不精确,因此,基于 Fry 的等级将不准确。

所以,也许你们中的任何人都知道在某个地方我可以找到基于弗莱的等级的不同级别的精确值,或者你们中的任何人都可以帮助我思考解决这个问题的方法。

谢谢

I'm working in an application (C#) that applies some readability formulas to a text, like Gunning-Fog, Precise SMOG, Flesh-Kincaid.

Now, I need to implement the Fry-based Grade formula in my program, I understand the formula's logic, pretty much you take 3 100-words samples and calculate the average on sentences per 100-words and syllables per 100-words, and then, you use a graph to plot the values.

Here is a more detailed explanation on how this formula works.

I already have the averages, but I have no idea on how can I tell my program to "go check the graph and plot the values and give me a level." I don't have to show the graph to the user, I only have to show him the level.

I was thinking that maybe I can have all the values in memory, divided into levels, for example:

Level 1: values whose sentence average are between 10.0 and 25+, and whose syllables average are between 108 and 132.

Level 2: values whose sentence average are between 7.7 and 10.0, and .... so on

But the problem is that so far, the only place in which I have found the values that define a level, are in the graph itself, and they aren't too much accurate, so if I apply the approach commented above, trying to take the values from the graph, my level estimations would be too much imprecise, thus, the Fry-based Grade will not be accurate.

So, maybe any of you knows about some place where I can find exact values for the different levels of the Fry-based Grade, or maybe any of you can help me think in a way to workaround this.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

层林尽染 2024-08-31 18:40:26

好吧,我不确定这是否是最有效的解决方案,也不是最好的解决方案,但至少它可以完成工作。

我放弃了用数学公式来获得等级的想法,也许有这样的公式,但我找不到它。

所以我采用了 Fry 的图表,包含所有级别,并为每个级别绘制了不同的颜色,我使用以下方法将图像加载到我的程序中:

Bitmap image = new Bitmap(@"C:\FryGraph.png");

image.GetPixel(int x, int y);

如您所见,加载图像后,我使用 GetPixel 方法来获取颜色在指定的坐标处。我必须进行一些转换,以获得图表上给定值的等效像素,因为图表的比例并不等于图像的像素。

最后,我比较了 GetPixel 返回的颜色,看看哪个是文本的 Fry 可读性级别。

我希望这对面临同样问题的人有帮助。

干杯。

Well, I'm not sure about this being the most efficient solution, neither the best one, but at least it does the job.

I gave up to the idea of having like a math formula to get the levels, maybe there is such a formula, but I couldn't find it.

So I took the Fry's graph, with all the levels, and I painted each level of a different color, them I loaded the image on my program using:

Bitmap image = new Bitmap(@"C:\FryGraph.png");

image.GetPixel(int x, int y);

As you can see, after loading the image I use the GetPixel method to get the color at the specified coordinates. I had to do some conversion, to get the equivalent pixels for a given value on the graph, since the scale of the graph is not the equivalent to the pixels of the image.

In the end, I compare the color returned by GetPixel to see which was the Fry readability level of the text.

I hope this may be of any help for someone who faces the same problem.

Cheers.

生生漫 2024-08-31 18:40:26

您只需确定图表的公式即可。即,接受句子数和音节数并返回级别的公式。

如果找不到公式,可以自己确定。估计 图表上每条线的线性方程。还要估计“长单词”和“长句子”区域中的“出界”区域。

现在对于每个点,只需确定它所在的区域即可;哪一行在上面,哪一行在下面。这是相当简单的代数,不幸的是是我能找到的最好的链接描述如何做到这一点。

You simply need to determine the formula for the graph. That is, a formula that accepts the number of sentences and number of syllables, and returns the level.

If you can't find the formula, you can determine it yourself. Estimate the linear equation for each of the lines on the graph. Also estimate the 'out-of-bounds' areas in the 'long words' and 'long sentences' areas.

Now for each point, just determine the region in which it resides; which lines it is above and which lines it is below. This is fairly simple algebra, unfortunately this is the best link I can find to describe how to do that.

老娘不死你永远是小三 2024-08-31 18:40:26

我已经解决了这个问题,我想我会分享,以防其他人将来某个时候看到。我根据上面的答案创建了一个通用的线性方程列表,可以用来确定大致的年级水平。首先必须纠正这些值以使其更加线性。这没有考虑到无效区域,但我可能会重新考虑这一点。
方程类:

public class GradeLineEquation
{
    // using form y = mx+b
    // or y=Slope(x)=yIntercept

    public int GradeLevel { get; set; }

    public float Slope { get; set; }
    public float yIntercept { get; set; }

    public float GetYGivenX(float x)
    {
        float result = 0;
        result = (Slope * x) + yIntercept;
        return result;
    }

    public GradeLineEquation(int gradelevel,float slope,float yintercept)
    {
        this.GradeLevel = gradelevel;
        this.Slope = slope;
        this.yIntercept = yintercept;
    }


}

这是 FryCalculator:

public class FryCalculator
{

    //this class normalizes the plot on the Fry readability graph the same way a person would, by choosing points on the graph based on values even though
    //the y-axis is non-linear and neither axis starts at 0.  Just picking a relative point on each axis to plot the intercept of the zero and infinite scope lines

    private List<GradeLineEquation> linedefs = new List<GradeLineEquation>();

    public FryCalculator()
    {
        LoadLevelEquations();
    }
    private void LoadLevelEquations()
    {
        // load the estimated linear equations for each line with the 
        // grade level, Slope, and y-intercept
        linedefs.Add(new NLPTest.GradeLineEquation(1, (float)0.5, (float)22.5));
        linedefs.Add(new NLPTest.GradeLineEquation(2, (float)0.5, (float)20.5));
        linedefs.Add(new NLPTest.GradeLineEquation(3, (float)0.6, (float)17.4));
        linedefs.Add(new NLPTest.GradeLineEquation(4, (float)0.6, (float)15.4));
        linedefs.Add(new NLPTest.GradeLineEquation(5, (float)0.625, (float)13.125));
        linedefs.Add(new NLPTest.GradeLineEquation(6, (float)0.833, (float)7.333));
        linedefs.Add(new NLPTest.GradeLineEquation(7, (float)1.05, (float)-1.15));
        linedefs.Add(new NLPTest.GradeLineEquation(8, (float)1.25, (float)-8.75));
        linedefs.Add(new NLPTest.GradeLineEquation(9, (float)1.75, (float)-24.25));
        linedefs.Add(new NLPTest.GradeLineEquation(10, (float)2, (float)-35));
        linedefs.Add(new NLPTest.GradeLineEquation(11, (float)2, (float)-40));
        linedefs.Add(new NLPTest.GradeLineEquation(12, (float)2.5, (float)-58.5));
        linedefs.Add(new NLPTest.GradeLineEquation(13, (float)3.5, (float)-93));
        linedefs.Add(new NLPTest.GradeLineEquation(14, (float)5.5, (float)-163));
    }


    public int GetGradeLevel(float avgSylls,float avgSentences)
    {
        // first normalize the values given to cartesion positions on the graph
        float x = NormalizeX(avgSylls);
        float y = NormalizeY(avgSentences);

        // given x find the first grade level equation that produces a lower y at that x
        return linedefs.Find(a => a.GetYGivenX(x) < y).GradeLevel;
    }

    private float NormalizeY(float avgSentenceCount)
    {
        float result = 0;
        int lower = -1;
        int upper = -1;
        // load the list of y axis line intervalse
        List<double> intervals = new List<double> {2.0, 2.5, 3.0, 3.3, 3.5, 3.6, 3.7, 3.8, 4.0, 4.2, 4.3, 4.5, 4.8, 5.0, 5.2, 5.6, 5.9, 6.3, 6.7, 7.1, 7.7, 8.3, 9.1, 10.0, 11.1, 12.5, 14.3, 16.7, 20.0, 25.0 };
        // find the first line lower or equal to the number we have
        lower = intervals.FindLastIndex(a => ((double)avgSentenceCount) >= a);

        // if we are not over the top or on the line grab the next higher line value
        if(lower > -1 && lower < intervals.Count-1 && ((float) intervals[lower] != avgSentenceCount))
            upper = lower + 1;

        // set the integer portion of the respons
        result = (float)lower;
        // if we have an upper limit calculate the percentage above the lower line (to two decimal places) and add it to the result
        if(upper != -1)
             result += (float)Math.Round((((avgSentenceCount - intervals[lower])/(intervals[upper] - intervals[lower]))),2); 

        return result;
    }

    private float NormalizeX(float avgSyllableCount)
    {
        // the x axis is MUCH simpler.   Subtract 108 and divide by 2 to get the x position relative to a 0 origin.
        float result = (avgSyllableCount - 108) / 2;
        return result;
    }

}

I have made a first pass at solving this that I thought I would share in case someone else is looking sometime in the future. I built on the answer above and created a generic list of linear equations that one can use to determine an approximate grade level. First had to correct the values to make it more linear. This does not take into account the invalid areas, but I may revisit that.
The equation class:

public class GradeLineEquation
{
    // using form y = mx+b
    // or y=Slope(x)=yIntercept

    public int GradeLevel { get; set; }

    public float Slope { get; set; }
    public float yIntercept { get; set; }

    public float GetYGivenX(float x)
    {
        float result = 0;
        result = (Slope * x) + yIntercept;
        return result;
    }

    public GradeLineEquation(int gradelevel,float slope,float yintercept)
    {
        this.GradeLevel = gradelevel;
        this.Slope = slope;
        this.yIntercept = yintercept;
    }


}

Here is the FryCalculator:

public class FryCalculator
{

    //this class normalizes the plot on the Fry readability graph the same way a person would, by choosing points on the graph based on values even though
    //the y-axis is non-linear and neither axis starts at 0.  Just picking a relative point on each axis to plot the intercept of the zero and infinite scope lines

    private List<GradeLineEquation> linedefs = new List<GradeLineEquation>();

    public FryCalculator()
    {
        LoadLevelEquations();
    }
    private void LoadLevelEquations()
    {
        // load the estimated linear equations for each line with the 
        // grade level, Slope, and y-intercept
        linedefs.Add(new NLPTest.GradeLineEquation(1, (float)0.5, (float)22.5));
        linedefs.Add(new NLPTest.GradeLineEquation(2, (float)0.5, (float)20.5));
        linedefs.Add(new NLPTest.GradeLineEquation(3, (float)0.6, (float)17.4));
        linedefs.Add(new NLPTest.GradeLineEquation(4, (float)0.6, (float)15.4));
        linedefs.Add(new NLPTest.GradeLineEquation(5, (float)0.625, (float)13.125));
        linedefs.Add(new NLPTest.GradeLineEquation(6, (float)0.833, (float)7.333));
        linedefs.Add(new NLPTest.GradeLineEquation(7, (float)1.05, (float)-1.15));
        linedefs.Add(new NLPTest.GradeLineEquation(8, (float)1.25, (float)-8.75));
        linedefs.Add(new NLPTest.GradeLineEquation(9, (float)1.75, (float)-24.25));
        linedefs.Add(new NLPTest.GradeLineEquation(10, (float)2, (float)-35));
        linedefs.Add(new NLPTest.GradeLineEquation(11, (float)2, (float)-40));
        linedefs.Add(new NLPTest.GradeLineEquation(12, (float)2.5, (float)-58.5));
        linedefs.Add(new NLPTest.GradeLineEquation(13, (float)3.5, (float)-93));
        linedefs.Add(new NLPTest.GradeLineEquation(14, (float)5.5, (float)-163));
    }


    public int GetGradeLevel(float avgSylls,float avgSentences)
    {
        // first normalize the values given to cartesion positions on the graph
        float x = NormalizeX(avgSylls);
        float y = NormalizeY(avgSentences);

        // given x find the first grade level equation that produces a lower y at that x
        return linedefs.Find(a => a.GetYGivenX(x) < y).GradeLevel;
    }

    private float NormalizeY(float avgSentenceCount)
    {
        float result = 0;
        int lower = -1;
        int upper = -1;
        // load the list of y axis line intervalse
        List<double> intervals = new List<double> {2.0, 2.5, 3.0, 3.3, 3.5, 3.6, 3.7, 3.8, 4.0, 4.2, 4.3, 4.5, 4.8, 5.0, 5.2, 5.6, 5.9, 6.3, 6.7, 7.1, 7.7, 8.3, 9.1, 10.0, 11.1, 12.5, 14.3, 16.7, 20.0, 25.0 };
        // find the first line lower or equal to the number we have
        lower = intervals.FindLastIndex(a => ((double)avgSentenceCount) >= a);

        // if we are not over the top or on the line grab the next higher line value
        if(lower > -1 && lower < intervals.Count-1 && ((float) intervals[lower] != avgSentenceCount))
            upper = lower + 1;

        // set the integer portion of the respons
        result = (float)lower;
        // if we have an upper limit calculate the percentage above the lower line (to two decimal places) and add it to the result
        if(upper != -1)
             result += (float)Math.Round((((avgSentenceCount - intervals[lower])/(intervals[upper] - intervals[lower]))),2); 

        return result;
    }

    private float NormalizeX(float avgSyllableCount)
    {
        // the x axis is MUCH simpler.   Subtract 108 and divide by 2 to get the x position relative to a 0 origin.
        float result = (avgSyllableCount - 108) / 2;
        return result;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文