<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Traindex</title>
    <description>The latest articles on DEV Community by Traindex (@traindex).</description>
    <link>https://dev.to/traindex</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2824%2F201ceca8-e10a-4133-a1bf-77dcaf7713ca.png</url>
      <title>DEV Community: Traindex</title>
      <link>https://dev.to/traindex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/traindex"/>
    <language>en</language>
    <item>
      <title>Alternatives to Google Patents</title>
      <dc:creator>Eshban Suleman</dc:creator>
      <pubDate>Sat, 20 Feb 2021 09:56:01 +0000</pubDate>
      <link>https://dev.to/traindex/alternatives-to-google-patents-4j4b</link>
      <guid>https://dev.to/traindex/alternatives-to-google-patents-4j4b</guid>
      <description>&lt;p&gt;There are multiple tools available over the internet to check the similarity of a claim or a patent. There are pros and cons of every tool and a user can sometimes have a hard time deciding what to use where. In such situations, people tend to use the services they trust. People tend to rely on big tech companies when it comes to choosing between a variety of options because they are perceived to be doing well in every area. Such is the case with Google Patents. &lt;/p&gt;

&lt;p&gt;Although Google Patents is a well all-round search engine for patent data, it does have some disadvantages. In this article, we will have a look at some of the more obvious cons of Google Patents and will also proceed to look at some other services available online. And if you are not familiar with the concepts of patent search or how to conduct a patent search, have a look at our article &lt;a href="https://www.traindex.io/blog/patent-search-4j05"&gt;Patent Search&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Some Shortfalls of Google Patents
&lt;/h1&gt;

&lt;p&gt;This article is not aimed at disregarding Google Patents as a search engine for patents, instead, the goal of this article is to get the reader familiar with some alternatives to using Google Patents. So, let’s, first of all, discuss why one might decide to not use Google Patents.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Semi Semantic Behavior
&lt;/h2&gt;

&lt;p&gt;Google Patents has been observed to show semi-semantic behavior. It is a keyword-based search at its core but it can extract some semantically similar results. Sometimes it can be useful but most of the time it searches for unrelated synonyms. Following is an example of this behavior. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BK7w6x8t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rc6ujdqejbw7ygkmmunt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BK7w6x8t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rc6ujdqejbw7ygkmmunt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not necessarily bad behavior but it does affect the results. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Bad with Acronyms
&lt;/h2&gt;

&lt;p&gt;As with all keyword-based searches, Google Patents also seem to struggle with the acronyms. The most common example of it is the acronym AIDS (Acquired Immune Deficiency Syndrome) which is often misinterpreted with the word “aids”, a verb with the meaning of “to help”. So you might get a lot of false positives if your query contains such acronyms. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tK4F2dE1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq2nsu7kebba3fcwe990.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tK4F2dE1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq2nsu7kebba3fcwe990.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Empty Results
&lt;/h2&gt;

&lt;p&gt;Google Patents shows the keyword search behavior here as well. If the keywords are very unique then it might show zero results. Semantic search engines usually shine in this department but Google Patents is not one of them. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Unable to Process Scientific Jargon
&lt;/h2&gt;

&lt;p&gt;Patents usually cover complex novel scientific inventions and thus have a lot of “science language”, but it is observed that Google Patents is usually unable to get results if queried with scientific jargon for example chemical formulas, etc. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Missing Citations
&lt;/h2&gt;

&lt;p&gt;There’s been a case of some missing patents which occurred during data transfer. Due to this, citations are missing in some of the patents.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Disclosure Risk
&lt;/h2&gt;

&lt;p&gt;Google tracks its search activity according to its &lt;a href="https://policies.google.com/privacy?hl=en"&gt;Privacy Policy&lt;/a&gt;. According to &lt;a href="https://www.uspto.gov/web/offices/pac/mpep/s904.html"&gt;MPEP 904.02(c)&lt;/a&gt; of Manual of Patent Examining Procedure by the United States Patent and Trademark Office (USPTO), examiners are allowed to use tools and the internet to search for the prior art of any claim under examination but are not allowed to use any proprietary information as query, instead, they are advised to use a general state of the art query to get similar results. Simply put, to check whether the claim under inspection is similar or identical to any published claim, you can use any service on the internet but you shouldn’t provide any information about the claim that might expose its privacy. Since Google Patents is a keyword-based search, it is difficult to come up with a query that maintains the balance of the privacy of your claims and search for any similar or identical existing claim. Thus your case might always be at risk if Google Patents is being used.&lt;/p&gt;

&lt;p&gt;I think these are more than enough reasons to try something different this time. Let’s now discuss some of the alternatives to Google Patents.&lt;/p&gt;

&lt;h1&gt;
  
  
  Patentscope
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://patentscope.wipo.int/search/en/search.jsf"&gt;Patentscope&lt;/a&gt; is a patent search service by the World Intellectual Property Organization (&lt;a href="https://www.wipo.int/portal/en/index.html"&gt;WIPO&lt;/a&gt;). You can search over 92 million patents worldwide and can also enhance your search results by filtering them using certain meta-level filters. It is a free global search engine technology information. It doesn’t employ any spelling correction technique nor does it enable to use chemical compounds as a query on the open version. Also, it strictly searches for words in the query and not their other forms, so no lemmatization is observed. It also returns zero results if even one word in the query is out of its vocabulary. &lt;/p&gt;

&lt;h1&gt;
  
  
  Escapenet
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://worldwide.espacenet.com/"&gt;Escapenet&lt;/a&gt; by European Patent Office (EPO) is also a keyword-based patent search on over 120 million patents. It has all the characteristics of keyword search such as advanced search features and metadata-based filters. Unlike Patentscope, it uses lemmatization to get different word forms too and supports multiple European languages. The base search only allows up to 10 keywords.&lt;/p&gt;

&lt;h1&gt;
  
  
  lens.org
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.lens.org/"&gt;lens.org&lt;/a&gt; provides search services for different scholarly datasets including patent data of 125.4 million patent records. It has very fine-grained advanced search filters and has patents from all around the world. It uses Apache Lucene and Elasticsearch for text search and shows a semi-semantic behavior. It also supports spelling correction and handles acronyms better than the previous two options. Still, it doesn’t search for chemical compounds, etc, and is susceptible to return empty results. &lt;/p&gt;

&lt;h1&gt;
  
  
  Traindex
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.traindex.io/"&gt;Traindex&lt;/a&gt; is a semantic search engine, unlike others in this list. It uses Machine Learning to find patents that are semantically similar to the query. It searches over Google Public Patents Data and can be integrated very easily into your applications. It can accept texts of various lengths, you can enter whole patent documents and it will handle that easily. Since it is a semantic search engine, it outstands in retrieving desired results for even a very unique set of queries. One of the things that make it stand out is that it doesn’t track search data and lets you use their API safely. Does this look like something you want to know more about? How about you schedule a demo &lt;a href="https://www.traindex.io/"&gt;here&lt;/a&gt; and we will walk you through the process. &lt;/p&gt;

&lt;p&gt;The goal of this article was to point out some areas where Google Patents falls short and to provide you with some alternative resources so you can use the right tool for your problems, without compromising privacy and security. If you’re still confused, you can reach us at &lt;a href="mailto:help@traindex.io"&gt;help@traindex.io&lt;/a&gt; and we would be happy to guide you more.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Machine learning possible with small data?</title>
      <dc:creator>Danial Ranjha</dc:creator>
      <pubDate>Tue, 02 Feb 2021 22:44:14 +0000</pubDate>
      <link>https://dev.to/traindex/machine-learning-possible-with-small-data-5cd5</link>
      <guid>https://dev.to/traindex/machine-learning-possible-with-small-data-5cd5</guid>
      <description>&lt;p&gt;It's not worth trying machine learning projects unless you have a huge data set.&lt;/p&gt;

&lt;p&gt;True or false?&lt;/p&gt;

&lt;p&gt;Smaller companies are afraid to add machine learning features to their projects unless they have big data. They think that since they're not Amazon or Microsoft, they don't have a large enough data set to be successful in taking on machine learning projects or features.&lt;/p&gt;

&lt;p&gt;There are definitely applications of machine learning that can work even on small data sets. Perhaps you can start small and prove out a concept, before investing in getting more data to build a larger model. You can also use off-the-shelf models in AWS, Azure, and GCP to solve generic problems.&lt;/p&gt;

&lt;p&gt;With smaller data sets you will encounter problems that you need to be weary of, such as over fitting, bias, and data imbalance. With the right tools and people, there are strategies to overcome these problems.&lt;/p&gt;

&lt;p&gt;Like any good project management program, you can invest in small wins to either prove out the concept. This can help you gain credibility in a new program, and then getting funding for bigger and bolder bets.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>startup</category>
    </item>
    <item>
      <title>Multipart Upload for Large Files using Pre-Signed URLs - AWS</title>
      <dc:creator>Syed Afroz Pasha</dc:creator>
      <pubDate>Tue, 15 Dec 2020 21:32:13 +0000</pubDate>
      <link>https://dev.to/traindex/multipart-upload-for-large-files-using-pre-signed-urls-aws-4hg4</link>
      <guid>https://dev.to/traindex/multipart-upload-for-large-files-using-pre-signed-urls-aws-4hg4</guid>
      <description>&lt;p&gt;It’s mind-blowing how fast data is growing. It is now possible to collect raw data with a frequency of more than a million requests per second. Storage is quicker and cheaper. It is normal to store data practically forever, even if it is rarely accessed.&lt;/p&gt;

