論文タイトルから雑誌名を当てるプヨグラムを書く

【イントロ】
 名は体を表すということわざがあるように、名前というのは大切な個性です。
子供が生まれると、ご両親は画数や漢字の組み合わせなど、いろいろ思い悩んで最高の名前を子供につけてあげるという大きなイベントが待ち構えています[1]。(楽しそう
すこしでも明るい未来を歩んでほしいという親心に胸が熱くなりますね。
 それでは、研究者にとっていちばん大切な子供である論文にはどのような名前をつけて上げれば、輝かしい未来が待っているのでしょうか?
 そこで今回は、論文のタイトルから掲載されている論文誌を予測する方法がないか考えてみることにしました。

【方法】
 ほんとは”きかい学習”とか”でぃーぷらーにんぐ”とかかっこいい手段を使いたいのですが、知性が足りないので露骨な力技を採用することにしました。
 「各論文誌の出現単語数を頻度順に並べ、頻度が高いものから順にポイントを与え、予測したいタイトルに含まれる単語の総ポイントを各論文誌毎に計算し、最もポイントが高くなる論文誌が一番”それっぽい”論文誌と判断する」、というアルゴリズムにしました。
 今回対象としたのは物理学における定番論文誌、APS発行のPhysical Review誌[2]です。
 まず、Physical Review A, B, C, D, E, Lの各論文誌1年間の論文タイトルをWeb Scrapingにより取得します[3]。ここで注意すべきなのは取得間隔を十分にとることです。さもないとアクセス過多でアク禁されます。(反省)
 ただし皆さんご存知かと思いますが、1年間待つことでアク禁が解除されます[4]。
 APSは優しいですね。
 つぎに、取得したタイトルを出現頻度順にならべます。そして、最多出現頻度を1として規格化します。すると、下図のようなcsvファイルが作成できます。これを各論文誌毎に用意します。
 注意すべきなのは単語を大文字か小文字に揃えることです。
 皆さんご存知かと思いますが、Phys.Rev.誌はPRLのみ論文タイトルの単語の頭文字すべてが大文字、PRA, B, C, D, Eは先頭の単語のみ大文字になっているという違いがあります。これに気づかないと、PRLだけ100%正答することになります。
わたしはこれで休日を1日潰しました。

図1,1年間の論文に含まれる単語の頻度。A列が単語、B列が規格化した出現数、C列が出現数。
  
 次に、予測したい論文タイトルを集めます。これは最新論文から適当に25本ずつ集めました。論文誌6本で全150本です。
 このタイトルを読み込み、単語に分割します。そして、各論文誌毎にポイントを計算します。このとき、未知の単語に対して何ポイント付与するかが問題ですが、とりあえずある程度負の値が良さそうです(霊感)。
 そして、一番高いポイントを示した論文誌がその論文の掲載誌と判断しました。
 こうして比較した全150本の論文のうち何本で正解したか示したのが下図です。

図2、各論文誌25本中、予測と実際が正解した数

正解率53%。。。( ;`・~・) ぐぬぬ…当てずっぽうだと1/6=17%程度の正解率になるので、それを踏まえると割とマシな予測になっています。今はこれが限界。。。

【まとめ】
 今回は、論文タイトルから掲載誌を予測するプログラムを書くことを目指しました。力づくで比較した結果として正解率53%を得ることができました。今後はもっと高度な技術を手に入れて再チャレンジしてみたいです。( ˘ω˘)スヤァ

【参考文献】

  1. 姓名判断
  2. Physical Review誌
  3. 「2016-17年度フィジカルレビュー誌流行語調査...みたいな?」
  4. Private experience.



 【設計図】

タイトル
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/usr/bin/python
 
# coding: UTF-8
 
 
 
import re
 
 
 
x=-10.0 #出てこない単語に対するポイント
 
 
 
def numA(title): #PRAのポイント計算
 
    dict={}
 
    f = open('PRAtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split()
 
    #print(p)
 
    t=0
 
    for i in p:
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
def numB(title): #PRBのポイント計算
 
    dict={} #ココのブロックで辞書の中身を作る
 
    f = open('PRBtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split() #入力したタイトルをリストに分割
 
    #print(p)
 
    t=0
 
    for i in p:
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
 
 
def numC(title): #PRBのポイント計算
 
    dict={} #ココのブロックで辞書の中身を作る
 
    f = open('PRCtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split() #入力したタイトルをリストに分割
 
    #print(p)
 
    t=0
 
    for i in p:
 
        #r=dict.get(i,-0.5)
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
def numD(title): #PRBのポイント計算
 
    dict={} #ココのブロックで辞書の中身を作る
 
    f = open('PRDtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split() #入力したタイトルをリストに分割
 
    #print(p)
 
    t=0
 
    for i in p:
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
def numE(title): #PREのポイント計算
 
    dict={} #ココのブロックで辞書の中身を作る
 
    f = open('PREtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split()
 
    #print(p)
 
    t=0
 
    for i in p:
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
def numL(title): #PRLのポイント計算
 
    dict={} #ココのブロックで辞書の中身を作る
 
    f = open('PRLtitle.csv')#単語と出現頻度のファイル開く
 
    data1 = f.readline()  #各行を読み込む
 
    while data1:#すべての行で繰り返す
 
        lst=re.split('[,\n]', data1) #各行を,と\nで分割
 
        dict[lst[0]]=float(lst[1]) #各単語=各頻度を辞書に保管
 
        data1 = f.readline() #次の行を読み込む
 
 
 
    f.close() #ファイルを閉じる
 
    
 
    p=title.split()
 
    #print(p)
 
    t=0
 
    for i in p:
 
        #r=dict.get(i,-0.40)
 
        r=dict.get(i,x)
 
        t+=r
 
 
 
    return t
 
 
 
#テスト用のデータを読み込んで評価する
 
if __name__=="__main__":
 
    lst=["L","A","B","C","D","E"] #タイトルのラベル
 
    j=0 #ラベルの順番
 
    total=0
 
    for i in lst: #ラベルを順に調べる
 
        title="PR"+i+"Title100.csv" #読み込むラベルのファイル
 
        f = open(title) #ファイル開く
 
        data=f.readline() #ファイルを各行読み込む=入力タイトル
 
        q=0 #ラベルiの雑誌が他の雑誌よりもポイントが高い回数
 
        while data: #すべての各行に対して繰り返す
 
            word=data.lower() #タイトルをすべて小文字に変える
 
            #print(word)
 
            l=[numL(word), numA(word), numB(word), numC(word), numD(word), numE(word)] #あるタイトルの各雑誌ポイントのリスト
 
            if l[j] >= max(l): #今のラベルiの雑誌のポイントが最大ならqに1加える
 
                q+=1
 
            data=f.readline() #つぎの行を読み込む
 
        f.close() #ファイル閉じる
 
        print("PR"+i+" point is " + str(q) +" /25 ") #ラベルiの雑誌がポイント最大だった回数(正解した回数のこと)
 
        total+=q
 
        j+=1 #つぎの雑誌の順番を指定するためラベルの順番を1増やす
 
         
    print(str(total)+"/150") #各雑誌25タイトル合計150タイトルのうち正解タイトル数

コメント

このブログの人気の投稿

LLM技術を利用した常圧高温超伝導体の発見~AIリテラシーを高めるぞ!!!~

拙著はリジェクト また…流れるでござるよ~逆オッカムの剃刀を使って論文を魅力的に~

交代磁性があるのかないのかどっちなんだい!~RuO2の場合~