2

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

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

是有关此公式如何工作的更详细说明。

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

我在想也许我可以将内存中的所有值划分为级别,例如:

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

级别 2:句子平均值在 7.7 到 10.0 之间的值,等等。

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

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

谢谢

4

3 回答 3

1

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

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

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

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

image.GetPixel(int x, int y);

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

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

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

干杯。

于 2010-03-17T00:16:44.223 回答
0

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

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

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

于 2010-03-17T00:34:13.063 回答
0

我已经完成了解决这个问题的第一步,我想我会分享一下,以防其他人在未来的某个时候寻找。我以上面的答案为基础,创建了一个通用的线性方程列表,可以用来确定大致的年级水平。首先必须更正这些值以使其更线性。这没有考虑到无效区域,但我可能会重新考虑。方程类:

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;
    }

}
于 2018-04-10T13:42:12.000 回答