&lt;p&gt;Users of &lt;a href="https://traindex.io/" rel="noopener noreferrer"&gt;Traindex&lt;/a&gt; can upload large data files to create a semantic search index. This article will explain how we implemented the multipart upload feature that allows Traindex users to upload large files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problems and their Solutions
&lt;/h3&gt;

&lt;p&gt;We wanted to allow users of Traindex to upload large files, typically 1-2 TB, to Amazon S3 in minimum time and with appropriate access controls. &lt;/p&gt;

&lt;p&gt;In this article, I will discuss how to set up pre-signed URLs for the secure upload of files. This allows us to grant temporary access to objects in AWS S3 buckets without needing permission.&lt;/p&gt;

&lt;p&gt;So how do you go from a 5GB limit to a 5TB limit in uploading to AWS S3? Using multipart uploads, AWS S3 allows users to upload files partitioned into 10,000 parts. The size of each part may vary from 5MB to 5GB.&lt;/p&gt;

&lt;p&gt;The table below shows the upload service limits for S3.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmc21sba4zou7dcdratzf.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmc21sba4zou7dcdratzf.PNG" alt="Capture" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apart from the size limitations, it is better to keep S3 buckets private and only grant public access when required. We wanted to give the client access to an object without changing the bucket ACL, creating roles, or creating a user on our account. We ended up using S3 pre-signed URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  What will you learn?
&lt;/h3&gt;

&lt;p&gt;For a standard multipart upload to work with pre-signed URLs, we need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initiate a multipart upload&lt;/li&gt;
&lt;li&gt;Create pre-signed URLs for each part&lt;/li&gt;
&lt;li&gt;Upload the parts of the object&lt;/li&gt;
&lt;li&gt;Complete multipart upload&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You have to make sure that you have configured your command-line environment not to require the credentials at the time of operations. Steps 1, 2, and 4 stated above are server-side stages. They will need an AWS access keyID and secret key ID. Step 3 is a client-side operation for which the pre-signed URLs are being set up, and hence no credentials will be needed.&lt;/p&gt;

&lt;p&gt;If you have not configured your environment to perform server-side operations, then you must complete it first by following these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download AWS-CLI from this &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;link&lt;/a&gt; according to your OS and install it. To configure your AWS-CLI, you need to use the command &lt;strong&gt;aws configure&lt;/strong&gt; and provide the details it requires, as shown below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws configure

AWS Access Key ID &lt;span class="o"&gt;[&lt;/span&gt;None]: EXAMPLEFODNN7EXAMPLE
AWS Secret Access Key &lt;span class="o"&gt;[&lt;/span&gt;None]: eXaMPlEtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name &lt;span class="o"&gt;[&lt;/span&gt;None]: xx-xxxx-x
Default output format &lt;span class="o"&gt;[&lt;/span&gt;None]: json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Initiate a Multipart Upload
&lt;/h4&gt;

&lt;p&gt;At this stage, we request AWS S3 to initiate a multipart upload. In response, we will get the &lt;strong&gt;UploadId&lt;/strong&gt;, which will associate each part to the object they are creating.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[XYZ]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[ABC.pqr]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_multipart_upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;upload_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;UploadId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing this chunk of code after setting up the bucket name and key, we get the UploadID for the file we want to upload. After setting up the bucket name and key, we get the UploadID for the file that needs to be uploaded. It will later be required to combine all parts.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create pre-signed URLs for each part
&lt;/h4&gt;

&lt;p&gt;The parts can now be uploaded via a PUT request. As explained earlier, we are using a pre-signed URL to provide a secure way to upload and grant access to an object without changing the bucket ACL, creating roles, or providing a user on your account. The permitted user can generate the URL for each part of the file and access the S3. The following line of code can generate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;signed_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_presigned_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ClientMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;upload_part&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bucket&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;UploadId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;upload_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PartNumber&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;part_no&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As described above, this particular step is a server-side stage and hence demands a preconfigured AWS environment. The pre-signed URLs for each of the parts can now be handed over to the client. They can simply upload the individual parts without direct access to the S3. It means that the service provider does not have to worry about the ACL and change in permission anymore.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Upload the parts of the object
&lt;/h4&gt;

&lt;p&gt;This step is the only client-side stage of the process. The default pre-signed URL expiration time is 15 minutes, while the one who is generating it can change the value. Usually, it is kept as minimal as possible for security reasons.&lt;/p&gt;

&lt;p&gt;The client can read the part of the object, i.e., &lt;em&gt;file_data&lt;/em&gt;, and request to upload the chunk of the data concerning the part number. It is essential to use the pre-signed URLs in sequence as the part number, and the data chunks must be in sequence; otherwise,  the object might break, and the upload ends up with a corrupted file. For that reason, a dictionary, i.e., &lt;strong&gt;parts&lt;/strong&gt;, must be managed to store the unique identifier, i.e., &lt;strong&gt;eTag&lt;/strong&gt; of every part concerning the part number. A dictionary must be a manager to keep the unique identifier or eTag of every part of the number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signed_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;file_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ETag&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  

&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ETag&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PartNumber&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;part_no&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As far as the size of data is concerned, each chunk can be declared into bytes or calculated by dividing the object’s &lt;strong&gt;total size&lt;/strong&gt; by the &lt;strong&gt;no. of parts&lt;/strong&gt;. Look at the example code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;max_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;    &lt;span class="c1"&gt;# Approach 1: Assign the size  
&lt;/span&gt;
&lt;span class="n"&gt;max_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;object_size&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;no_of_parts&lt;/span&gt;    &lt;span class="c1"&gt;# Approach 2: Calculate the size 
&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileLocation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;file_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Complete Multipart Upload
&lt;/h4&gt;

&lt;p&gt;Before this step, check the data’s chunks and the details uploaded to the bucket. Now, we need to merge all the partial files into one. The dictionary parts (about which we discussed in step 3) will be passed as an argument to keep the chunks with their part numbers and eTags to avoid the object from corrupting.&lt;/p&gt;

&lt;p&gt;You can refer to the code below to complete the multipart uploading process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete_multipart_upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;MultipartUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Parts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;UploadId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;upload_id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Additional step
&lt;/h4&gt;

&lt;p&gt;To avoid any extra charges and cleanup, your S3 bucket and the S3 module stop the multipart upload on request. In case anything seems suspicious and one wants to abort the process, they can use the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort_multipart_upload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;UploadId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;upload_id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this article, we discussed the process of implementing the process of multipart uploading in a secure way pre-signed URLs. The suggested solution is to make a &lt;a href="https://www.traindex.io/blog/cli-upload-for-large-files-6i" rel="noopener noreferrer"&gt;CLI tool to upload large files&lt;/a&gt; which saves time and resources and provides flexibility to the users.  It is a cheap and efficient solution for users who need to do this frequently.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>multipart</category>
      <category>presignedurls</category>
      <category>amazons3</category>
    </item>
    <item>
      <title>CLI upload for large files</title>
      <dc:creator>Mohsin Ashraf</dc:creator>
      <pubDate>Mon, 14 Dec 2020 23:08:21 +0000</pubDate>
      <link>https://dev.to/traindex/cli-upload-for-large-files-6i</link>
      <guid>https://dev.to/traindex/cli-upload-for-large-files-6i</guid>
      <description>&lt;p&gt;We deal with data every day as part of my work in the data science team. It starts by collecting data and analyzing it for potentially important features and baseline numbers. Then we do data preprocessing and cleaning. Finally, we feed the data into a machine learning algorithm for training.&lt;/p&gt;

&lt;p&gt;Once the training is complete, we test the model. We then serve via an API if the performance is good.&lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://www.traindex.io/blog/"&gt;previous article&lt;/a&gt;, we talked about uploading large files using multipart upload via pre-signed URLs. We will take a step further now and discuss how to create a CLI tool for uploading large files to S3 using pre-signed URLs.&lt;/p&gt;

&lt;p&gt;The article comprises 3 parts, as described below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create pre-signed URLs for multipart upload&lt;/li&gt;
&lt;li&gt;Upload all parts of the object&lt;/li&gt;
&lt;li&gt;Complete the upload&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Request for Multipart upload pre-signed URLs
&lt;/h1&gt;

&lt;p&gt;First of all, we have to request the pre-signed URLs to the AWS S3 bucket. It will return a list of pre-signed URLs corresponding with each of the object’s parts, along with a upload_id, which is associated with the object whose parts are being created. Let’s create the route for requesting pre-signed URLs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from pathlib import Path
…
…

@app.route('/presigned',methods=['POST'])
def return_presigned():
    data = request.form.to_dict(flat=False)
    file_name = data['file_name'][0]
    file_size = int(data['file_size'][0])
    target_file = Path(file_name)
    max_size = 5 * 1024 * 1024
    upload_by = int(file_size / max_size) + 1
    bucket_name = "YOUR_BUCKET_NAME"
    key = file_name
    upload_id = s3util.start(bucket_name, key)
    urls = []
    for part in range(1, upload_by + 1):
           signed_url = s3util.create_presigned_url(part)
             urls.append(signed_url)
    return jsonify({
                     'bucket_name':bucket_name,
                     'key':key,
                     'upload_id':upload_id,
                'file_size:file_size,
                   'file_name':file_name,
                'max_size':max_size,
                     'upload_by':upload_by,
                'urls':urls
            })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go through the code. In this route (Flask route), we get the information sent in the request: file_name and file_size.&lt;br&gt;
