source: other-projects/maori-lang-detection/src/org/greenstone/atea/WebPageURLsListing.java@ 33887

Last change on this file since 33887 was 33887, checked in by ak19, 4 years ago
  1. Added support for writing out tables in csv format too. 2. Second table written out now. 3. Moved getFilePath() into Utility.
File size: 13.1 KB
Line 
1package org.greenstone.atea;
2
3import java.util.*;
4import java.io.*;
5
6import org.apache.log4j.Logger;
7
8/**
9 * Runs some of the important mongoDB queries I ran.
10 *
11 * TO COMPILE OR RUN, FIRST DO:
12 * cd maori-lang-detection/apache-opennlp-1.9.1
13 * export OPENNLP_HOME=`pwd`
14 * cd maori-lang-detection/src
15 *
16 * TO COMPILE:
17 * maori-lang-detection/src$
18 * javac -cp ".:../conf:../lib/*" org/greenstone/atea/WebPageURLsListing.java
19 *
20 * TO RUN:
21 * maori-lang-detection/src$
22 * java -cp ".:../conf:../lib/*" org/greenstone/atea/WebPageURLsListing
23 * OR:
24 * java -cp ".:../conf:../lib/*" org/greenstone/atea/WebPageURLsListing ../mongodb-data/domainsNZ_IsMRI.txt
25 *
26*/
27public class WebPageURLsListing {
28 static Logger logger = Logger.getLogger(org.greenstone.atea.WebPageURLsListing.class.getName());
29 static private final long FIXED_SEED = 1000;
30
31 private final MongoDBAccess mongodbAccess;
32 private File outFolder;
33
34
35
36 public static class Tuple {
37 public final String url;
38 public final String countryCode;
39
40 public Tuple(String url, String countryCode) {
41 this.url = url;
42 this.countryCode = countryCode;
43 }
44
45 public String toString() {
46 return this.url + "," + countryCode;
47 }
48 }
49
50
51 public WebPageURLsListing(MongoDBAccess mongodbAccess, File outFolder)
52 {
53 this.mongodbAccess = mongodbAccess;
54 this.outFolder = outFolder;
55 }
56
57
58 public void produceURLsForPagesInMRI(File domainsFile) {
59 ArrayList<Tuple> urlsList = getURLsForWebPages(MongoDBAccess.IS_MRI, domainsFile);
60 File outFile = new File(outFolder, "isMRI_"+domainsFile.getName());
61 writeURLsToFile(urlsList, outFile, urlsList.size());
62
63 System.out.println("Wrote all isMRI web page URLs for the sites in input domainsFile\ninto file: "
64 + Utility.getFilePath(outFile));
65 }
66
67 public void produceURLsForPagesContainingMRI(File domainsFile) {
68 ArrayList<Tuple> urlsList = getURLsForWebPages(MongoDBAccess.CONTAINS_MRI, domainsFile);
69 File outFile = new File(outFolder, "containsMRI_"+domainsFile.getName());
70 writeURLsToFile(urlsList, outFile, urlsList.size());
71
72 System.out.println("Wrote all containsMRI web page URLs for the sites in input domainsFile\ninto file: "
73 + Utility.getFilePath(outFile));
74 }
75
76 private ArrayList<Tuple> getURLsForWebPages(int filterType, File domainsFile) {
77 ArrayList<Tuple> urlsList = new ArrayList<Tuple>();
78
79 // 1. read each url from the domainsFile
80 // 1a. do the query
81 // 1b. add the arraylist result to urls
82
83 try (
84 BufferedReader reader = new BufferedReader(new FileReader(domainsFile));
85 ) {
86
87 String domain;
88
89 while((domain = reader.readLine()) != null) {
90 domain = domain.trim();
91 if(!domain.equals("")) {
92
93 String countryCode = "";
94 int index = domain.lastIndexOf(",");
95 if(index != -1) {
96 countryCode = domain.substring(index+1).trim();
97 domain = domain.substring(0, index);
98 }
99 ArrayList<String> moreURLs = mongodbAccess.queryAllMatchingURLsFilteredBy(domain, filterType);
100
101 // Print out whether there were no isMRI pages for the domain (only containsMRI). A useful thing to know
102 if(moreURLs.size() == 0 && filterType == MongoDBAccess.IS_MRI) {
103 System.out.println(" " + countryCode + " domain " + domain + " had no isMRI webpages - only containsMRI.");
104 }
105
106 //urlsList.addAll(moreURLs);
107 for(int i = 0; i < moreURLs.size(); i++) {
108 urlsList.add(new Tuple(moreURLs.get(i), countryCode));
109 }
110
111 }
112 }
113 System.err.println("");
114 } catch(Exception e) {
115 logger.error("Unable to read URLs from file " + Utility.getFilePath(domainsFile));
116 logger.error(e.getMessage(), e);
117 }
118
119 return urlsList;
120 }
121
122 /** Given a hand curated list of NZ sites with positive numPagesContainingMRI,
123 * get a listing of all their web pages IN_MRI (or CONTAINS_MRI?).
124 * Total all these pages in MRI (N), then work out the correct sample size (n)
125 * at 90% confidence with 5% margin of error. Then generate a random listing
126 * of n of these pages in MRI of these trusted sites and output to a file
127 * for manual inspection. */
128 /* OLD: Given a hand curated list of non-NZ sites that CONTAINS_MRI, get a listing
129 * of all their web pages IN_MRI (or CONTAINS_MRI).
130 * Plus a listing of all the NZ pages IN_MRI. */
131 //public void webPagesOfAllNZSitesAndDomainListing(File domainsFile) {
132 public void mriWebPageListingForDomainListing(File domainsFile) {
133
134 int filterType = MongoDBAccess.IS_MRI;
135
136 // for overseas websites,
137 //produceURLsForPagesContainingMRI(handCuratedOverseasDomainsFile);
138
139 // 0. get a list of all the web pages in the given domain listing where isMRI = true
140 ArrayList<Tuple> urlsList = getURLsForWebPages(MongoDBAccess.IS_MRI, domainsFile);
141 // produceURLsForPagesInMRI(domainsFile);
142
143 // 1. calculate the population size, N, the number of all webpages in the given domain
144 // site listing where isMRI = true.
145 int N_totalNumPages = urlsList.size();
146
147 // 2. write all the URLs in urlsList to a file
148 //File outFolder = domainsFile.getParentFile();
149 String fileName = (filterType == MongoDBAccess.IS_MRI) ? "isMRI_" : "containsMRI_";
150 File outFile = new File(outFolder, fileName+domainsFile.getName());
151
152 writeURLsToFile(urlsList, outFile, N_totalNumPages);
153 System.out.println("Wrote out full listing of web page URLs for sites in input domainsFile"
154 + "\ninto file: " + Utility.getFilePath(outFile));
155
156 // 3. calculate sample size n for population size N if using 90% confidence and 5% margin of error
157 int n_numSampleURLs = calcSampleSize(N_totalNumPages);
158
159 System.err.println("*** N, total number of web pages that matched: " + N_totalNumPages);
160 System.err.println("*** n, sample size of web page URLs: " + n_numSampleURLs);
161
162 // 4. Shuffle all the URLs and write the first n (sample size) URLs to a file
163 // Using a constant seed for reproducibility
164 // https://stackoverflow.com/questions/6284589/setting-a-seed-to-shuffle-arraylist-in-java-deterministically
165 Collections.shuffle(urlsList, new Random(FIXED_SEED));
166
167 outFile = new File(outFolder, "random"+n_numSampleURLs+"_"+domainsFile.getName());
168 writeURLsToFile(urlsList, outFile, n_numSampleURLs);
169 System.out.println("Wrote a sample of n=" + n_numSampleURLs + " of web page URLs "
170 + "for the sites in input domainsFile\ninto file: " + Utility.getFilePath(outFile));
171 }
172
173 /**
174 * Calculates sample size n for binary outcomes at 90% confidence and 5% margine of error
175 * for given population size N.
176 * @return n, the sample size.
177 */
178 public int calcSampleSize(int N) {
179
180 // calculate sample size n for population size N if using 90% confidence and 5% margin of error
181 // https://stats.stackexchange.com/questions/207584/sample-size-choice-with-binary-outcome
182 // https://www.statisticshowto.datasciencecentral.com/probability-and-statistics/find-sample-size/#CI1
183 // https://www.statisticshowto.datasciencecentral.com/z-alpha2-za2/
184
185 double m = 0.05; // margin of error = 5%
186 // for 90% confidence, alpha is the remainder = 10% and alpha/2 = 5%.
187 // For 90% confidence, use the table of known z_alpha/2 values from step 1 of
188 // https://www.statisticshowto.datasciencecentral.com/z-alpha2-za2/
189 double z_alpha_over_2 = 1.6449;
190
191 // Formula: n = (zalpha2 ^ 2 * N) / ((z-alpha-2 ^ 2) + 4(N-1)*m^2)
192 // see https://stats.stackexchange.com/questions/207584/sample-size-choice-with-binary-outcome
193 double n = (Math.pow(z_alpha_over_2, 2.0) * N) / (Math.pow(z_alpha_over_2, 2.0) + (4 * (N-1) * Math.pow(m,2.0)));
194
195 // Round up to get a whole number:
196 return (int)Math.ceil(n);
197 }
198
199 /**
200 * Writes out the first n URLs in urlsList into outFile.
201 */
202 private void writeURLsToFile(ArrayList<Tuple> urlsList, File outFile, final int n) {
203 try (
204 Writer writer = new BufferedWriter(new FileWriter(outFile));
205 ) {
206
207 for (int i=0; i < n; i++) {
208 Tuple urlInfo = urlsList.get(i);
209
210 //System.out.println(list.get(i));
211 writer.write(urlInfo + "\n"); // calls toString() on tuple of url -> countryCode
212 }
213 } catch(Exception e) {
214 logger.error("Unable to write to file " + Utility.getFilePath(outFile));
215 logger.error(e.getMessage(), e);
216 }
217 }
218
219 /* ---------------------------------------- */
220
221 /**
222 * Create the file 5counts_tentativeNonAutotranslatedSites.json
223 * that contains the count and domains for NZ sites (NZ origin or nz TLD) that CONTAIN_MRI
224 * followed by counts and domain listing for overseas sites that are either from Australia
225 * or don't contain mi in their URL path.
226 * @return full path of file generated
227 */
228 public String writeTentativeNonAutotranslatedSites() {
229
230 File outFile = new File(outFolder, "5a_counts_tentativeNonAutotranslatedSites.json");
231
232 String filename = Utility.getFilePath(outFile);
233
234 try (
235 Writer writer = new BufferedWriter(new FileWriter(outFile));
236 ) {
237 // first write out NZ sites and .nz TLD count and domains
238 mongodbAccess.aggregateContainsMRIForNZ(writer, MongoDBAccess.CONTAINS_MRI);
239 // next write out all overseas sites (not NZ origin or .nz TLD)
240 // that have no "mi" in the URL path as mi.* or */mi
241 boolean isMiInURLPath = false;
242 mongodbAccess.aggregateContainsMRIForOverseas(writer, MongoDBAccess.CONTAINS_MRI, isMiInURLPath);
243
244 } catch(Exception e) {
245 logger.error("Unable to write to file " + filename);
246 logger.error(e.getMessage(), e);
247 }
248
249 System.err.println("*** Wrote file: " + filename);
250
251 return filename;
252 }
253
254 /**
255 * Listing of the remainder of overseas sites that CONTAIN_MRI not included by
256 * writeTentativeNonAutotranslatedSites(): those that have mi in their URL path.
257 * This listing is separate to allow easier weeding out of product sites/autotranslated
258 * sites when eyeballing the listing output.
259 */
260 public String writeOverseasSitesWithMiInURLPath() {
261 File outFile = new File(outFolder, "5b_counts_overseasSitesWithMiInPath.json");
262
263 String filename = Utility.getFilePath(outFile);
264 try (
265 Writer writer = new BufferedWriter(new FileWriter(outFile));
266 ) {
267 boolean isMiInURLPath = true;
268 mongodbAccess.aggregateContainsMRIForOverseas(writer, MongoDBAccess.CONTAINS_MRI, isMiInURLPath);
269
270 } catch(Exception e) {
271 logger.error("Unable to write to file " + filename);
272 logger.error(e.getMessage(), e);
273 }
274
275 System.err.println("*** Wrote file: " + filename);
276 return filename;
277 }
278
279 public static void printUsage() {
280 System.err.println("Usage: WebPageURLsListing [domains.txt]");
281 }
282
283 /**
284 * If no args are passed in, generates complete containsMRI file listings for NZ and overseas web SITES (domains),
285 * with overseas web sites that have mi (mi.* or *\/mi) in the URL path listed separately.
286 * You can then manually inspect the domains in this listing to shortlist which of these sites are not automatically
287 * translated and really contain at least one webpage containing at least one sentence in MRI.
288 * If a file is passed in containing a list of domains, then this first generates a full listing of all webpages
289 * matching isMRI for each site in the domain list. It then generates a smaller set of random webpages matching
290 * isMRI for the pooled sites in the domain list where the sample size of URLs produced is sufficient for giving
291 * 90% confidence with 5% margin of error for testing binary outcomes, see
292 * https://stats.stackexchange.com/questions/207584/sample-size-choice-with-binary-outcome
293 */
294 public static void main(String args[]) {
295 if(args.length >= 2) {
296 printUsage();
297 System.exit(-1);
298 }
299
300 try (
301 MongoDBAccess mongodb = new MongoDBAccess();
302 ) {
303
304 mongodb.connectToDB();
305
306 // output files will be stored in mongodb-data-auto
307 File outFolder = new File("../mongodb-data-auto/").getAbsoluteFile();
308 WebPageURLsListing listing = new WebPageURLsListing(mongodb, outFolder);
309
310 System.out.println("*************************************");
311
312
313 if(args.length >= 1) {
314 File domainsFile = new File(args[0]);
315 if(!domainsFile.exists()) {
316 System.err.println("File " + domainsFile + " does not exist");
317 System.exit(-1);
318 }
319
320 //String isMRIFile = listing.produceURLsForPagesInMRI(domainsFile);
321 //String containsMRIFile = listing.produceURLsForPagesContainingMRI(domainsFile);
322
323
324 // TODO: for NZ, do IS_MRI. For overseas still CONTAINS_MRI
325 // then also do the shuffle to gen X num of random web page URLs.
326 //String filename = listing.webPagesOfAllNZSitesAndDomainListing(domainsFile);
327 listing.mriWebPageListingForDomainListing(domainsFile);
328
329 // TODO: generate the special table (6)
330
331 } else {
332
333 // calculating sample size works:
334 //System.err.println("For N = " + 4360 + ", n = " + listing.calcSampleSize(4360));
335 //System.err.println("For N = " + 681 + ", n = " + listing.calcSampleSize(681));
336
337 String filename = listing.writeTentativeNonAutotranslatedSites();
338 filename = listing.writeOverseasSitesWithMiInURLPath();
339
340 // TODO: generate the tables
341
342 mongodb.writeTables(outFolder);
343 }
344
345 System.out.println("*************************************");
346 } catch(Exception e) {
347 logger.error(e.getMessage(), e);
348 }
349 }
350}
Note: See TracBrowser for help on using the repository browser.