shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package com.walker.semantics.support;
 
import com.walker.infrastructure.utils.StringUtils;
import com.walker.semantics.ExtractorException;
import com.walker.semantics.InputWord;
import com.walker.semantics.SemanticsManager;
import com.walker.semantics.SummaryExtractor;
import com.walker.semantics.SummaryMeta;
import com.walker.semantics.SummaryQuery;
import com.walker.semantics.WordKey;
import org.ansj.app.keyword.KeyWordComputer;
import org.ansj.app.keyword.Keyword;
import org.ansj.app.summary.SummaryComputer;
import org.ansj.app.summary.TagContent;
import org.ansj.app.summary.pojo.Summary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
public abstract class AbstractSummaryExtractor implements SummaryExtractor {
 
    protected final transient Logger logger = LoggerFactory.getLogger(getClass());
 
    @Override
    public SummaryMeta extract(SummaryQuery query) throws ExtractorException {
        if(query == null){
            throw new ExtractorException("未提供抽取条件,无法完成摘要抽取");
        }
        if(StringUtils.isEmpty(query.getContent())){
            throw new ExtractorException("原始抽取素材不存在");
        }
        if(query.getMinScore() <= 0){
            throw new ExtractorException("关键词分值必须大于0");
        }
 
        String input = query.getContent();
        if(this.logger.isDebugEnabled()){
            this.logger.debug(input);
        }
 
        InputWord inputWord = new InputWord(input);
        if(inputWord.getWordMetaList().size() <= 3){
            throw new ExtractorException("输入内容过少", query.getContent(), true);
        }
        logger.debug(inputWord.getWordMetaList().toString());
 
        String referenceKeywords = null;
        if(StringUtils.isNotEmpty(query.getKeywords())){
            referenceKeywords = query.getKeywords();
        } else {
            referenceKeywords = this.acquireKeywords(null, input);
        }
        logger.debug("referenceKeywords = {}", referenceKeywords);
 
        SummaryComputer summaryComputer = new SummaryComputer(query.getMaxLength(), null, input);
        Summary summary = summaryComputer.toSummary(referenceKeywords);
        List<Keyword> keywordList = summary.getKeyWords();
        if(keywordList == null || keywordList.size() <= 1){
            throw new ExtractorException("输入内容过少", query.getContent(), true);
        }
 
        double minScore = query.getMinScore();
        StringBuilder title = new StringBuilder();
 
        List<WordKey> wordKeyList = new ArrayList<>(keywordList.size());
        for(Keyword keyword : keywordList){
            if(keyword.getScore() >= minScore){
                wordKeyList.add(new WordKey(keyword.getScore(), keyword.getName()));
                title.append(keyword.getName());
            }
        }
 
        SummaryMeta summaryMeta = new SummaryMeta();
        summaryMeta.setTitle(title.toString());
        summaryMeta.setSummary(summary.getSummary());
        summaryMeta.setWordKeyList(wordKeyList);
 
        // 如果存在标签,添加标签内容
        if(StringUtils.isNotEmpty(query.getBeginTag()) && StringUtils.isNotEmpty(query.getEndTag())){
            TagContent tagContent = new TagContent(query.getBeginTag(), query.getEndTag());
            summaryMeta.setTagSummary(tagContent.tagContent(summary));
        }
        return summaryMeta;
    }
 
    /**
     * 从内容中获取排名靠前的关键词集合,按照分值排名
     * @param title 给定的参考标题,可选
     * @param content 给定的原始内容素材
     * @return 返回关键词字符串结果
     */
    private String acquireKeywords(String title, String content){
        KeyWordComputer kwc = new KeyWordComputer(20);
        Collection<Keyword> result = kwc.computeArticleTfidf(title, content);
        if(result == null || result.size() == 0){
            return StringUtils.EMPTY_STRING;
        }
 
        StringBuilder sb = new StringBuilder();
        int size = result.size();
        float currentSize = 0;
        for(Keyword kw : result){
            if(currentSize == 0){
                sb.append(kw.getName());
                currentSize ++;
                continue;
            }
            if(currentSize/size < keywordPercent){
                sb.append(kw.getName());
                currentSize ++;
                continue;
            } else {
                break;
            }
        }
        return sb.toString();
    }
 
    @Override
    public void setSemanticsManager(SemanticsManager semanticsManager) {
        this.semanticsManager = semanticsManager;
    }
 
    public SemanticsManager getSemanticsManager() {
        return semanticsManager;
    }
 
    public float getKeywordPercent() {
        return keywordPercent;
    }
 
    /**
     * 设置提取关键词中的百分比,不能使用全部关键词,只取前百分比部分的。
     * @param keywordPercent
     */
    public void setKeywordPercent(float keywordPercent) {
        this.keywordPercent = keywordPercent;
    }
 
    // 取前 60% 的关键词
    private float keywordPercent = 0.4f;
    private SemanticsManager semanticsManager;
}