The file_name will be used in creating URLs for parts of the object, and file_size will be used to find how many parts to create (pre-signed URLs to create).&lt;br&gt;
In the route, max_size determines each part’s maximum size. You can change it according to your needs.&lt;br&gt;
upload_by tells how many parts there will be for the object to upload.&lt;br&gt;
bucket_name is the bucket you want to upload data in.&lt;br&gt;
upload_id is generated using the S3 utility function create_multipart_upload, which we will discuss shortly.&lt;br&gt;
After that, pre-signed URLs are created in the for loop using the create_presigned_url utility function of s3. Again, we will come back to it in a bit.&lt;br&gt;
Next, I return the required data in JSON format.&lt;/p&gt;

&lt;p&gt;Now, let’s talk about create_multipart_upload. It’s a utility function that helps me encapsulate the code so it’s more readable and manageable. Following is the code for the utility class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3
from botocore.exceptions import ClientError
from boto3 import Session


class S3MultipartUploadUtil:
    """
    AWS S3 Multipart Upload Uril
    """
    def __init__(self, session: Session):
        self.session = session
        self.s3 = session.client('s3')
        self.upload_id = None
        self.bucket_name = None
        self.key = None

    def start(self, bucket_name: str, key: str):
        """
        Start Multipart Upload
        :param bucket_name:
        :param key:
        :return:
        """
        self.bucket_name = bucket_name
        self.key = key
        res = self.s3.create_multipart_upload(Bucket=bucket_name, Key=key)
        self.upload_id = res['UploadId']
        logger.debug(f"Start multipart upload '{self.upload_id}'")
        return self.upload_id

    def create_presigned_url(self, part_no: int, expire: int=3600) -&amp;gt; str:
        """
        Create pre-signed URL for upload part.
        :param part_no:
        :param expire:
        :return:
        """
        signed_url = self.s3.generate_presigned_url(
            ClientMethod='upload_part',
            Params={'Bucket': self.bucket_name,
                    'Key': self.key,
                    'UploadId': self.upload_id,
                    'PartNumber': part_no},
            ExpiresIn=expire)
        logger.debug(f"Create presigned url for upload part '{signed_url}'")
        return signed_url

    def complete(self, parts,id,key,bucket_name):
        """
        Complete Multipart Uploading.
        `parts` is list of dictionary below.
        ```


        [ {'ETag': etag, 'PartNumber': 1}, {'ETag': etag, 'PartNumber': 2}, ... ]


        ```
        you can get `ETag` from upload part response header.
        :param parts: Sent part info.
        :return:
        """
        res = self.s3.complete_multipart_upload(
            Bucket=bucket_name,
            Key=key,
            MultipartUpload={
                'Parts': parts
            },
            UploadId=id
        )
        logger.debug(f"Complete multipart upload '{self.upload_id}'")
        logger.debug(res)
        self.upload_id = None
        self.bucket_name = None
        self.key = None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this class, I wrap the functionality of the S3 client to make it easy to use and less cluttered in the API file.&lt;/p&gt;

&lt;p&gt;Once you get the response from the API, it would look something like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LtRb_uwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z7v7suf92k708na4wyzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LtRb_uwx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z7v7suf92k708na4wyzd.png" alt="Code Snippet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You would download this response in a JSON file to upload the data using the CLI. &lt;/p&gt;
&lt;h1&gt;
  
  
  Upload all parts of the object
&lt;/h1&gt;

&lt;p&gt;Now let’s turn to the CLI code, which uses this JSON file, and we assume that we save this file as presigned.json.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests
import progressbar
from pathlib import Path

