-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhighlight.py
215 lines (192 loc) · 15.9 KB
/
highlight.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# Written by Yuen-Hsien Tseng on 2022/01/30
import sys, re, json
from LCS import LCS
import jieba
jieba.setLogLevel(60) # stop printing loading messages to stderr
from gensim import corpora, models, similarities
class Indexing():
def __init__(self, org_texts, min_length):
self.org_texts = org_texts
#self.texts = [ jieba.lcut(text) for text in org_texts ]
self.texts = []
for text in org_texts:
if len(text) <= min_length:
self.texts.append( [] )
else:
self.texts.append( jieba.lcut(text) )
self.MakeIndex()
def MakeIndex(self):
self.dictionary = corpora.Dictionary(self.texts)
self.NumTokens = len(self.dictionary)
self.corpus = [self.dictionary.doc2bow(text) for text in self.texts]
self.tfidf = models.TfidfModel(self.corpus, normalize=True)
self.corpus_tfidf = self.tfidf[self.corpus]
self.index = similarities.SparseMatrixSimilarity(self.corpus_tfidf, num_features=self.NumTokens)
def GetSimilarText(self, inp, sim_threshold):
new = self.dictionary.doc2bow( jieba.lcut(inp) )
new_tfidf = self.tfidf[new]
sims = self.index[new_tfidf]
sims = sorted(enumerate(sims), key=lambda item: -item[1])
#print(sims[:3]) # print sorted (document number, similarity score) 2-tuples
SimTexts = []
for (docID, sim) in sims:
if sim > sim_threshold: # append a triple
SimTexts.append((docID, sim, self.org_texts[docID]))
return SimTexts
'''
SimTexts = GetSimilarText(inp, sim_threshold)
for DocID, sim, SimText in SimTexts:
print(DocID, sim, SimText)
'''
def HighLightFast(sentence, TextPatterns, Bold, index):
''' A fast method to highlight a given sentence based on indexing'''
SimTexts = index[Bold].GetSimilarText(sentence, 0.5)
if len(SimTexts) == 0:
return (0, sentence)
(maxi, sim, txtpttn) = SimTexts[0]
(matchedMatrix, mPos) = LCS(sentence, txtpttn)
#print("mPos:", mPos)
#print("sentence="+sentence)
#print("Pattern="+TextPatterns[maxi])
mPos.reverse()
for pos in mPos:
(p, length) = pos
sentence = sentence[ : p + length ] + '</'+Bold+'>' + sentence[ p + length : ]
sentence = sentence[ : p ] + '<'+Bold+'>' + sentence[ p : ]
return (1, sentence)
def HighLightOne(sentence, TextPatterns, Bold):
''' A brute force method to highlight a given sentence'''
bestMatch = 0
maxi = 0 # the index of the matched text pattern
mPos = [] # must initialize this variable
for i, txtpttn in enumerate(TextPatterns):
if len(txtpttn) < 4:
(matchedMatrix, matchedPos) = ([], [])
else:
(matchedMatrix, matchedPos) = LCS(sentence, txtpttn)
length = sum([ length for (p, length) in matchedPos if length > 1])
if (length > len(sentence)*0.4 # total matched length must exceed a threshold
and length > len(txtpttn)*0.25
and bestMatch < length):
bestMatch = length
mPos = matchedPos
maxi = i
if bestMatch > 0:
# print("bestMatch =", bestMatch, ", mPos:", mPos)
# print("sentence="+sentence)
# print("Pattern="+TextPatterns[maxi])
mPos.reverse()
for pos in mPos:
(p, length) = pos
sentence = sentence[ : p + length ] + '</'+Bold+'>' + sentence[ p + length : ]
sentence = sentence[ : p ] + '<'+Bold+'>' + sentence[ p : ]
return (bestMatch, sentence)
def HighLightAll(text, TextPatterns, index):
'''
Given a text generated by the bullshit generator,
fuzzily highlight the strings from data.json.
'''
Sentences = re.findall(r'[^。?!?!]+[。?!!?]', text)
Sents = []
num_matched = 0 # number of matched text pattern
for sent in Sentences:
num_sent_matched = 0
for (key, tag) in (('famous', 'F'), ('bullshit', 'B'),
('before', 'P'), ('after', 'A')):
if tag in ['F', 'B']:
(match, sent) = HighLightFast(sent, TextPatterns[key], tag, index)
else:
(match, sent) = HighLightOne(sent, TextPatterns[key], tag)
if match and num_sent_matched == 0:
Sents.append( sent )
num_matched += 1 # one sent may match one text pattern, but rarely
num_sent_matched += 1
if num_sent_matched == 0:
Sents.append( sent )
elif num_sent_matched > 1:
sys.stderr.write("One sentence matches %d text patterns" % num_sent_matched)
return (num_matched, Sents)
if __name__ == '__main__':
import time
time1 = time.time()
(file, text) = sys.argv[1:3]
with open(file, "r", encoding="utf8") as f:
TextPatterns = json.loads(f.read())
index = {}
index['F'] = Indexing(TextPatterns['famous'], 5)
index['B'] = Indexing(TextPatterns['bullshit'], 5)
(num_match, Sentences) = HighLightAll(text, TextPatterns, index)
if len(sys.argv) == 4: # if give an html_file name
S = []
for sent in Sentences:
sent = sent.replace('<F>', '<font color="red">')
sent = sent.replace('<B>', '<font color="blue">')
sent = sent.replace('<P>', '<font color="orange">')
sent = sent.replace('<A>', '<font color="green">')
sent = re.sub(r'</.>', '</font>', sent)
S.append(sent)
with open(sys.argv[3], 'w') as outF:
outF.write("<html><head></head><body><h2>Highlighted Text:</h2>\n")
outF.write("<br>\n".join(S))
outF.write(f"\n<h2>Original Text:</h2>\n{text}\n")
outF.write('</body></html>')
else:
print("\nHighlighted Text:\n" + "".join(Sentences))
sys.stderr.write("It takes %2.4f seconds for %d matches in %d sentences.\n"
% ((time.time() - time1), num_match, len(Sentences)))
''' 測試命令:
On 2022/02/02
測試世新大學葉乃靜老師的臉書貼文:https://www.facebook.com/liz.li.9480/posts/4749671761785382
$ python highlight.py ./data.json '不要先入為主覺得資訊行為很複雜,實際上,資訊行為可能比你想的還要更複雜。了解清楚資訊行為到底是一種怎麼樣的存在,是解決一切問題的關鍵。一般來講,我們都必須務必慎重的考慮考慮。
我們普遍認為,若能理解透徹核心原理,對其就有了一定的了解程度。查普曼說過一句富有哲理的話,誰都沒有真正的愛情,而只有一見鍾情。這讓我的思緒清晰了。我們需要淘汰舊有的觀念,資訊行為的出現,必將帶領人類走向更高的巔峰。把資訊行為輕鬆帶過,顯然並不適合。資訊行為必定會成為未來世界的新標準。既然,在人生的歷程中,資訊行為的出現是必然的。想必大家都能了解資訊行為的重要性。總而言之,我認為,泰戈爾曾說過一句意義深遠的話,人生雖只有幾十春秋,但它決不是夢一般的幻滅,而是有著無窮可歌可頌的深長意義的; 附和真理,生命便會得到永生。希望大家能從這段話中有所收穫。
斯賓諾莎曾說過,我們對於情感的理解愈多,則我們愈能控制情感,而心靈感受情感的痛苦也愈少。這讓我對於看待這個問題的方法有了巨大的改變。動機,可以說是最單純的力量。若無法徹底理解資訊行為,恐怕會是人類的一大遺憾。'
Highlighted Text:
<B>不要先入為主覺得</B>資訊行為<B>很複雜,實際上,</B>資訊行為<B>可能比你想的還要更複雜。</B><B>了解清楚</B>資訊行為<B>到底是一種怎麼樣的存在,是解決一切問題的關鍵。</B><B>一般來講,我們都必須務必慎重的考慮考慮。</B>
<B>我們普遍認為,若能理解透徹核心原理,對其就有了一定的了解程度。</B><F>查普曼</F>說過一句富有哲理的話<F>,誰都沒有真正的愛情,而只有一見鍾情。</F>這讓我的<B>思緒清晰了。</B>我們需要淘汰舊有的觀念,資訊行為<B>的出現,必將帶領人類走向更高的巔峰。</B><B>把</B>資訊行為<B>輕鬆帶過,顯然並不適合。</B>資訊行為<B>必定會成為未來世界的新標準。</B>既然,<B>在人生的歷程中,</B>資訊行為<B>的出現是必然的。</B><B>想必大家都能了解</B>資訊行為<B>的重要性。</B>總而言之,我認為,<F>泰戈爾</F>曾說過一句意義深遠的話<F>,人生雖只有幾十春秋,但它決不是夢一般的幻滅,而是有著無窮可歌可頌的深長意義的; 附和真理,生命便會得到永生。</F><A>希望大家能從這段話中有所收穫。</A>
<F>斯賓諾莎</F>曾說過<F>,我們對於情感的理解愈多,則我們愈能控制情感,而心靈感受情感的痛苦也愈少。</F><A>這讓我對於看待這個問題的方法有了巨大的改變。</A><B>動機,可以說是最單純的力量。</B><B>若無法徹底理解</B>資訊行為<B>,恐怕會是人類的一大遺憾。</B>
It takes 1.4563 seconds for 17 matches in 17 sentences.
It takes 1.8024 seconds for 17 matches in 17 sentences.
It takes 15.2392 seconds for 17 matches in 17 sentences. on 2022/01/31
底下測試楊德倫用唬爛產生器生成的範例:
$ python highlight.py ./data.json '若能夠洞悉資訊行為各種層面的含義,
勢必能讓思維再提高一個層級。世界需要改革,需要對資訊行為有新的認知。
我們都知道,只要有意義,那麼就必須慎重考慮。做好資訊行為這件事,可以說已經成為了全民運動。
我以為我了解資訊行為,但我真的了解資訊行為嗎?仔細想想,我對資訊行為的理解只是皮毛而已。
回過神才發現,思考資訊行為的存在意義,已讓我廢寢忘食。
我們都有個共識,若問題很困難,那就勢必不好解決。
既然如此,我們不得不面對一個非常尷尬的事實,那就是,蘇霍姆林斯基曾說過,
只有能夠激發學生去進行自我教育的教育,才是真正的教育。這影響了我的價值觀。'
Highlighted Text:
<B>若能夠洞悉</B>資訊行為<B>各種層面的含義,</B>
<B>勢必能讓思維再提高一個層級。</B><B>世界需要改革,需要對</B>資訊行為<B>有新的認知。</B>
<B>我們都知道,只要有意義,那麼就必須慎重考慮。</B><B>做好</B>資訊行為<B>這件事,可以說已經成為了全民運動。</B>
<B>我以為我了解</B>資訊行為<B>,但我真的了解</B>資訊行為<B>嗎?</B><B>仔細想想,我對</B>資訊行為<B>的理解只是皮毛而已。</B>
<B>回過神才發現,思考</B>資訊行為<B>的存在意義,已讓我廢寢忘食。</B>
<B>我們都有個共識,若問題很困難,那就勢必不好解決。</B>
既然如此,我們不得不面對一個非常尷尬的事實,那就是,<F>蘇霍姆林斯基</F>曾說過<F>,</F>
<F>只有能夠激發學生去進行自我教育的教育,才是真正的教育。</F><A>這影響了我的價值觀。</A>
It takes 1.3296 seconds for 10 matches in 10 sentences.
It takes 1.5615 seconds for 10 matches in 10 sentences.
It takes 9.0120 seconds for 10 matches in 10 sentences. on 2022/01/31
$ python highlight.py ./data.json '需要考慮周詳唬爛會長壽的影響及因應對策。在這種困難的抉擇下,本人思來想去,寢食難安。經過上述討論,我以為我了解唬爛會長壽,但我真的了解唬爛會長壽嗎?仔細想想,我對唬爛會長壽的理解只是皮毛而已。回過神才發現,思考唬爛會長壽的存在意義,已讓我廢寢忘食。這是不可避免的。唬爛會長壽因何而發生?普勞圖斯說過一句很有意思的話,需要面 前無羞恥。這段話可說是震撼了我。愛獻生深信,人類的全部歷史都告誡有智慧的人,不要篤信時運,而應堅信思想。這不禁令我深思。'
Highlighted Text:
<B>需要考慮周詳</B>唬爛會長壽<B>的影響及因應對策。</B><B>在這種困難的抉擇下,本人思來想去,寢食難安。</B>經過上述討論,<B>我以為我了解</B>唬爛會長壽<B>,但我真的了解</B>唬爛會長壽<B>嗎?</B><B>仔細想想,我對</B>唬爛會長壽<B>的理解只是皮毛而已。</B><B>回過神才發現,思考</B>唬爛會長壽<B>的存在意義,已讓我廢寢忘食。</B><B>這是不可避免的。</B>唬爛會長壽<B>因何而發生?</B>普勞圖斯<P>說過一句很有意思的話</P>,需要面 前無羞恥。<A>這段話可說是震撼了我。</A><F>愛獻生</F>深信<F>,人類的全部歷史都告誡有智慧的人,不要篤信時運,而應堅信思想。</F><A>這不禁令我深思。</A>
It takes 1.2101 seconds for 11 matches in 11 sentences.
It takes 1.5033 seconds for 11 matches in 11 sentences.
It takes 7.4386 seconds for 11 matches in 11 sentences. on 2022/01/31
On 2022/02/05
$ python highlight.py ./data.json '不要先入為主覺得資訊行為很複雜,實際上,資訊行為可能比你想的還要更複雜。了解清楚資訊行為到底是一種怎麼樣的存在,是解決一切問題的關鍵。一般來講,我們都必須務必慎重的考慮考慮。
我們普遍認為,若能理解透徹核心原理,對其就有了一定的了解程度。查普曼說過一句富有哲理的話,誰都沒有真正的愛情,而只有一見鍾情。這讓我的思緒清晰了。我們需要淘汰舊有的觀念,資訊行為的出現,必將帶領人類走向更高的巔峰。把資訊行為輕鬆帶過,顯然並不適合。資訊行為必定會成為未來世界的新標準。既然,在人生的歷程中,資訊行為的出現是必然的。想必大家都能了解資訊行為的重要性。總而言之,我認為,泰戈爾曾說過一句意義深遠的話,人生雖只有幾十春秋,但它決不是夢一般的幻滅,而是有著無窮可歌可頌的深長意義的; 附和真理,生命便會得到永生。希望大家能從這段話中有所收穫。
斯賓諾莎曾說過,我們對於情感的理解愈多,則我們愈能控制情感,而心靈感受情感的痛苦也愈少。這讓我對於看待這個問題的方法有了巨大的改變。動機,可以說是最單純的力量。若無法徹底理解資訊行為,恐怕會是人類的一大遺憾。' tmp/tmp.html
$ python highlight.py ./data.json '若能夠洞悉資訊行為各種層面的含義,
勢必能讓思維再提高一個層級。世界需要改革,需要對資訊行為有新的認知。
我們都知道,只要有意義,那麼就必須慎重考慮。做好資訊行為這件事,可以說已經成為了全民運動。
我以為我了解資訊行為,但我真的了解資訊行為嗎?仔細想想,我對資訊行為的理解只是皮毛而已。
回過神才發現,思考資訊行為的存在意義,已讓我廢寢忘食。
我們都有個共識,若問題很困難,那就勢必不好解決。
既然如此,我們不得不面對一個非常尷尬的事實,那就是,蘇霍姆林斯基曾說過,
只有能夠激發學生去進行自我教育的教育,才是真正的教育。這影響了我的價值觀。' tmp/tmp.html
$ python highlight.py ./data.json '需要考慮周詳唬爛會長壽的影響及因應對策。在這種困難的抉擇下,本人思來想去,寢食難安。經過上述討論,我以為我了解唬爛會長壽,但我真的了解唬爛會長壽嗎?仔細想想,我對唬爛會長壽的理解只是皮毛而已。回過神才發現,思考唬爛會長壽的存在意義,已讓我廢寢忘食。這是不可避免的。唬爛會長壽因何而發生?普勞圖斯說過一句很有意思的話,需要面 前無羞恥。這段話可說是震撼了我。愛獻生深信,人類的全部歷史都告誡有智慧的人,不要篤信時運,而應堅信思想。這不禁令我深思。' tmp/tmp.html
'''