拼写检查 - 带有java流的嘈杂通道模型

时间:2017-06-11 04:40:04

标签: java java-8 java-stream spell-checking

我有一个查询日志列表,其中的条目如下所示:

Session ID Query
01 Movie atcor
01 Movie actor
02 Award winning axtor
02 Award winning actor
03 Soap opera axtor
03 Soap opera actor
...

我需要确定拼写建议正确的概率。例如,如果我想确定"演员"的概率。正确拼写" axtor,"我会通过确定" axtor"被#34;演员取代,"除以"演员"的会话数量。是任何拼写错误的单词的正确拼写。

这意味着在这种情况下,概率将是2/3,因为有两个会话,其中"演员"取代" axtor"和三个会议"演员"取代错误拼写(" atcor"" axtor")。

我试图让自己更熟悉Java 8流,所以我试图使用流来获得解决方案。

这是我能够提出的。这是朝着正确方向迈出的一步,但我仍然遗漏了一些碎片。

public int numberOfCorrections(String misspelledWord, String suggestedWord)
{
    return (int) sessionIdsWithWord(misspelledWord)
            .stream()
            .map(sessionId -> getLogsWithSameSessionId(sessionId)
                    .stream()
                    .filter(queryLog -> queryLog.queryContainsWord(suggestedWord))
                    .count()
            ).count();
}

public Set<String> sessionIdsWithWord(String word)
{
    return getQueryLogsThatContainWord(word)
            .stream()
            .map(QueryLog::getSessionId)
            .collect(Collectors.toSet());
}

public List<QueryLog> getQueryLogsThatContainWord(String word)
{
    return logs
            .stream()
            .filter(queryLog -> queryLog.queryContainsWord(word))
            .collect(Collectors.toList());
}

public Map<String, List<QueryLog>> getSessionIdMapping()
{
    return logs
            .stream()
            .collect(Collectors.groupingBy(QueryLog::getSessionId));
}

public List<QueryLog> getLogsWithSameSessionId(String sessionId)
{
    return getSessionIdMapping()
            .get(sessionId);
}

我做的不太对劲。我只根据suggestedWord是否出现在查询日志中而进行过滤。我需要检查并查看它是否在正确的位置(拼写错误的单词与纠正位置相同)。

我需要在numberOfCorrections中的一种方式,在流的.map部分检查并查看查询日志是否suggestedWord位于misspelledWord的同一位置在查询中。这是我被困的地方。我怎么能这样做?

我认为它可能是这样的:

.map(sessionId -> getLogsWithSameSessionId(sessionId)
        .stream()
        .filter(queryLog -> //queryLog.getQuery().equals(some other queryLog in the same session)
        .count()
).count();

但我不知道是否有办法与同一会话中的其他queryLog进行比较。

我无法真正转向概率的第二部分,直到我能够根据给定查询是否与同一会话中的另一个查询相似来计算出如何进行过滤。

1 个答案:

答案 0 :(得分:2)

逐一解释你的方法并不容易。这是一个简单的解决方案:

public double countProbability(String misspelledWord, String suggestedWord) {
    try (Stream<String> stream = Files.lines(logFilePath)) {
        return stream.skip(1).map(line -> line.contains(misspelledWord) ? misspelledWord : (line.contains(suggestedWord) ? suggestedWord : ""))
                .filter(w -> !w.equals("")).collect(collectingAndThen(groupingBy(Function.identity(), counting()),
                        m -> m.size() < 2 ? 0d : m.get(misspelledWord).doubleValue() / m.get(suggestedWord)));
    }
}

我可能会误解你的问题。