Как получить уровни по формуле читабельности Fry Graph? - PullRequest
2 голосов
/ 12 марта 2010

Я работаю в приложении (C #), которое применяет к тексту некоторые формулы читабельности, такие как Gunning-Fog, Precise SMOG, Flesh-Kincaid.

Теперь мне нужно реализовать формулу оценки на основе Фрая в моей программе, я понимаю ее логику, в основном вы берете 3 образца по 100 слов и вычисляете среднее значение для предложений на 100 слов и слогов на 100 слов. , а затем вы используете график для построения значений.

Здесь - более подробное объяснение того, как работает эта формула.

У меня уже есть средние значения, но я понятия не имею, как я могу сказать своей программе: «Пойди проверь график, нарисуй значения и дай мне уровень». Мне не нужно показывать график пользователю, мне нужно только показать ему уровень.

Я думал, что, возможно, у меня могут быть все значения в памяти, разделенные на уровни, например:

Уровень 1: значения, в которых среднее предложение составляет от 10,0 до 25+, а средние слоги - от 108 до 132.

Уровень 2: значения, в которых среднее предложение составляет от 7,7 до 10,0, и ... и т. Д.

Но проблема в том, что до сих пор единственное место, в котором я нашел значения, которые определяют уровень, находится в самом графике, и они не слишком точны, поэтому, если я применю подход, приведенный выше, пытаясь взять значения из графика, мои оценки уровня были бы слишком неточными, поэтому оценка на основе Фрая не будет точной.

Так что, возможно, любой из вас знает о каком-то месте, где я могу найти точные значения для различных уровней оценки на основе Фрая, или, может быть, любой из вас может помочь мне подумать, как обойти это.

Спасибо

Ответы [ 3 ]

1 голос
/ 17 марта 2010

Ну, я не уверен, что это самое эффективное и не самое лучшее решение, но, по крайней мере, оно работает.

Я отказался от идеи иметь математическую формулу для получения уровней, может быть, есть такая формула, но я не смог ее найти.

Итак, я взял график Фрая со всеми уровнями и нарисовал каждый уровень разным цветом. Затем я загрузил изображение в свою программу, используя:

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

image.GetPixel(int x, int y);

Как видите, после загрузки изображения я использую метод GetPixel, чтобы получить цвет по указанным координатам. Мне пришлось сделать какое-то преобразование, чтобы получить эквивалентные пиксели для данного значения на графике, поскольку масштаб графика не эквивалентен пикселям изображения.

В конце я сравниваю цвет, возвращаемый GetPixel, чтобы определить уровень читаемости текста Фраем.

Я надеюсь, что это может помочь любому, кто сталкивается с той же проблемой.

Приветствие.

0 голосов
/ 10 апреля 2018

Я сделал первый проход при решении этого вопроса, который, как я думал, я поделился бы, если кто-нибудь еще заглядывает в будущее. Я построил ответ выше и создал общий список линейных уравнений, который можно использовать для определения приблизительного уровня обучения. Сначала пришлось исправить значения, чтобы сделать его более линейным. Это не учитывает недействительные области, но я могу вернуться к этому. Класс уравнения:

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

}
0 голосов
/ 17 марта 2010

Вам просто нужно определить формулу для графика. То есть формула, которая принимает количество предложений и количество слогов и возвращает уровень.

Если вы не можете найти формулу, вы можете определить ее самостоятельно. Оцените линейное уравнение для каждой из линий на графике. Также оцените области «за пределами» в областях «длинные слова» и «длинные предложения».

Теперь для каждой точки просто определите регион, в котором она находится; какие линии это выше и какие линии это ниже. Это довольно простая алгебра, к сожалению, эта - лучшая ссылка, которую я могу найти, чтобы описать, как это сделать.

...