def main():
    data = eval(open('presigned.json').read())
    upload_by = data['upload_by']
    max_size = data['max_size']
    urls = data['urls']
    target_file = Path(data['file_name'])
    file_size = data['file_size']
    key = data['key']
    upload_id = data['upload_id']
    bucket_name = data['bucket_name']
    bar = progressbar.ProgressBar(maxval=file_size, \
        widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
    json_object = dict()
    parts = []
    file_size_counter = 0
    with target_file.open('rb') as fin:
        bar.start()
        for num, url in enumerate(urls):
            part = num + 1
            file_data = fin.read(max_size)
            file_size_counter += len(file_data)
            res = requests.put(url, data=file_data)

            if res.status_code != 200:
                print (res.status_code)
                print ("Error while uploading your data.")
                return None
            bar.update(file_size_counter)
            etag = res.headers['ETag']
            parts.append((etag, part))
        bar.finish()
        json_object['parts'] = [
            {"ETag": eval(x), 'PartNumber': int(y)} for x, y in parts]
        json_object['upload_id'] = upload_id
        json_object['key'] = key
        json_object['bucket_name'] = bucket_name
    requests.post('https://YOUR_HOSTED_API/combine, json={'parts': json_object})
    print ("Dataset is uploaded successfully")

if __name__ == "__main__":
    main()    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code loads the file and gets all the required information, including upload_id, URLs, and others. I use Progressbar to show progress while uploading the file. The entire code is pretty much self-explanatory except for the following line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;requests.post('https://YOUR_HOSTED_API/combine, json={'parts': json_object})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand this piece of code, we have to look at the final step of completing the upload.&lt;/p&gt;

&lt;h1&gt;
  
  
  Complete the upload
&lt;/h1&gt;

&lt;p&gt;We have uploaded all parts of the file, but these parts are not yet combined. To combine them we need to tell the s3 that we have finished uploading and that now you can combine the parts. The above request calls the route in the table below and completes the multipart upload using the s3 utility class. It provides the proper information about the file and the upload_id, which tells s3 about the parts of the same file being uploaded using the upload_id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route("/combine",methods=["POST"])
def combine():
    body = request.form
    body = body['parts']    
    session = Session()
    s3util = Presigned(session)
    parts = body['parts']
    id, key, bucket_name = body['upload_id'], body['key'], body['bucket_name']
    PARTS = [{"Etag": eval(x), 'PartNumber': int(y)} for x, y in parts]
    s3util.complete(PARTS, id, key, bucket_name)
    return Response(status_code=200)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is a very minimum required code to create a CLI tool. You can deploy it on a server, which has proper roles in AWS for interacting with S3, to create and return the pre-signed URLs for completing the multipart upload. This way, you can make sure that no one has direct access to your S3 bucket. Instead, they upload the data using pre-signed URLs, which is a secure way of uploading the data.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>upload</category>
      <category>large</category>
      <category>file</category>
    </item>
    <item>
      <title>Google Patent Search</title>
      <dc:creator>Nada Gul</dc:creator>
      <pubDate>Thu, 03 Dec 2020 07:19:31 +0000</pubDate>
      <link>https://dev.to/traindex/google-patent-search-2fgf</link>
      <guid>https://dev.to/traindex/google-patent-search-2fgf</guid>
      <description>&lt;p&gt;A patent search is a tool to check the patentability of your invention. You can find out if someone else has already come up with the same idea. And if there is a patent similar to your invention, your patent application won’t be accepted. All the hard work, time, and money you invested in the invention will go to waste. It is important that you do a thorough patent search before proceeding with your invention.&lt;/p&gt;

&lt;p&gt;There are many options to pick from when searching for patents. In this article, we will talk about Google Patent Search in detail. Google Patent Search engine is free and has an easy-to-use interface. The Google search engine is quite fast, as opposed to the United States Patent and Trademark Office’s &lt;a href="https://www.uspto.gov/" rel="noopener noreferrer"&gt;online library&lt;/a&gt;. Google Patents also provides information on legal events for patents.&lt;br&gt;
How to search on Google Patents&lt;/p&gt;

&lt;p&gt;Google Patents has two search interfaces. A simple search interface and an advanced search interface. As the name suggests, the simple search interface is quite simple to use and very similar to the regular Google search engine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffjz1rzx85m8woymv9wfy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffjz1rzx85m8woymv9wfy.png" alt="Google Patents simple search interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may enter your query in the search bar on the main search page, a publication number of a particular patent you’re looking for, or an application number. When I entered “chemical reaction” in the search bar, I got 135,160 results in just 3 seconds. That’s fairly quick. &lt;/p&gt;

&lt;p&gt;In the advanced search interface, you can use boolean syntax to search for patents. You can also search for patent publications using Cooperative Patent Classifications (CPCs) that represent ideas instead of keywords.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2ev8k7r5j6a08u0pf3ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2ev8k7r5j6a08u0pf3ln.png" alt="Google Patents advanced search interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The AND operator is used to include all words entered in the search bar to be present in search results. The OR operator is used for at least one of the words to be present in search results. When entering terms, it is important to note that all terms are automatically ANDed together, and synonyms are ORed. You can add a synonym by pressing TAB and a new search term by pressing ENTER. You can also use proximity operators NEAR, WITH, SAME, AJD.&lt;/p&gt;

&lt;p&gt;On the Advanced Search page and under Search Fields, there’s an option to search for patents using particular fields. You can select before or after the filing date and choose either priority, filing, or publication for the date or date range you entered. There’s an option to search using an inventor and/or assignee. This option helps users look for patent documents by a particular inventor or patents filed by a specific person or company.&lt;/p&gt;

&lt;p&gt;The last box on the advanced search page includes the patent office, in case you want to search for patent documents by country. The next option is the language. You can choose to specify status: grant or application, and type: patent or design. The last option is litigation, where you can choose one of the two options: “has related litigation” or “no known litigation”.&lt;/p&gt;

&lt;p&gt;Specifying the patent search using the search field options narrows the search results to the most relevant patent publications you are looking for. It helps to make your patent search experience more efficient.&lt;/p&gt;

&lt;p&gt;Patent searching is an essential part of your patent process. You can also learn about recent inventions, the development of particular technologies or patents of famous academics. Google Patent search is a user-friendly patent search engine that makes the complex process of patent searching less tedious. It’s free and fast.&lt;/p&gt;

&lt;p&gt;If you want to learn about other avenues for patent searching, check our article on Patent Search &lt;a href="https://www.traindex.io/blog/patent-search-4j05" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>patents</category>
      <category>patentsearch</category>
      <category>googlepatents</category>
      <category>tips</category>
    </item>
    <item>
      <title>Event Driven Data Pipelines in AWS</title>
      <dc:creator>Eshban Suleman</dc:creator>
      <pubDate>Mon, 30 Nov 2020 17:52:07 +0000</pubDate>
      <link>https://dev.to/traindex/event-driven-data-pipelines-in-aws-480i</link>
      <guid>https://dev.to/traindex/event-driven-data-pipelines-in-aws-480i</guid>
      <description>&lt;p&gt;In a data-driven organization, there is a constant need to provide vast amounts of data to the teams. There are many tools available to aid your requirements and needs. Choosing the right tool can be a little challenging and overwhelming at times. The basic principle you can keep in mind is that there is no right tool or architecture, it depends on what you need. &lt;/p&gt;

&lt;p&gt;In this guide, I’m going to show you how to build a simple event-driven data pipeline in AWS. Pipelines are often scheduled or interval based, however, the event-driven concept is unique and a good starting point. Instead of trying to figure out the right intervals of the pipeline activation, you can use an event handler to deal with certain events to activate your pipeline. &lt;/p&gt;

&lt;p&gt;To learn more about which problem we were solving in Traindex and why the data pipeline was the right choice for us, refer to my previous article &lt;a href="https://www.traindex.io/blog/introduction-to-data-pipelines-26o7" rel="noopener noreferrer"&gt;Introduction to Data Pipelines&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;As an example, we would be using the “Sentiment140 dataset with 1.6 million tweets” which is available on Kaggle. Our goal would be to set up a data preprocessing pipeline. Once you have uploaded the CSV file in a specified bucket, an event is generated. A lambda function would handle that event and will activate your pipeline. Your data pipeline would be AWS Data Pipeline which is a web service that helps you process and move data between different AWS compute and storage services. This pipeline would divide a compute resource and run your preprocessing code in that resource. Once your data is cleaned and preprocessed, it will upload it to the specified bucket for later use. Based on these objectives, we can divide our task into the following sub-tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a pre-configured AMI&lt;/li&gt;
&lt;li&gt;Defining AWS data pipeline architecture&lt;/li&gt;
&lt;li&gt;Writing the event handler AWS Lambda function&lt;/li&gt;
&lt;li&gt;Integrating everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before diving into the steps, make sure you have the following preconditions met&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You require an AWS account with certain IAM privileges&lt;/li&gt;
&lt;li&gt;Make sure you have already downloaded the data from “Sentiment140 dataset with 1.6 million tweets”&lt;/li&gt;
&lt;li&gt;Active internet connection&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Pre-Configured AMI
&lt;/h1&gt;

&lt;p&gt;This step can be optional based on your requirements but it is good to have a pre-configured AMI that you can use in the compute resources. Follow the following steps to create a pre-configured AMI: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the AWS console, click on the Services dropdown menu, and select EC2&lt;/li&gt;
&lt;li&gt;On the EC2 dashboard, select Launch an Instance&lt;/li&gt;
&lt;li&gt;Select the Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type - ami-01fee56b22f308154 &lt;/li&gt;
&lt;li&gt;Select the General Purpose t2.micro which is free-tier eligible&lt;/li&gt;
&lt;li&gt;Click on Review and Launch and then click Launch to launch this EC2 instance&lt;/li&gt;
&lt;li&gt;Now go to the EC2 dashboard and select your EC2 Instance. Copy the public DNS and SSH into your created instance. &lt;/li&gt;
&lt;li&gt;Now, install all the required packages, tools, and libraries in it using standard Linux commands.&lt;/li&gt;
&lt;li&gt;Also, set up any credentials you might require later like AWS credentials, etc.&lt;/li&gt;
&lt;li&gt;Once satisfied with your instance, it’s time to create an AMI image from this instance.&lt;/li&gt;
&lt;li&gt;Go to EC2 dashboard, right-click on your instance. Click on Actions, select Image, and click on create an image.&lt;/li&gt;
&lt;li&gt;Keep the default settings and create the image by clicking on Create Image.&lt;/li&gt;
&lt;li&gt;It’ll take a couple of minutes and once it’s done, go ahead and terminate the instance you created. You will only need the AMI ID in the next phases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  AWS Data Pipeline Architecture
&lt;/h1&gt;

&lt;p&gt;The main idea behind this step is to set up a data pipeline which upon certain triggers, launches an EC2 instance. And then we will have a bash script run in that instance that would be responsible to move our raw data back and forth and run our preprocessing python script. This step can be further divided into 3 main subsections, let’s do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Data Pipeline Architecture Definition
&lt;/h2&gt;

&lt;p&gt;First of all, let’s define the AWS data pipeline architecture. We can do so by writing a JSON file that defines and describes our data pipeline and provides it with all the required logic. I’ll try to break it down as much as required but you can always refer to the documentation to explore more options. The data pipeline definition can have different pieces of information like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Names, locations, and formats of your data sources&lt;/li&gt;
&lt;li&gt;Activities that transform the data&lt;/li&gt;
&lt;li&gt;The schedule for those activities&lt;/li&gt;
&lt;li&gt;Resources that run your activities and preconditions&lt;/li&gt;
&lt;li&gt;Preconditions that must be satisfied before the activities can be scheduled&lt;/li&gt;
&lt;li&gt;Ways to alert you with status updates as pipeline execution proceeds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can express the data pipeline definition in three parts: Objects, parameters and values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objects
&lt;/h3&gt;

&lt;p&gt;Below you can see the syntax of the definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"objects"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"name1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"name2"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value2"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"name1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"name3"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="nl"&gt;"name4"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value5"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following the above syntax we can place our required objects one by one. First of all, we need to define our pipeline object. We would be defining fields like ID, name, IAM and resource roles, path to save pipeline logs and schedule type. You can add or remove these fields based on your requirements and should look at the official documentation to know more about these and other fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"failureAndRerunMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CASCADE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"resourceRole"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DataPipelineDefaultResourceRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DataPipelineDefaultRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"pipelineLogUri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3://automated-data-pipeline/logs/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"scheduleType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ONDEMAND
    },

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this object with one change, that is the &lt;code&gt;pipelineLogUri&lt;/code&gt; field. You can give the path to the S3 bucket you want to save your logs in. The next object in our definition is the compute i.e. EC2 resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyEC2Resource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ec2Resource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"imageId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ami-xxxxxxxxxxxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"instanceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"r5.large"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"spotBidPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"terminateAfter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30 Minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"actionOnTaskFailure"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"terminate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"maximumRetries"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DataPipelineDefaultRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"resourceRole"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DataPipelineDefaultResourceRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"keyPair"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;YOUR-KEY&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have described our compute needs in this object, for example, we need an EC2 instance of type r5.large on spot pricing with your key. Also, remember to put in the pre-configured AMI ID in the &lt;code&gt;imageId&lt;/code&gt; field so it launches the instance with all of the configurations set in place. Now, let’s move on to the next and last object which is the shell activity. This object would be able to run our shell script which in turn would run our preprocessing code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ShellCommandActivityObj"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ShellCommandActivityObj"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ShellCommandActivity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aws s3 cp s3://automated-data-pipeline/script.sh ~/ &amp;amp;&amp;amp; sudo sh ~/script.sh #{myS3DataPath}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"maximumRetries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"runsOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MyEC2Resource"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this object, the two most important fields are &lt;code&gt;command&lt;/code&gt; and &lt;code&gt;runsOn&lt;/code&gt;. In the &lt;code&gt;command&lt;/code&gt; field you would define the bash command that you would like to run on the EC2 instance described earlier. I described a command that will copy a bash script into the EC2 instance and run it. Note that I’m also giving it a parameter &lt;code&gt;#{myS3DataPath}&lt;/code&gt;, it is the path we would like our pipeline to preprocess. It is given as a parameter to add flexibility to our pipeline so it can handle different data sets. The &lt;code&gt;runsOn&lt;/code&gt; field takes the ID of the EC2 resource we created earlier so it can run the shell command on that resource.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;Parameters place holders should be written in this format &lt;code&gt;#{myPlaceholder}&lt;/code&gt;. Every parameter should start with the "my" suffix. Here is the parameter section of the definition JSON file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"myS3DataPath"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mys3DataPath"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This is the path to the data uploaded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::S3::ObjectKey"&lt;/span&gt;&lt;span class="w"&gt;

        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have defined that our parameter should be AWS S3 object key type. The whole data pipeline definition can be found &lt;a href="https://github.com/EshbanTheLearner/preprocessing-pipeline-demo/blob/main/definition.json" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Now, after you are done with defining your pipeline, activate it by the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datapipeline create-pipeline &lt;span class="nt"&gt;--name&lt;/span&gt; data-preprocessing-pipeline &lt;span class="nt"&gt;--unique-id&lt;/span&gt; data-preprocessing-pipeline

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once created, you can put the definition in place. Note that we can pass a temporary parameter value at this stage, which later can be passed dynamically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws datapipeline put-definition &lt;span class="nt"&gt;--pipeline-definition&lt;/span&gt; file://definition.json &lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="nt"&gt;--parameter-values&lt;/span&gt; &lt;span class="nv"&gt;s3DataPath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;s3://your/s3/data/path&amp;gt; &lt;span class="nt"&gt;--pipeline-id&lt;/span&gt; &amp;lt;Your Pipeline ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since our data pipeline is defined and created, let’s write the bash script that will run in the compute resource of our data pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bash Script
&lt;/h2&gt;

&lt;p&gt;This script will run on the EC2 instance that the pipeline would launch as its compute resource. The working of this script is simple, it makes a new working directory, sets the current working directory and path to data in S3 bucket as environment variables, copies the data into the current working directory, runs the python script and finally uploads the cleaned data back to S3. Here is the code you will need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"Starting the process"&lt;/span&gt;

&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; ~/data-pipeline-tmp
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;ugo+rwx ~/data-pipeline-tmp
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/data-pipeline-tmp

&lt;span class="nv"&gt;CURRENT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"pwd"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;DATA_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WORKING_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$CURRENT_DIR&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;S3_DATA_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$DATA_PATH&lt;/span&gt;

aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;s3://automated-data-pipeline/scripts/script.py &lt;span class="nv"&gt;$WORKING_DIR&lt;/span&gt;

python3 &lt;span class="nv"&gt;$WORKING_DIR&lt;/span&gt;/script.py

aws s3 &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$WORKING_DIR&lt;/span&gt;/twitter_data_cleaned.csv s3://automated-data-pipeline/outputs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, the S3 bucket is named &lt;code&gt;automated-data-pipeline&lt;/code&gt; and I have made folders to separate different objects. This code can also be found &lt;a href="https://github.com/EshbanTheLearner/preprocessing-pipeline-demo/blob/main/script.sh" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Next is the python code that will preprocess the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Code
&lt;/h2&gt;

&lt;p&gt;This code is the standard preprocessing code that we will use to clean our datasets. Here’s the code that you would need. Changes can be made, add or remove anything according to your needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;nltk&lt;/span&gt;
&lt;span class="n"&gt;nltk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stopwords&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;nltk.corpus&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stopwords&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;nltk.stem&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SnowballStemmer&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S3_DATA_PATH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Inside Python Script&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Path = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Loading Data&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISO-8859-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flag&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tweet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Data has &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; rows and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; columns&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;TEXT_CLEANING_RE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@\S+|https?:\S+|http?:\S|[^A-Za-z0-9]+&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;stop_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stopwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;english&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stemmer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SnowballStemmer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;english&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Remove link, user and special characters
&lt;/span&gt;    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TEXT_CLEANING_RE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stop_words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stemmer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Starting cleaning process&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;preprocess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Data cleaning completed, saving to CSV!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;twitter_data_cleaned.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also find this code &lt;a href="https://github.com/EshbanTheLearner/preprocessing-pipeline-demo/blob/main/script.py" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You have successfully defined and created a working data pipeline that can work on its (with manual activation). To add the event-driven label to it, we need to write a cloud function that will act as a trigger. It will handle certain events and then activate our pipeline when required.&lt;/p&gt;

&lt;h1&gt;
  
  
  Event Handler AWS Lambda Function
&lt;/h1&gt;

&lt;p&gt;The title says that we will be using the AWS Lambda function for this step but I like to use Chalice for this step. You can use either as per your preference, the code will almost be the same. Following are the steps to create the chalice app that runs on AWS Lambda which triggers the data pipeline. You will need the ID of the pipeline you created earlier in this step.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a chalice app using chalice &lt;code&gt;new-project &amp;lt;NAME&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Once the project is initialized, open &lt;code&gt;app.py&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Copy the contents of the following snippet into it. Code also available &lt;a href="https://github.com/EshbanTheLearner/preprocessing-pipeline-demo/blob/main/app.py" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;chalice&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Chalice&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Chalice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;pipeline-trigger&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;datapipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# The pipeline you want to activate
&lt;/span&gt;&lt;span class="n"&gt;PIPELINE_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;df-xxxxxxxxxxxxxxxxxxxx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@app.on_s3_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;automated-data-pipeline&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3:ObjectCreated:*&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;preprocess/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;activate_pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Received event for bucket: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, key: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;activate_pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;pipelineId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PIPELINE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;parameterValues&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myS3DataPath&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stringValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Change the arguments like &lt;code&gt;pipeline-id&lt;/code&gt;, path to s3 bucket etc&lt;/li&gt;
&lt;li&gt;Once done, deploy the chalice app using &lt;code&gt;chalice deploy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If deployed successfully, go to the AWS console -&amp;gt; Lambda&lt;/li&gt;
&lt;li&gt;Select your lambda function, go the Permissions tab&lt;/li&gt;
&lt;li&gt;Click on the name of Execution Role and it will open the IAM policy for the particular lambda function&lt;/li&gt;
&lt;li&gt;Under the Permissions tab, click on the policy name to expand&lt;/li&gt;
&lt;li&gt;Make sure that the policy has &lt;code&gt;iam:PassRole&lt;/code&gt; and proper data pipeline permission&lt;/li&gt;
&lt;li&gt;To make the life easier, following is the IAM policy that works fine
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VisualEditor0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"iam:PassRole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"datapipeline:*"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VisualEditor1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"logs:CreateLogStream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"logs:CreateLogGroup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"logs:PutLogEvents"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:*:logs:*:*:*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Testing
&lt;/h1&gt;

&lt;p&gt;To test this pipeline, you need to upload the dataset to the S3 bucket path you specified in the trigger function. In my case the path is &lt;code&gt;s3://automated-data-pipeline/preprocess/&lt;/code&gt;. This allows me to use the following command in my PC terminal to simply upload the data, sit back and wait for the output into the S3 path I specified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp&lt;/span&gt; ~/training.1600000.processed.noemoticon.csv s3://automated-data-pipeline/preprocess/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the pipeline has run its course, it will automatically delete the resources attached to it so you don’t incur any unwanted bills. It will upload the data to your specified path, ready to be used. Now let’s observe a before and after state of the data. Following is what the data looked in its raw form:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvw2zzx4w6onxialcdgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvw2zzx4w6onxialcdgf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what the data looks like after going through the pipeline once:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr9g340jgelv3mgwfp5q5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr9g340jgelv3mgwfp5q5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can clearly observe the difference, you can also find these notebooks to observe closely &lt;a href="https://github.com/EshbanTheLearner/preprocessing-pipeline-demo" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I know that there are a lot of steps involved in this process but I assure you that once you have set up a pipeline like this, your life would be much easier. Still seems like a lot of work? Contact us at &lt;a href="mailto:help@traindex.io"&gt;help@traindex.io&lt;/a&gt; to consult for any data engineering/science problems you might be facing.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>datascience</category>
      <category>bigdata</category>
    </item>
    <item>
      <title>How Traindex Leverages the Keyword Search?</title>
      <dc:creator>Mohsin Ashraf</dc:creator>
      <pubDate>Fri, 13 Nov 2020 17:50:23 +0000</pubDate>
      <link>https://dev.to/traindex/how-traindex-leverages-the-keyword-search-7fi</link>
      <guid>https://dev.to/traindex/how-traindex-leverages-the-keyword-search-7fi</guid>
      <description>&lt;p&gt;Traindex is a semantic search engine for corporate datasets to retrieve the most relevant results from a corpus. This search not only incorporates the meaning of the words but also includes contextual awareness. It enables a semantic search engine to outperform any keyword search engine; to find more, you can head out to our detailed &lt;a href="https://dev.to/traindex/how-is-semantic-search-different-from-keyword-search-578d"&gt;article&lt;/a&gt; about the difference between both these approaches.  &lt;/p&gt;

&lt;p&gt;Traindex performance is measured using a variety of benchmarks, ranging from automated algorithms to manual experts' classification. For instance, we are using the &lt;a href="https://dev.to/traindex/benchmarking-of-textual-models-jaccard-similarity-1c3i"&gt;Jaccard Similarity&lt;/a&gt;, which counts how many words from the retrieved results match the query's keywords. The following graph illustrates the visual intuition of this benchmark:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f3R8oYIS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/otxfhw6pri8vw8js8b5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f3R8oYIS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/otxfhw6pri8vw8js8b5k.png" alt="Screenshot from 2020-11-13 22-48-23"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The blue bar represents the query's keywords, whereas the orange bars represent the matched keywords. The higher the bar, the more keywords in common.&lt;/p&gt;

&lt;p&gt;In general, the benchmarking queries contain around 1200+ unique words. We have achieved a 47% average Jaccard Similarity score for the first twenty results against each query in our latest API release. This score means that we are implicitly applying the keyword search over the corpus since it approves that on average, Traindex could retrieve 564 common keywords with the query, which is far more than any keyword search engine can offer. &lt;/p&gt;

&lt;p&gt;Moreover, the common words are not just random words because they are meticulously picked by an algorithm that decides about the query's best representative. The same algorithm also incorporates their semantic meaning during the search, which leads the percentage of Jaccard Similarity score sometimes to raise up to 90% and 99%.&lt;/p&gt;

&lt;p&gt;When it comes to response time, Traindex is fairly quick. You can imagine how much time it would take to perform a keyword search of 564 words on 8.5M+ documents. It will require a lot of time and resources to go through the entire corpus, match the keywords, and bring up the relevant results. However, Traindex searches and ranks the results by their semantic similarity and not by the highest keyword match, as you can see from the above figure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Traindex could give you the best of both worlds: keyword search and semantic search. Keyword search over millions of documents will take a long processing time and too many resources and produce a lot of false positives. Traindex, on the other hand, permits you to do a query with an entire document with even tens of thousands of words, and still, the response time is quick, and results are quite relevant.&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>patents</category>
    </item>
    <item>
      <title>Patent Search</title>
      <dc:creator>Nada Gul</dc:creator>
      <pubDate>Thu, 12 Nov 2020 10:51:40 +0000</pubDate>
      <link>https://dev.to/traindex/patent-search-4j05</link>
      <guid>https://dev.to/traindex/patent-search-4j05</guid>
      <description>&lt;h3&gt;
  
  
  How to conduct a patent search
&lt;/h3&gt;

&lt;p&gt;A patent search helps evaluate the patentability of your invention. It lets you know if somebody else has already come up with the same idea or similar. If there's an existing patent for your invention, the patent offices will reject your patent, and all the time and money you invested in it will go to waste.&lt;/p&gt;

&lt;p&gt;Patent search may get a little overwhelming, which is why this article will help and make this daunting task easier for you.&lt;/p&gt;

&lt;p&gt;If you're new to patent searching, let's understand why you might find it helpful. If you have an idea for an invention, a patent search will help you familiarize yourself with previous patents to understand your invention's patentability. Understanding patentability enables you to avoid costly decisions. Patent search may also allow you to improve your existing patent application or your invention itself while avoiding copying someone else's idea.&lt;/p&gt;

&lt;p&gt;Besides building up on your idea for an invention, you might want to conduct a patent search to find out about recent inventions. It might assist you in studying the development of a particular technology you are interested in. You can also find patents by famous academics, perhaps for your research, or maybe if you are just keen on learning about their work.&lt;/p&gt;

&lt;p&gt;Now that we've discussed what patent search is and how it might help you, let's move on to the process of a patent search itself. There are multiple ways to conduct a patent search. We have made a list of four patent search methods we have used in the past and found useful:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. United States Patent and Trademark Office
&lt;/h2&gt;

&lt;p&gt;The United States Patent and Trademark Office, or the &lt;a href="https://www.uspto.gov/"&gt;USPTO&lt;/a&gt;, has an extensive library with multiple patent resources. There are Full-Text Patents from 1976 and PDF Image Patents starting from 1790. There is also a Full Text and Image Database for patent applications.&lt;/p&gt;

&lt;p&gt;There are three ways of searching Full Text patents: &lt;a href="http://patft.uspto.gov/netahtml/PTO/search-bool.html"&gt;Quick Search&lt;/a&gt;, &lt;a href="http://patft.uspto.gov/netahtml/PTO/search-adv.htm"&gt;Advanced Search&lt;/a&gt;, and &lt;a href="http://patft.uspto.gov/netahtml/PTO/srchnum.htm"&gt;Patent Number Search&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In Quick Search, you enter the terms along with fields to search for patents. Although the process was very slow, I got 848557 hits with 1 through 50 on the first page when I searched for chemical (Term 1) and reaction (Term 2). The boolean operator here being "and". You can choose the boolean operator when you enter terms to search: "and", "or" and "andnot". You can easily move to the next page by clicking "Next 50 hits", or enter a number you want to jump to in the box next to "Jump To".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--alJ3ApuP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qrtiejx1o1jgecbv2jdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--alJ3ApuP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qrtiejx1o1jgecbv2jdh.png" alt="USPTO Quick Search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Advanced Search, you have the option to enter multiple terms with appropriate boolean operators in different fields. The Patent Number Search allows you to search for patents using patent numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Google Patent Search
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4duLRGVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7339h3xb2q708w5ogcg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4duLRGVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7339h3xb2q708w5ogcg5.png" alt="Google Patent Search"&gt;&lt;/a&gt;&lt;br&gt;
Google Patents works the same as the Google search engine but catalogs patents and patent applications. Over the years, it has expanded to cover the European Patent Office, World Intellectual Property Organization, among other Intellectual Property organizations worldwide. It has global litigation information showing litigation history for patents anywhere in the world. Google Patent Search engine is a lot faster than the USPTO in showing results.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. IFI Claims Patent Services
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ificlaims.com/start.htm"&gt;IFI Claims Patent Services&lt;/a&gt; is another platform to search for global patent information if you have a subscription. Google Patents also use the IFI Claims patent database. You cannot search for patents on their publicly available website. However, the IFI Claims service provides an API service built on top of a SOLR index. The full documentation of their &lt;a href="https://docs.ificlaims.com/display/CDVDP/Search"&gt;search API endpoint is available here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Traindex
&lt;/h2&gt;

&lt;p&gt;Traindex is a search service for corporate datasets powered by machine learning. Specifically, it is a semantic text similarity service served as an Application Programming Interface (API). Traindex applies a model on patents extracted from "Google public patents data" and serves it as an API that your applications can consume.&lt;/p&gt;

&lt;p&gt;You can use the Traindex search widget &lt;a href="https://www.traindex.io/search"&gt;here&lt;/a&gt; to search for patents. Type your query in the space provided, as shown in the image below. You can choose one of the two indices: Google Patents or Wikipedia (the two active indices) and hit the search button. It was fairly quick and gave me 99 results for my query, "chemical reaction", along with the score for each link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2kcPo-2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c9i4f1ozp9no6uyv4wv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2kcPo-2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c9i4f1ozp9no6uyv4wv4.png" alt="Traindex"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information on Traindex, check out the link &lt;a href="https://www.traindex.io/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Patentability search is essential if you need to submit a patent application or have an idea for an invention and want to ensure someone else hasn't come up with the same or similar idea. It is also helpful if you want to find out about recent inventions or are interested in the development of particular technologies or want to find patents of famous academics. There are various routes to search for patents, including the USPTO, Google Patent Search, IFI claims, and Traindex.&lt;/p&gt;

&lt;p&gt;Hopefully, this article gave you an insight into how to search for patents. But if you have any questions regarding patent searching, send us an email at &lt;a href="mailto:blog@foretheta.com"&gt;blog@foretheta.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>patents</category>
      <category>patentsearch</category>
      <category>tips</category>
    </item>
    <item>
      <title>Introduction to Data Pipelines</title>
      <dc:creator>Eshban Suleman</dc:creator>
      <pubDate>Mon, 26 Oct 2020 17:37:22 +0000</pubDate>
      <link>https://dev.to/traindex/introduction-to-data-pipelines-26o7</link>
      <guid>https://dev.to/traindex/introduction-to-data-pipelines-26o7</guid>
      <description>&lt;p&gt;If you are a growing data-driven organization, you might have been working to harvest large amounts of data to extract valuable insights from it. This can be costly and inefficient unless the data science team adopts the repeatable solutions to common problems. Although the specifics of organizations may vary, the basic principles remain the same. There are some common features that you can encapsulate into a data pipeline. Let’s look at a common problem and see how we overcame it.&lt;/p&gt;

&lt;p&gt;Our team members at Traindex manually performed recurring tasks. These tasks included data cleaning, model training, testing, and so on. By performing these tasks manually, the engineer worked on the same thing again and again. This resulted in slow throughput, human error, and lack of flexibility and centralization. &lt;/p&gt;

&lt;p&gt;To overcome this, we envisioned a data pipeline to do all the above tasks with minimal human intervention. We developed and deployed such a pipeline, and it has proven itself to be a gust of fresh air. In this article, we’ll look at what data pipelines are, the benefits of using data pipelines in a corporate setting, and finally, what an event-driven data pipeline is.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a Data Pipeline?
&lt;/h1&gt;

&lt;p&gt;A pipeline is nothing more than a set of steps performed in a particular order in simple terms. A data pipeline is a set of processes performed on data from a source later moved to the destination, also known as the sink. The source could be anything from online transactional databases to data lakes, and the sink or the destination could be anything from data warehouses to business intelligence systems. The most common data pipeline is ETL, which extracts, transforms, and loads the data. The transformation process could include anything depending on the business. Here is a detailed data pipeline diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F485dkplisyhck3b47bn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F485dkplisyhck3b47bn8.png" alt="Alt Text" width="722" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ETL pipeline is a type of data pipeline that performs operations in batches and is sometimes referred to as a batch data pipeline. Batch data processing was very common for a long time. Now there are different types of processing available like streaming and real-time processing. This architecture of the data pipelines has a lot of variety according to your business needs. For example, stream analytics for IoT applications keeps the data flowing from hundreds of sensors and real-time data analysis.&lt;/p&gt;

&lt;p&gt;Now that we have understood what a data pipeline is let's discuss why it is important to use data pipelines in modern data-oriented applications. &lt;/p&gt;

&lt;h1&gt;
  
  
  Why use Data Pipeline
&lt;/h1&gt;

&lt;p&gt;In modern data-driven organizations, almost all actions and decisions are based on insights gathered from data. Every department of the organization has certain authorizations, restrictions, and data needs. Often the organizations have a single entity that manages the requirements of everyone resulting in a data silo. In such situations, getting even simple insights becomes difficult and leads to data redundancy within departments. The effort required to obtain essential data also handicaps the organization. &lt;/p&gt;

&lt;h3&gt;
  
  
  Easy and Fast Access to Data
&lt;/h3&gt;

&lt;p&gt;Well-thought-out data pipelines result in easy and fast access with right permission roles to data throughout the organization. Anyone from any department can access their desired data with no intervention or interference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swift Decision Making
&lt;/h3&gt;

&lt;p&gt;Based on the previously mentioned point, fast access to the data results in quick data-driven decisions. Data supports such choices, and they are less likely to go south.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;Well architectured data pipelines can automatically scale up or down according to the users'/organizations' needs. This reduces admins' headache to keep a constant eye and manually add or remove resources as per requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reliability
&lt;/h3&gt;

&lt;p&gt;Well-written data pipelines improve data quality. The data becomes more reliable, and executives can make better decisions based on it. &lt;/p&gt;

&lt;h3&gt;
  
  
  Economically Efficient
&lt;/h3&gt;

&lt;p&gt;Automated data pipelines run independently and need minimal maintenance and human intervention, thus less paid workforce. Also, their autonomous nature allows them to remove unused resources and save costs.&lt;/p&gt;

&lt;p&gt;Since we now understand what a data pipeline is and its benefits, let us see how we crafted a pipeline according to our needs at Traindex.&lt;/p&gt;

&lt;h1&gt;
  
  
  Event-Driven Data Pipelines
&lt;/h1&gt;

&lt;p&gt;Based on the problem we discussed at the beginning of this article, we decided on an event-driven pipeline. It runs based only on certain events. We wanted our pipeline to automatically run the data processing jobs, followed by training a machine learning model on the preprocessed data. We also wanted it to run some tests once it’s completed based on a specific event, which in our case, was an upload event. &lt;br&gt;
Moving data to a specified data storage by the user or engineer generates an event. Once they complete the upload, it triggers our pipeline. Scheduling is not optimal for this use case because we don’t know when this raw data will be uploaded in our storage. It can be frequent or occasional, so we went for the event-driven approach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2m2q19d34w857s8jr1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk2m2q19d34w857s8jr1e.png" alt="Alt Text" width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We learned the importance of mining large datasets efficiently to get the best insights on time to stay ahead of the competition. Modern-day data-driven organizations should consider setting up data pipelines to provide their teams with correct and useful data a click away. Data pipelines can also automate data-driven and recurring tasks like data preprocessing, model training, and testing on a schedule or based on specific events. We hope you have found this article useful, and you may consider crafting some data pipeline solutions for your organization. You can consult your data engineering problems with us at &lt;a href="mailto:help@traindex.io"&gt;help@traindex.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>bigdata</category>
      <category>dataengineering</category>
      <category>pipelines</category>
    </item>
    <item>
      <title>Summarizing Large Documents for Machine Learning Modeling</title>
      <dc:creator>Mohsin Ashraf</dc:creator>
      <pubDate>Thu, 08 Oct 2020 14:25:47 +0000</pubDate>
      <link>https://dev.to/traindex/summarizing-large-documents-for-machine-learning-modeling-4jhc</link>
      <guid>https://dev.to/traindex/summarizing-large-documents-for-machine-learning-modeling-4jhc</guid>
      <description>&lt;p&gt;Information is growing exponentially every passing day thanks to the internet. It has connected humanity from all the corners of the world. According to Forbes, 2.5 quintillion bytes of data are created every day, and the pace is accelerating. It includes all kinds of data: text, images, videos, and transactions, etc. Text data is the largest shareholder among these data. This text data can be a conversation between two persons, which can be of small sentences, or it can be intellectual property data, for example, patents, which can be up to millions of words.&lt;/p&gt;

&lt;p&gt;Handling smaller datasets with fairly small to medium-length documents is not a big challenge anymore, thanks to the power of deep learning. The problem comes when you have to deal with large-sized documents ranging from a few thousand words to millions of words such as patents and research papers. This is still challenging for deep learning methods to deal with such larger documents. It is hard for even state-of-the-art deep learning methods to capture the long-term dependencies in these documents. Hence, these huge documents require some special techniques to deal with them.&lt;/p&gt;

&lt;p&gt;At Traindex, we are working with intellectual property and providing effective and efficient search solutions on patents. Patent analysts might want to know what other patents exist in the same domain when filing a new patent. They may want to find prior art to challenge a claim in an existing patent. There are numerous use cases that better patent search helps solve.&lt;/p&gt;

&lt;p&gt;We are dealing with millions of patents, each containing thousands of words in it and some patents even reaching millions of words! Dealing with such a massive dataset with enormously large documents is a big challenge. These patents are not only lengthy, but they are intellectually intensive and have long-term dependencies. Deep learning alone will fail here to capture the proper semantics of such humongous documents. There need to be some very specialized techniques to deal with such large documents. We have developed some preprocessing techniques that help us reduce the size of the documents and keep the sense of the document pretty much the same. &lt;/p&gt;

&lt;p&gt;We use an extractive summarizer that summarizes the patent by first going through the whole patent, figuring out the important sentences in it, and then dropping off the patent's least important sentences. The summarizer uses two measures to figure out which sentence is essential: first, how many stopwords are present in the sentence (which reduces the importance of the sentence), second, how many important topics does a sentence contain with respect to the overall topics discussed in the patent (which increases the importance of the sentence). Then we use a simple threshold value for deciding which sentences to keep and which to drop. By changing the threshold's value, we can change the summary length, such that the summary contains the most important information about the patent. The following figure illustrates this point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foyrpgfl1xqeiclriacj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foyrpgfl1xqeiclriacj3.png" alt="Extraction" width="720" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image shows you the scores of the sentences in a patent. The horizontal red line is the threshold of importance for keeping or throwing away the sentences. The blue bars are the importances of the sentences below our defined threshold; hence we will drop them, and the result would look as follows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6n4sviu12iyg8nrzuzz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6n4sviu12iyg8nrzuzz5.png" alt="Summarization" width="720" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are the sentences that we are going to keep for our summarized patent. We can change the threshold line and get the summary's different lengths based on our needs. The flow of the overall process is given below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8tp14hitqupeuomrcf75.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8tp14hitqupeuomrcf75.jpg" alt="Untitled Diagram-1" width="396" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have tested this approach, and it has improved our search index's overall performance on patents. It tackles many problems for deep learning algorithms, especially if you are using some pre-trained models like Universal Sentence Encoder or Bert, which accept a limited number of words for any document. If you increase the length, you will run into errors. You can apply this summarization technique for all kinds of embedding algorithms with some limits regarding the input document's length.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>nlp</category>
      <category>summarization</category>
      <category>modeling</category>
    </item>
    <item>
      <title>Benchmarking of Textual Models - Jaccard Similarity</title>
      <dc:creator>Syed Afroz Pasha</dc:creator>
      <pubDate>Mon, 28 Sep 2020 21:18:03 +0000</pubDate>
      <link>https://dev.to/traindex/benchmarking-of-textual-models-jaccard-similarity-1c3i</link>
      <guid>https://dev.to/traindex/benchmarking-of-textual-models-jaccard-similarity-1c3i</guid>
      <description>&lt;p&gt;I recently concluded my internship with the Data Science team at Traindex. One of the tasks assigned to me was replicating the ML-based semantic search technique. The Data Science team had implemented this on their Traindex search API.&lt;/p&gt;

&lt;p&gt;Traindex uses document similarity techniques like LSI and Doc2Vec to train a model that can identify the best matching documents with a given document or paragraphs or phrases.&lt;/p&gt;

&lt;p&gt;One of the most challenging tasks is the benchmarking of language models. The process sometimes requires using a series of techniques for proper evaluation and testing.&lt;br&gt;
One of the benchmarks used for Traindex is Jaccard Similarity. It provides a baseline and is not enough for a complete evaluation of any model.&lt;/p&gt;

&lt;p&gt;This article intends to give some background on the where and how of the Jaccard Similarity score. It is useful for creating benchmarks to measure the performance of their language models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text Similarity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Text similarity can help us determine the similarity between pairs of documents, or a specific document and a set of other documents. The score calculated by performing the similarity check decides model acceptance, improvement, or rejection. The categorization of string-based text similarity shows various approaches that fit according to the scenario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VaZQNQjs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pheia0ozm871qcnzybcm.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VaZQNQjs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pheia0ozm871qcnzybcm.PNG" alt="Search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two main alternatives for finding the similarity metric.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;Character-based&lt;/em&gt; approach deals with the individual characters present in the document with the proper sequence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;em&gt;Term-based&lt;/em&gt; deals with the whole word. The words are often simplified or lemmatized before performing the test as per the initial data cleaning process used for the training purpose.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Introduction - Jaccard Index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the comparison of a finite number of elements between two observations, it is common practice to count items that are common to both sets. It is a natural fit for comparing posts in case of the representative tags to measure how similar two articles are in terms of tags.&lt;/p&gt;

&lt;p&gt;The Jaccard similarity index, also the Jaccard similarity coefficient, compares members of two sets to see shared and distinct members. It is a measure of similarity for the two sets of data, with a range from 0% to 100%. The higher the percentage, the more similar the two populations. The Jaccard Index is a statistic to compare and measure how similar two different sets are to each other. Although it is easy to interpret, it is susceptible to small sample sizes. It may give erroneous results, especially with smaller samples or data sets with missing observations.&lt;/p&gt;

&lt;p&gt;Let's have a look on this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;gensim.matutils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jaccard&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaccard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bow_water&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bow_bank&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8571428571428572&lt;/span&gt;


&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaccard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc_water&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc_bank&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8333333333333334&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jaccard&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;'word'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'word'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three code examples above feature two different input methods.&lt;/p&gt;

&lt;p&gt;In the first case, we present to Jaccard document vectors already in the bag of words format. The distance's definition is one minus the size of the intersection upon the size of the union of the vectors. We can see that the distance is likely to be high - and it is.&lt;/p&gt;

&lt;p&gt;The last two examples illustrate the ability for Jaccard to accept even lists (i.e. documents) as inputs. In the previous case, because they are the same vectors, the value returned is 0 - this means the distance is 0 and the two documents are identical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mathematical Representation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mathematically,  it is a ratio of intersection of two sets over the union of them. In the case of textual documents or phrases, it compares the words and counts the common words. Then divides it with the total number of words present in both of the documents. The same method applies to more than two documents with the same technique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UssTPfr3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zbj2nxs9dh9mwohapjng.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UssTPfr3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zbj2nxs9dh9mwohapjng.jpg" alt="jaccard similarity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the venn diagram above, it can be concluded that:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Jaccard Index = (number in both sets) / (number in either set) * 100&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Benchmarking is an essential process of Data Science that indicates the confidence level and effectiveness of a model. Traindex performs multiple benchmarking techniques from which Jaccard means similarity testing is an important one.&lt;/p&gt;

&lt;p&gt;A test data set finds the mean similarity score for the trained model. Sampling the main dataset where the validation fraction provides the parameter in the config file. Leaving every feature aside, UCID i.e., the unique document ID and the whole text, are the two crucial columns that are necessary to perform the testing. &lt;/p&gt;

&lt;p&gt;The following steps test the LSI model performance on the basis of term-based similarity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The test data is made containing the UCIDs with their respective text where the sampling is done according to the size mentioned in the configuration file.&lt;/li&gt;
&lt;li&gt;Cleaning of the text column of the test data as per the requirements, while the removal of duplicate terms is compulsory.
For each document, the query is made by using the text corresponding to its UCID.&lt;/li&gt;
&lt;li&gt;The document and index are sent to a function that returns the no of common words present in the query and document with the help of indices.&lt;/li&gt;
&lt;li&gt;Meanwhile, the calculations for common words and the total observations are done, followed by the calculation for Jaccard similarity by taking the ratio of the lengths saved earlier.&lt;/li&gt;
&lt;li&gt;Following the above steps can produce the adequate results required for the evaluation, but the results are scaled by dividing the score with respective query size. The extra step eradicates the behavioral bent of results because of different query size.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At last, the mean similarity score for all the combined results is calculated by averaging.&lt;/p&gt;

&lt;p&gt;A data frame is optional but populated with the similarity score for each result. The values are mapped on the bar chart, which clearly shows the percentage similarity with particular UCID, as shown in the sample figure. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3YnTYxlb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5ls4nfp5p33nh7cwos9w.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3YnTYxlb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5ls4nfp5p33nh7cwos9w.PNG" alt="bars"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact of Jaccard Similarity as an Evaluation Metric&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Jaccard similarity score may not be the best solution for benchmarking, but it may be considered for the following advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jaccard similarity takes a unique set of words for each sentence. This means that if you repeat any word in the sentence several times, Jaccard's similarity remains unchanged.
Consider these two sentences:&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Sentence 1: AI is our friend, and it has been friendly.&lt;/p&gt;

&lt;p&gt;Sentence 2: AI and humans have always been friendly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is robust enough to cater repetitions of a word like the word &lt;br&gt;
  "friend" in sentence 1. No matter how much frequent any word is, &lt;br&gt;
  Jaccard's similarity will be the same - here it is 0.5.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Instead of rejecting or accepting the document for a given set of queries, It provides a numerical score ranges from 0 to 1, which provides a clear view and can be used as a lookup for further iterations. Figure 3 explains the closeness of random search queries with the same document where the height of the bars represents the  Jaccard similarity scores between queries and the document.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jaccard similarity is useful for cases where duplication does not matter. For example, it will be better to use Jaccard similarity for two product descriptions as the repetition of a word does not reduce their similarity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a nutshell, benchmarking for evaluating a set of models is a necessary step in the data science process. The development of various tools and approaches for the calculation of a metric that can differentiate between products is important. In comparison with other domains, evaluation of Machine Learning, the language and contextual models are difficult. When there is less number of benchmarking techniques for textual models, the Jaccard similarity score is an important performance evaluation metric that can help in providing a partial summary of the model.  It can be concluded that the effectiveness of any benchmarking technique depends on how good they fit the problem. Also, to understand that a mismatch between the metric and the case can misguide the results.&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>benchmarking</category>
    </item>
    <item>
      <title>How Is Semantic Search Different From Keyword Search?</title>
      <dc:creator>Mohsin Ashraf</dc:creator>
      <pubDate>Wed, 23 Sep 2020 04:45:44 +0000</pubDate>
      <link>https://dev.to/traindex/how-is-semantic-search-different-from-keyword-search-578d</link>
      <guid>https://dev.to/traindex/how-is-semantic-search-different-from-keyword-search-578d</guid>
      <description>&lt;p&gt;With the exponential growth of information, finding the right information is like looking for a needle in a haystack. Bubbling the right information to the top of the search results is essential for efficiently working in the knowledge economy. Putting the best relevant results in the limited place of the first  page is what distinguishes an excellent search engine from a good search engine. This is the challenge we are solving at Traindex.&lt;/p&gt;

&lt;p&gt;One of the first challenges we are trying to solve is in patent space. Patent analysts might want to know what other patents exist in the same domain as a new patent being filed. They may want to find prior art to challenge a claim in an existing patent. There are numerous use cases that better patent search helps solve.&lt;/p&gt;

&lt;p&gt;We have experimented with numerous approaches to retrieve the relevant information quickly and effectively.  These approaches are centered around two fundamental techniques, the keyword search, and semantic search. &lt;/p&gt;

&lt;p&gt;In this article, we will take a deep dive in what is the difference between semantic search and keyword search and which approach is better.&lt;/p&gt;

&lt;p&gt;A keyword search is a simple keyword lookup in a corpus of documents against a query. The system will retrieve all the documents from the database which have any keyword present in the query. We can set constraints of whether all words in the query should be present in the retrieved results or any single word in the document would be sufficient to bring it up.&lt;/p&gt;

&lt;p&gt;One drawback of this approach is that the retrieval system will not care what the meaning of the keyword is in the context of a document and query it will simply bring back all the documents which contain the keyword specified by the user. This type of search might return irrelevant results (false positives). To view how keyword search works take a look at the following diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--udjheprR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zaajxnze3d10wk87us62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--udjheprR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zaajxnze3d10wk87us62.png" alt="Screenshot from 2020-09-23 09-30-47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above diagram, each small box shows the documents that contain a term specified e.g “A”. The diagram shows a user-entered query “raining cats and dogs” and how the system has retrieved the relevant documents to the terms that they used. In this case, the system retrieved all the documents which contained “raining”, “cats”, “and” and “dogs” and showed them to the user. But “raining cats and dogs” is a phrase in English used to describe heavy rain. This system might also get some relevant results but those results would be very small in number and also could have been ranked randomly (depending upon the database structure). Moreover, each word in the query is contributing independently regardless of its meaning being governed by its neighbors. Scaling the keyword search is also a problem and can slow down the response time of the search engine if you have millions of documents. Keyword searches may also fail to retrieve related documents that don’t specifically use the search term (false negatives). Under these conditions, researchers can miss pertinent information. There is also the danger of making business decisions based on less than a comprehensive set of search results.&lt;/p&gt;

&lt;p&gt;We use semantic search in Traindex. Unlike keyword search, the semantic search takes into account the meaning of the words according to their context. In semantic search, a latent vector representation of documents is inferred during the training process to project into the latent space. At the inference time, the incoming query is converted into the same latent space representation and projected into space in which the documents are already projected. The nearest points in the space to the query are retrieved as the similar documents to the query.&lt;/p&gt;

&lt;p&gt;Take a look at the following illustration using a 3D latent space, although these latent spaces can be from hundreds to a few thousands. At Traindex, we use the latent space representations ranging from 200 to 600 dimensions for capturing better representations of the documents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5juXFRKJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q9gybua7yhlqn8m1gldu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5juXFRKJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/q9gybua7yhlqn8m1gldu.png" alt="Figure_1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The red dot represents the query a user might have entered, whereas all the blue dots are the documents projected in 3D latent space. From here there are a number of ways to locate similar documents, for example, one can use Euclidean distance of these dots to calculate the most similar documents or a Cosine angle from the origin which is also known as cosine similarity, and the list of similarity matrices goes on.&lt;/p&gt;

&lt;p&gt;Now we have a solid understanding of how both searches work, let's compare them side by side.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Keyword Search&lt;/th&gt;
&lt;th&gt;Semantic Search&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Synonyms could be neglected during the search&lt;/td&gt;
&lt;td&gt;Incorporate the meaning of words hence comprehends the synonyms as well&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to carefully pick the keywords for search&lt;/td&gt;
&lt;td&gt;The query is automatically enriched by the latent encoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The information which is retrieved is dependent on keywords and page ranking algorithms that can produce spam results&lt;/td&gt;
&lt;td&gt;The information retrieved is independent of keywords and page rank algorithms that produce exact results rather than any irrelevant results&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Semantic search seeks to improve search accuracy by understanding a searcher’s intent through the contextual meaning of the words and brings back the results the user intended to see. &lt;/p&gt;

&lt;p&gt;In patents, technical and domain-specific terms are heavily used which might not be present in English dictionaries and hence can be missed by a patent analyst while they is searching for prior art. Semantic search in Traindex processes the whole patent as input for (prior art and similarity) search and uses vectorized representation of the text to find synonyms and same words in other patents during the search, which is impossible with a keyword search.&lt;/p&gt;

&lt;p&gt;Moreover, keyword search is restricted to use up to a fixed number of words which is at most 50 words generally and reduces the response time as the number of keywords grow, whereas in Traindex you can search with any number of words including the whole patents which are hundreds of thousands of words and can get results in real time. Semantic search in Traindex converts the whole patent into a vector representation and matches the most similar documents in the database, hence overcomes the problem of limited keywords search.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>nlp</category>
    </item>
  </channel>
</rss>
