<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Stéphanie Crêteur on Medium]]></title>
        <description><![CDATA[Stories by Stéphanie Crêteur on Medium]]></description>
        <link>https://medium.com/@stephanie.creteur?source=rss-2115e892c1d4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*NXm3_W7mZGpIhqtmU2K7Ww.jpeg</url>
            <title>Stories by Stéphanie Crêteur on Medium</title>
            <link>https://medium.com/@stephanie.creteur?source=rss-2115e892c1d4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 11:47:37 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@stephanie.creteur/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Machine learning: one-hot encoding vs integer encoding]]></title>
            <link>https://medium.com/geekculture/machine-learning-one-hot-encoding-vs-integer-encoding-f180eb831cf1?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/f180eb831cf1</guid>
            <category><![CDATA[data]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-wrangling]]></category>
            <category><![CDATA[encoding]]></category>
            <category><![CDATA[model-building]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Fri, 16 Dec 2022 11:01:44 GMT</pubDate>
            <atom:updated>2022-12-16T11:01:44.870Z</atom:updated>
            <content:encoded><![CDATA[<p>Which one is more efficient than the other in a model-building context?</p><p>First thing first: Why did I write this article? Well, while working on a machine learning project, I was confronted with this problem and I didn’t know which one to choose. So I had to take several minutes of my time to Google and find the reasons why one form could be preferred over the other. I found some useful information and decided to write this article to share what I learned. Hopefully, it will help others who are facing the same question.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ghGqbPjosmLDWczA" /><figcaption>Photo by <a href="https://unsplash.com/es/@ikukevk?utm_source=medium&amp;utm_medium=referral">Kevin Ku</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>But before starting, what are actually one-hot encoding and integer encoding? These two methods are options to numerically encode your data which take place during the preprocessing phase. Indeed, for the computer to understand the input you provide, it must be transformed into numerical values and this is where the one-hot encoding and the integer encoding come in. To illustrate this, I’ll use the example that led me to ask myself that very question. Using data from rotten tomatoes, I wanted to build a model that predicted whether a film would be classified as ‘Rotten’, ‘Fresh’, or ‘Certified-Fresh’. You can find the complete project with the data on <a href="https://platform.stratascratch.com/data-projects/rotten-tomatoes-movies-rating-prediction">StrataScratch</a>. In my data frame, I had several features that I had to transform into numerical values, for example, the content rating (‘PG’, ‘R’, etc.), and audience status (‘Spilled’ or ‘Upright’).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K18I9suIHXXrQmhwr_srqw.png" /><figcaption>Here is my dataframe before using any form of encoding.</figcaption></figure><p>There I had the choice between either using one-hot encoding or integer encoding. In the latter, each category is assigned a unique integer, and the integer values are used to represent the categories in the dataset. At that time, that’s the method I used — to be honest, the only reason I favoured that one is simply because I didn’t want to have too many columns in my df. To do so, I used the LabelEncoder() from sklearn.preprocessing and ended up with this result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zGK_NIfwcAqzg6TWgox6uA.png" /></figure><p>The last two columns are my new categorical data represented as integers. Its advantage is that it is pretty straightforward to implement. The code here was simply :</p><pre>LE = LabelEncoder()<br>movies_cl[&#39;audience&#39;] = LE.fit_transform(movies_cl[&#39;audience_status&#39;]</pre><p>It has as well the advantage of preserving an ordinal relationship, however, <strong>that is as well one of the reasons you shouldn’t be using it.</strong> Indeed, Integer encoding can introduce a bias into the data by implying a natural ordering between the categories. This can lead to poor performance or unexpected results in machine learning models that use the encoded data. For example, the model may make predictions that are halfway between the encoded categories, which may not accurately reflect the original data. Furthermore, it implies that one category is more similar than another. For example, if we encode the categories “red”, “green”, and “blue” as 1, 2, and 3 respectively, the encoded values will imply that “red” is closer to “green” than it is to “blue”. It can lead to incorrect assumptions and conclusions.</p><p>In this case, where there is no ordinal relationship, it would be better to use One-hot encoding. This will create a new column for each category, and each column will have a value of 0 or 1 to indicate the presence or absence of that category in a given sample.</p><p>One advantage of one-hot encoding is that it allows the model to learn more easily and effectively. This is because each input value is represented as a binary vector, where only a single element of the vector is set to 1 and the rest are set to 0. This makes it easier for the model to learn the relationship between the input values and the target output because the model can easily distinguish between the different input values based on their unique binary representation.</p><p>To do so easily you can use the pandas’ get_dummies() which will give you this result:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/395/1*-uAQQo4mf8hfKavVGxr33w.png" /><figcaption>Result from get_dummies()</figcaption></figure><p>You can as well use the sklearn.preprocessing OneHotEncoder() which is apparently <a href="https://stackoverflow.com/questions/36631163/what-are-the-pros-and-cons-between-get-dummies-pandas-and-onehotencoder-sciki">better for machine learning</a>. You can then put this feature into your original data frame and get rid of the old columns.</p><p>So, we can see that it is not really more complicated to implement than the integer encoding and One-hot encoding has some more advantages.</p><ul><li>First, one-hot encoding is often considered to be <strong>more expressive</strong> than integer encoding, because it can more accurately represent the data and its relationships. Indeed, it can better represent the presence or absence of a category. . For example, if a sample belongs to the “Red” and “Green” categories, the one-hot encoded representation of that sample would be [1, 0, 1] (with a 1 in the first and third columns and a 0 in the second column). This accurately reflects the fact that the sample belongs to the “Red” and “Green” categories, but not to the “Blue” category. In contrast, the integer encoded representation of the same sample would be [1, 2], which does not provide any information about the presence or absence of the “Blue” category.</li><li>The model can as well <strong>more easily handle new input</strong> values that it hasn’t seen before. For example, if the model has been trained on a set of input values that includes the values “red”, “green”, and “blue”, and then it receives a new input value “yellow”, it can easily represent this new value as a binary vector and make a prediction based on its training.</li><li>Finally, one-hot encoding can also be <strong>more efficient in terms of memory and computational cost</strong>, because the binary vectors are typically much shorter and sparser than the corresponding integer encodings. This can be especially important for large datasets or complex models.</li></ul><p>However, you have to note that one-hot encoding might lead to high dimensional data and to multicollinearity which might lower the model’s accuracy.</p><p>But why did I ask myself so many questions about those two methods? Well, simply because I saw that the Stratascratch solution was using a one-hot encoding method for the content rating when I had chosen to represent it with integer encoding and I couldn’t understand why it was doing so there when it was using integer encoding for the other categorical values. To be honest, I am not 100% sure that in this case, it was absolutely necessary to use one-hot encoding as my results were as good as Stratascratch’s (probably because content rating is perhaps not a very important feature in the construction of this model and we could as well find some sense of ordinality in it).</p><p>I hope that this article helped you better understand what is the difference between the two methods and what are its advantages and disadvantages of each. I mainly hope that you choose one version over another because you truly understand what it will imply for your model and not, as I did at first, because you don’t want to have too many columns in your dataframe… I’m at least happy that it piqued my interest enough to want to look into it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f180eb831cf1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/machine-learning-one-hot-encoding-vs-integer-encoding-f180eb831cf1">Machine learning: one-hot encoding vs integer encoding</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time series: what tools are available in Python to analyse them?]]></title>
            <link>https://medium.com/geekculture/time-series-what-tools-are-available-in-python-to-analyse-them-110e17806e7?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/110e17806e7</guid>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[analytics]]></category>
            <category><![CDATA[predictions]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Sat, 10 Dec 2022 06:01:40 GMT</pubDate>
            <atom:updated>2022-12-10T06:01:40.006Z</atom:updated>
            <content:encoded><![CDATA[<h4>Second part: Data filtering, analysis of the components and prediction</h4><p>Here is the second and last part of my article about time series. In this part, I will dive into data filtering, the analysis of the components and prediction. You’ll find the first part which focuses on visualisation and statistics by following this link:</p><p><a href="https://medium.com/geekculture/time-series-what-tools-are-available-in-python-to-analyse-them-dc2061f69e8c">Time series: what tools are available in Python to analyse them?</a></p><p>As a reminder, I was interested in analysing time series (which can be defined by the chronological evolution of a quantity, regularly spaced in time). The most common time series you can think of would be the stock market. After the visualisation and statistical analysis of my data (which were left intentionally abstract), I wanted to filter my data since it seemed to be noisy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*3zc49rBXL0CMT-_w" /><figcaption>Photo by <a href="https://unsplash.com/@nick604?utm_source=medium&amp;utm_medium=referral">Nick Chong</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>Data Filtering</h3><p>A filter ‘should eliminate all the undesired components’(Haslwanter, 2021, p. 72). Indeed, if the aim of the analysis is to create a model, ‘[t]he presence of noise in a data set can increase the model complexity and time of learning which degrades the performance of learning algorithms.’(Gupta &amp; Gupta, 2019, p. 466). Noisy data can refer to ‘errors (incorrect examples), as well as outliers (correct examples representing some relatively rare subconcept of the target theory)’ (Gamberger et al., 2000, p. 206). Being able to handle such data is crucial if you want to recognise and analyse the pattern present. It is, however, really important to understand that it might reduce the precision of the data, but in some contexts, you might be ‘more concerned with establishing whether the data exhibits a meaningful relationship, rather than establishing its precise character.’(Janert, 2011, p. 48). Certainly, ‘A smooth curve such as a spline or LOESS approximation is only a rough approximation to the data set — and, by the way, contains a huge degree of arbitrariness in the form of the smoothing parameter (<em>α</em> or <em>h </em>respectively).’(Janert, 2011, p. 57). Of course, you should pay attention to the context and, according to it, make the best judgment. Here, I will use two smoothing algorithms: one that I will implement by myself, and one available in the library SciPy, I will compare the results and see how a filter can drastically change the function and its components.</p><p>To choose the best fit for the filter, it is important to consider some criteria. The first one would be to be sure that the data has been sampled at equal intervals which is true for those values. In such a case, ‘FIR- or IIR-filters can be used.’(Haslwanter, 2021, p. 90) otherwise, I would need to use more complex smoothing algorithms such as LOESS or splines which handle the filtering of irregularly sampled data.</p><p>An Infinite Impulse Response (IIR) filter makes more sense in a dynamic system, I will therefore be using a Finite Impulse Response (FIR) filter. The FIR filter has no feedback in its equation which makes it very stable. First, I will be using the moving average filter, which is a special case of the FIR filter, and, as the name suggests, they both have a finite impulse response. This method places more importance on the recent data and is very good to reduce random white noise.</p><p>Here is the function weighted_moving_average() that was used.</p><pre>def weighted_moving_average(x,y,step_size=0.05,width=1):<br>    bin_centers = np.arange(np.min(x),np.max(x)-0.5*step_size,step_size)+0.5*step_size<br>    bin_avg = np.zeros(len(bin_centers))<br><br>    def gaussian(x,amp=1,mean=0,sigma=1):<br>        return amp*np.exp(-(x-mean)**2/(2*sigma**2))<br><br>    for index in range(0,len(bin_centers)):<br>        bin_center = bin_centers[index]<br>        weights = gaussian(x,mean=bin_center,sigma=width)<br>        bin_avg[index] = np.average(y,weights=weights)<br><br>    return (bin_centers,bin_avg)</pre><p>In the visualisation below, we can compare the result between our function untouched and the result of the weighted moving average algorithm.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*IYp6QrNTDXKG5zywo1sASw.png" /><figcaption>The result from a weighted moving average algorithm</figcaption></figure><p>Another kind of FIR filter is the scipy.signal lfilter whose result is given in the graph below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*6OFa8XhEcJIE7wBo7AEzNg.png" /><figcaption>The result of the scipy.signal lfilter</figcaption></figure><p>It is visible that the two algorithms give different answers which vary as well greatly according to the parameters input. Choosing which one is the best and which parameters to use will depend vastly on the context. We can see with those two results that smoothing ‘reveals behaviour that would otherwise not be visible’ (Janert, 2011, p. 52) and confirms what the visualisation had suggested that there is a recurrence of rises followed by drops around the mean.</p><p>Some interesting insights from our lfilter results are given from the summary statistics. If I use again the describe() function, I obtain those results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/1*tGXQ__9mtZvWs7IRj0z1Vw.png" /></figure><p>Compared to the original function, it is visible that our mean and median are closer even to zero and that the minimum and maximum have been drastically reduced. Therefore, the range of the function is considerably narrowed. As for the distribution, I get the following histogram which seems to be closer to a normal distribution but slightly right skewed with more data in the negative.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*NliNeO8f-WY_rARFbilfxg.png" /><figcaption>Histogram of the smoothed function</figcaption></figure><p>To know if those results are in concordance with what you want to achieve you will once again need to check what are the objectives of the study and the model.</p><h3>Analysis of the main components of the time series</h3><h4>Stationarity</h4><p>An important part of the analysis is to know if the data is stationary that is, if its ‘statistical properties do not change over time’ (Peixeiro, 2022, p. 39). This can be said true if it has a constant mean and constant variance over time. To calculate and visualise this, I used this code:</p><pre>yy_average = smoothed_function.rolling(window=50).mean()<br>yy_std = smoothed_function.rolling(window=50).std()[2]<br>plt.ylim([-0.5, 0.5 ])<br>yy_std.plot()<br>yy_average.plot()<br>plt.show()</pre><p>Plotting it using matplotlib, we get the result visible for the original function in the figure on the left and on the right for the smoothed function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*fVxw38-QzdHoA6jtP1b9sg.png" /></figure><p>Neither the mean nor the variance is changing too drastically, except in the smoothed function where the mean goes slightly more in the negative around the last values. We can therefore say that our data is stationary which is important to know since many forecasting models assume that our properties don’t change over time. This indeed makes sense because if the statistical properties change over time so should the properties of the model. If the data is not stationary ‘We cannot possibly derive a function of future values as a function of past values, since the coefficients change at each point in time’ (Peixeiro, 2022, p. 39). If the data is not stationary, one possibility to stabilise the mean is to use differentiation and for stabilising the variance to apply a logarithmic function.</p><h4>Autocorrelation and Seasonality</h4><p>Another useful tool to understand time series and more specifically its seasonality is autocorrelation which is the matching of a signal with itself over different time delays. It ‘can be used to detect periodicity in a signal which may be impossible to see otherwise’(Haslwanter, 2021, p. 114).</p><p>The autocorrelation shows if there are periodical events that impact the data and the strength of the relation between the current data and the past ones. To do that I will use the statsmodels library and specifically its plot_acf() function, the plot on the left shows the result for the original function while the one on the right shows it for the filtered version.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*IiTSZsm2RFhfp1A2OH6VPg.png" /></figure><p>The cone in transparent blue gives the confidence interval (here set at 95%). Therefore, if a point is outside the blue zone, we can say with 95% probability that it has an impact on the current value while if it is inside the blue cone we can consider it equal to zero (Peixeiro, 2022, p. 47). The point at lag 0 is 1 since it reflects how much the current value explains itself. For the original function, we can see that there seems to be no seasonality visible as the coefficient decrease directly at lag 1 under the confidence interval. For the smoothed function, it is a bit different: we see a correlation in the first values but, as we progress, the current values are explained less and less by the previous ones. We can see a dip in the negative that is statistically relevant which says that in the function ‘if a past value is above average the newer value is more likely to be below average (or the other way round)’ (Drelczuk, 2020). This could be the indicator that we are confronted to a mean reversion where values tend to revert towards previous levels after large moves. We can see as well that it has seasonality even though it is not significant enough to take any conclusion and, of course, without a time measure given to the x-axis it is difficult to conclude, but a cycle seems to be forming where the data goes from positive to negative in what can be described as 15 seconds/days/months/years…</p><h4>Seasonal Decompose</h4><p>The statsmodels package has another very useful feature, called seasonal_decompose(), that actually lets you decompose the time series into its main features: trend, seasonality and residual. Applying this to the smoothed data, I obtain the results visible in this figure below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*eM6Al5MYqa5Iv_X5Wn_nVg.png" /></figure><p>The ‘seasonal’ plot shows how our data deviate from the general trend. It has regular spikes going above the trend while the main part of the data is staying below. As for the trend, which represents the ‘slow-moving changes in a time series’ (Peixeiro, 2022, p. 6), we see that it seems to stay around the mean (a bit below zero for the smoothed function), even though the last 50 points seem to show a tendency to decrease.</p><h3>Prediction</h3><p>Those precise descriptions of the function will help go toward the final step which is forecasting i.e. ‘the prediction of the future using historical data and knowledge of future events that might affect our forecasts’ (Peixeiro, 2022, p. 6). In order to do so we will need to take into account the features that we have underlined, especially seasonality which is known to have a significant impact on time series.</p><p>One of the methods used to predict future results is a random walk. To be able to use a random walk the data must be stationary and I have shown previously that the original function is purely random with no visible trend or seasonality with tests such as the ACF plot, the running average, etc. Therefore, a random walk would be possible in this context. However, those values seem to be too noisy to really see a point in doing so.</p><p>Another option that is suitable if the data is autocorrelated is the moving average. Indeed, in that context, ‘The present value is linearly dependent on current and past error terms.’ (Peixeiro, 2022, p. 88). However, for this smoothed data, the autocorrelation coefficient falls too slowly to use this method and I have repeatedly shown that it seems to have a sinusoidal pattern which makes this model inappropriate. Therefore, taking into account those characteristics, an autoregressive model could be the best answer to predict this set of data. This process ‘establishes that the output variable depends linearly on its own previous values’ (Peixeiro, 2022, p. 91) which means that I will use lagged values to make our prediction.</p><p>In this case, I will be using the SARIMA model which is a more powerful extension of the ARIMA (Autoregressive Integrated Moving Average) that supports the seasonal component of the data. Ideally, to find the best parameters for the model, I would need to use all the elements gathered previously. However, it is, of course, quite difficult to set proper parameters without a real time frame on the x-axis. But I still managed to get a realistic result by using the pmdarima library which helps to set the best parameters for the Arima models. The result is visible below. It does seem to make sense since the predictions for the value above the 400th point seem to regress toward the mean which has been a feature of the data that I have shown previously.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/622/1*ZxJjDfTcM-5fkiToalMBjg.png" /></figure><p>And that’s it for the time series. I tried in those two articles to show how to analyse such data with the help of some of the great libraries available in Python. Follow me for more!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=110e17806e7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/time-series-what-tools-are-available-in-python-to-analyse-them-110e17806e7">Time series: what tools are available in Python to analyse them?</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time series: what tools are available in Python to analyse them?]]></title>
            <link>https://medium.com/geekculture/time-series-what-tools-are-available-in-python-to-analyse-them-dc2061f69e8c?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/dc2061f69e8c</guid>
            <category><![CDATA[visualization]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[time-series-analysis]]></category>
            <category><![CDATA[statistics]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Fri, 25 Nov 2022 15:02:02 GMT</pubDate>
            <atom:updated>2022-12-08T11:39:31.694Z</atom:updated>
            <content:encoded><![CDATA[<h4>First part: visualisation and statistics</h4><p>In this article, which I will divide into two parts, I would like to focus on time series, which is the chronological evolution of a quantity, regularly spaced in time (hourly, monthly, yearly…). They can represent the evolution of the temperature over time, the evolution of the stock market, the monitoring of the heart rate, etc. In any data analyst’s career, processing the information contained in time series is a crucial and recurring part of their work. However, these can sometimes be confusing and difficult to read. So how do you proceed with this data?</p><p>Faced with this challenge, I decided to turn to the literature written on this topic, so this article will be sprinkled with many references that helped me to better understand this subject.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Cu43P7_F5BAtzJfm" /><figcaption>Photo by <a href="https://unsplash.com/@nampoh?utm_source=medium&amp;utm_medium=referral">Maxim Hopman</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Since its creation, Python has managed to gather around it a growing community of scientists and analysts. That can be attributed to its easiness to code, open-source frameworks and libraries that have been developed which allows Python ‘to perform statistical computing, machine learning tasks, develop websites, and much more’ (Peixeiro, 2022, p. 1). Indeed, several of those libraries greatly facilitate the work of any researcher by automating complex procedures and offering many tools to visualise and calculate data. This is, of course, true as well for time series.</p><p>To help you understand the process better and to make it as concrete as possible, I propose working with concrete figures taken without context. I chose to leave these values deliberately abstract to be as universal as possible, although obviously knowledge of the sector in which they were taken would be part of a thorough and complete analysis and would likely allow me to conclude more quickly which method would be most relevant and effective. As Chatfield, in his book <em>The Analysis of time series: an introduction, </em>confirms ‘The context of a given problem is crucial in time-series analysis’ (Chatfield, 2004, p. 11).</p><h3>1. Visualisation</h3><p>In any analysis, the visualisation of data should be the first step. This is confirmed by many professionals: ‘Making plot and static or interactive visualizations is one of the most important tasks in data analysis.’(McKinney, 2018, p. 219) Janert in his book <em>Data analysis with open source tools</em> explains: ‘Looking at data, you will notice things — the way data points are distributed, or the manner in which one quantity varies with another, or the large number of outliers, or the total absence of them.’(Janert, 2011, p. 1)</p><p>This is revealed to be of even more importance in time series as Chatfield confirms: <em>‘</em>Anyone who tries to analyse a times series without plotting it first is asking for trouble. A graph will not only show up trend and seasonal variation, but will also reveal any’ wild’ observation or outliers that do not appear to be consistent with the rest of the data.’ (Chatfield, 2004, p. 6)</p><p>If I plot the data into a scatter plot (figure 1), it seems that no specific trend is visible at first glance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*Imf3WaKCslu-qADmKLM9IA.png" /></figure><p>However, if I use a line graph instead as shown in the graph below, I get a totally different picture. The line graph, by showing the change between two points, lets us glimpse at what seems to be a ‘regularly recurring feature’ (Janert, 2011, p. 80), looking almost like a sinusoidal function. This, combined with the amount of surrounding noise, makes the scatter plot confusing. The line graph can be useful when we need not only to see a general trend (which in this case is too confusing) but as well to distinguish the local trend between a group of points (‘Line Graphs and Scatter Plots,’ 2005). Here it allows us to see the repetitive pattern. Choosing the visualisation correctly is therefore an important step and different criteria have to be taken into account, such as ‘the amount of noise and outliers in the data’ (Wang et al., 2018) or if the data is discrete or continuous.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/612/1*5wzVYd47FlczXm_N1E4AIA.png" /></figure><p>The visualisation gives us the first hint at one of the main components of our function: the presence of seasonality. As for the trend (another important component of the time series) which is defined as a ‘long-term change in the mean level’ (Chatfield, 2004, p. 12), it doesn’t seem to have one. However, we will need to dive a bit more into our function to be able to make that clear.</p><h3>2. Statistics</h3><p>Halswanter says in his book that ‘[s]tatistics provides us with the tools to extract the maximum amount of knowledge from a given data.’ (Haslwanter, 2021, p. 123) Summary statistics can therefore be of great help in our understanding of the function. It is, however, important to take this information with caution as Chatfiled warns to be very careful with summary statistics of time series as they can be misleading (Chatfield, 2004, p. 11).</p><p>The data consists of 400 points, with the x-axis going from -20 to 20 and the y-axis from -0.511 to 0.486. It has a mean value of -0.019. Each value on the x-axis has only one corresponding value on the y-axis and they are equally spaced. Using the describe() function which returns the statistical summary of our dataframe, I get the following results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/272/1*pg7EHeOYpbPRV1UX7gvtfA.png" /></figure><p>The mean (-0,019) and the median (-0,010) are close together which implies that our distribution is symmetrical and might be normally distributed. However, a quick glance at a histogram plot tells us differently: the highest number of values are found at the extremities but with a general homogeneous distribution in each of the bins. We therefore have data that are symmetrically distributed around zero and oscillating between -0.5 and 0.5.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/593/1*q-2V5tqXy6Uqm_Nfgv7mXw.png" /></figure><p>However, thanks to the line graph, it is obvious that the data seems noisy. To further understand the graph, I would need to get rid of this feature by filtering it. And that&#39;s what I will be doing in the next article. Be sure to follow to get the next parts where we will focus on filtering, analysis and prediction!</p><p>Thank you for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dc2061f69e8c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/time-series-what-tools-are-available-in-python-to-analyse-them-dc2061f69e8c">Time series: what tools are available in Python to analyse them?</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Top Songs to Learn Spanish According to Data Science]]></title>
            <link>https://medium.com/geekculture/top-songs-to-learn-spanish-according-to-data-science-7575e61ec38c?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/7575e61ec38c</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[nlp]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[spanish]]></category>
            <category><![CDATA[language]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Wed, 29 Jun 2022 14:03:12 GMT</pubDate>
            <atom:updated>2022-06-29T14:03:12.600Z</atom:updated>
            <content:encoded><![CDATA[<p>After I wrote my previous article about the best songs to learn French, many people came back to me to do the same exercise but in another language. So I thought I’d give it a go with Spanish.</p><p>By the way, if you’re interested in the easiest French songs, my article can be found here:</p><p><a href="https://medium.com/geekculture/how-can-nlp-help-french-learners-find-songs-that-match-their-current-level-a1efdc4dc8fb">How can NLP help French learners find songs that match their current level?</a></p><p>I have more or less followed the same process, therefore I won’t dwell so much on the code in question, but rather on the results. Some new features though: I used the <a href="https://developer.musixmatch.com/documentation">MusiXmatch API</a> to find the music&#39;s genre and get the singers&#39; nationalities. The procedure to register for an API key is available by following this <a href="https://developer.musixmatch.com/">link</a>.</p><h3><strong>Exploratory Data</strong> Analysis</h3><p>My dataframe consists of <strong>4582 songs </strong>by artists from <strong>38 different countries</strong>. The most represented genres are pop (1139 songs), Latin (505 songs) and Latin Urban genres (275 songs).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*rZiiAnBXOupmA39W" /><figcaption>Photo by <a href="https://unsplash.com/@photoripey?utm_source=medium&amp;utm_medium=referral">Ibrahim Rifath</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>As mentioned earlier, the novelty in this analysis is the addition of nationalities. Despite a large number of missing data, we can still see a clear top three with the USA (862 songs), Spain (671 songs) and Mexico (596 songs).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2ylFCN8R7ABENURF6HwekA.png" /></figure><p>In the same way as for French songs, the vocabulary remains linked to love (‘amor’, ‘amar’), life (‘vida’) and desire/love (‘quiero’). Compared to French lyrics, I do have the impression though that there is a <strong>greater emphasis on the body </strong>in these songs with a regular occurrence of terms like ‘labios’ (‘lips’), ‘besos’ (‘kisses’), ‘piel’ (‘skin’), ‘sentir’ (‘feel’), ‘boca’ (‘mouth’), ‘cuerpo’ (‘body’).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QXNuyLBk75kCgZwPNOZMaQ.png" /></figure><p>The artists with the most songs are <a href="https://www.youtube.com/channel/UC5jcyfv-J8R1RGlapR_x1Cg">Julio Iglesias</a> (78 songs), <a href="https://www.youtube.com/channel/UCYLNGLIzMhRTi6ZOLjAPSmw">Shakira </a>(62 songs), <a href="https://www.youtube.com/channel/UC9TO_oo4c_LrOiKNaY6aysA">Daddy Yankee</a> (58 songs), <a href="https://www.youtube.com/channel/UCwR_LqB7g3-_J7p1nscCbEA">Wisin and Yandel</a> (53 songs) and <a href="https://www.youtube.com/channel/UC-6czyMkxDi8E8akPl0c7_w">Enrique Iglesias</a> (53 songs).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yWgLijBgN5RrCFv15397sg.png" /></figure><h3><strong>Classification</strong></h3><p>This time for my vocabulary I used the frequency list offered by the <a href="http://www.rae.es/">Real Academia Espanola</a> (REAL ACADEMIA ESPAÑOLA: Banco de datos (CORDE) [en línea]. Corpus diacrónico del español. <a href="http://www.rae.es/">http://www.rae.es</a> [22.06.2022]). A major difference between this list and the one used in French is that it contains not only the basic form of a word but all its forms classified according to their occurrence. Thus, we find “soy” (‘I am’) as well as “fuimos” (‘we were’) or “ser” (‘to be’), whereas my previous list was limited to the infinitive verb (here it would have been ‘ser’).</p><p>In order to estimate how many words I should include in each level, I based myself on this <a href="https://universeofmemory.com/how-many-words-you-should-know">article</a>. In this way, I have again created four lists of words divided into A1, A2, B1 and B2. For the rest, the process is quite identical to the <a href="https://medium.com/geekculture/how-can-nlp-help-french-learners-find-songs-that-match-their-current-level-a1efdc4dc8fb">French songs</a> (creation of a matrix with CountVectorizer, the insertion of the level of each word in this same matrix, creation of a dictionary with the percentage of words per level for each song, …)</p><h3><strong>Results</strong></h3><p>Here are the results of the analysis. First, you can see here a graph showing the distribution of songs according to their lexical range: either A (A1 to A2) or A + B (A1 to B2).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4MLTInbHLIsspeSkUETlYQ.png" /></figure><p>And finally here are the three lists of songs: one with the highest percentage of known words for A1 level, then for A2 level and finally for B2 level.</p><h4>TOP 10 songs for A1 level</h4><ul><li>Sueño de Noche by Gipsy Kings (genre = Latin)</li><li>¡Qué bien! [Hot Dog Dance] (Latin Spanish) by Mickey Mouse Clubhouse (OST) (genre = Children’s Music)</li><li>La despedida by Shakira (genre = Folk)</li><li>Te quiero tanto by OV7 (genre = Pop)</li><li>Toma mi vida by Milly Quezada (genre = Merengue)</li><li>¿Dónde Están, Corazón? by Enrique Iglesias (genre = Pop)</li><li>Así es la mujer que amo by Victor Manuelle (genre = Latin)</li><li>Más by Nelly Furtado (genre = Pop)</li><li>5 razones by Manu Chao (genre = World)</li><li>Nada ni nadie by Soy Luna (OST)</li></ul><p>Again I created a <a href="https://open.spotify.com/playlist/2TqdGBVVLP32c0pVhPMyny?si=fefcaa78d56344c9">Spotify playlist</a> with some A1 level songs from the corpus (almost 3 hours of songs).</p><h4>TOP 10 songs for A2 level</h4><ul><li>Tú estás aquí by Jesús Adrián Romero (genre = Christian &amp; Gospel)</li><li>Reflejo de Luna by Alacrán (genre = Electronica)</li><li>Eres tú by Mocedades (genre = Pop)</li><li>A Lo Mejor by Banda MS (genre = Pop)</li><li>Mi primer amor by Ender Thomas (genre = Latin)</li><li>Lo que yo sé de ti by Ha*Ash (genre = Pop)</li><li>Me voy by Yasmin Levy (genre = Pop)</li><li>Por qué será by Xtreme (genre = Salsa y Tropical)</li><li>Amor Genuino by Zion &amp; Lennox (genre = Latin Urban)</li><li>Renuevame by Christian Hymns &amp; Songs (genre = Christian &amp; Gospel)</li></ul><p>Here is the <a href="https://open.spotify.com/playlist/5VP5hsAnPHRzF0VSbdblwC?si=693b1e0a66e8486d">playlist for the A2 level</a>.</p><h4>TOP 10 songs for B2 level</h4><ul><li>Porque by Yasmin Levy (genre = Raices)</li><li>Dame tu mano by Glorya (genre = Electronica)</li><li>Los adolescentes by Dënver (genre = Pop)</li><li>La incondicional by Luis Miguel (genre = Pop)</li><li>Vayamos compañeros by Marquess (genre = Pop)</li><li>Años by Mercedes Sosa (genre = Latin)</li><li>Amor, amor, amor by Julio Iglesias (genre = Pop)</li><li>You are my hiding place by Selah (genre = Christian &amp; Gospel)</li><li>Vai (LLP Remix) by Muneca (genre = Pop)</li><li>Amada amante by Roberto Carlos (genre = Brazilian)</li></ul><p>Finally, the <a href="https://open.spotify.com/playlist/27q5AbHsGX2ENCtCFv5wGK?si=e05b866582294476">playlist for the B2 level</a>.</p><p>If you rather want to search by yourself according to your preferences, <strong>you can use the table below to browse the whole corpus</strong>. You can either search by artist, title, genre or nationality. You can also classify the list according to the lexical range: A1-A2 or A1-B2.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fdatawrapper.dwcdn.net%2FD8Xul%2F1%2F&amp;display_name=Datawrapper&amp;url=https%3A%2F%2Fdatawrapper.dwcdn.net%2FD8Xul%2F1%2F&amp;image=https%3A%2F%2Fdatawrapper.dwcdn.net%2FD8Xul%2Fplain-s.png%3Fv%3D1&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=dwcdn" width="600" height="1200" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ecfbe49273c88c59b647f6466918175/href">https://medium.com/media/3ecfbe49273c88c59b647f6466918175/href</a></iframe><p>If you are interested in the full code here is the <a href="https://github.com/StMaCre/Song_level_analysis">GitHub repository</a>. Thank you very much for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7575e61ec38c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/top-songs-to-learn-spanish-according-to-data-science-7575e61ec38c">Top Songs to Learn Spanish According to Data Science</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How can NLP help French learners find songs that match their current level?]]></title>
            <link>https://medium.com/geekculture/how-can-nlp-help-french-learners-find-songs-that-match-their-current-level-a1efdc4dc8fb?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/a1efdc4dc8fb</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[language-learning]]></category>
            <category><![CDATA[nlp]]></category>
            <category><![CDATA[french]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Mon, 20 Jun 2022 09:01:37 GMT</pubDate>
            <atom:updated>2022-09-06T08:17:05.188Z</atom:updated>
            <content:encoded><![CDATA[<p>I have taught French to a lot of students over the years and have been in the shoes of a learner many times myself. This long language learning experience has taught me one thing: <strong>when you’re a beginner the best way to get vocabulary and a sense of the prosody of the language is through songs</strong>. However, whenever I would explain this to my students I saw that they were expecting me to give them a selection of songs, yet, my tastes aren’t theirs and I find myself offering them songs that are neither their level nor their taste.</p><p>After reading the series of articles written by <a href="https://frank-andrade.medium.com/">Frank Andrade</a> who used data science tools to classify more than <a href="https://towardsdatascience.com/the-best-movies-to-learn-english-according-to-data-science-2dccb4b3ee23">3000 films</a> and tv shows according to their language level, I thought I would try to do the same with French songs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xrktHsXgeoq3H1G6" /><figcaption>Photo by <a href="https://unsplash.com/@simon_noh?utm_source=medium&amp;utm_medium=referral">Simon Noh</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>The aim of this analysis is therefore to classify the songs according to their <a href="https://www.coe.int/en/web/common-european-framework-reference-languages/level-descriptions">CEFR level</a>. However, how do I evaluate the level of a text? Obviously, there are many ways to work on this problem (grammar, length, readability, pronunciation,…) As I see this as a tool to develop language comprehension and improve vocabulary, I will focus on the lexicon used. In this article, I will show you how I worked on this challenge before revealing the most appropriate songs per level. If you’re only interested in the song list, you can head directly to the result section.</p><h4>What information do we need?</h4><p>So I have to go looking for the data, but what information is essential? At the very least, I need the text, the artist and the title of each song. To this, I would also like to add the genre, as learners don’t realise the actual diversity of the French music scene, believing that it’s relatively small and limited to the artists that cross the borders of French-speaking countries. Generally, the learners are only presented with pop songs or older songs from famous singers like Edith Piaf. The fact that you’re learning French shouldn’t force you to listen to pop songs for hours if you like metal. In addition to all these elements, I also need a list of words that are classified according to their level (i.e. A1 to C2).</p><h3>Getting the Data</h3><p>For the first part, I have collected all the songs categorised as ‘French’ on the <a href="https://lyricstranslate.com/en/songs/22/none/none/0">Lyricstranslate</a> website. I realise, however, that this implies an important bias in my corpus, which is that these songs have been already translated into other languages by the users (which would therefore imply that they are already popular with non-French speakers). Despite this, I still favoured it because it provided a piece of essential information: the popularity of the song. Indeed, when sorting the songs, you can choose to order the list by popularity. The index of my corpus would thus serve as a basis to know their popularity level.</p><p>After collecting the songs, I was still missing the genres. To do this I created several lists: rock, pop, <a href="https://fr-academic.com/dic.nsf/frwiki/335294">chanson francaise</a>, metal, electro, folk/children’s music, and film music. In each list, I added the artists corresponding to the genre.</p><p>Finally, all I needed was a list of words classified by level. However, unlike English where it’s quite easy to find a vocabulary list classified by levels from A1 to C1, in French, I couldn&#39;t get one and had to create it. To do this, I discovered two lists on the internet that would give me an overview of the vocabulary that a learner of French should know. The first one is from the <a href="https://eduscol.education.fr/186/liste-de-frequence-lexicale">French Ministry of National Education and Youth</a> which gives a list of the 1500 most frequent words in French, and the other is from <a href="https://app.memrise.com/course/131111/5000-most-common-french-words">Memrise</a> where you can find a list of 5000 most used words (according to the creator of the list, so it has to be taken with caution). I will explain below how I used those two lists to classify the words by level.</p><p>So I started my work with a list of 5000 songs, several lists of artists classified according to their genre and a list of over 6000 French words ranked according to their frequency. All of them in their own CSV files.</p><h3>Data wrangling</h3><p>The first step is to load the songs&#39; lyrics CSV file into a DataFrame and check its information with df.info() and how it looks like with df.head() here are the results:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/491/1*h4bHKNgRj8V8tivpxVHTGA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/845/1*GyOSrNoMpzW-qvUbMOV0pQ.png" /></figure><p>I notice that I’m missing some lyrics and many album titles. I as well have a column ‘Unnamed: 0’ that I will get rid of. Looking more specifically at the text of the songs, I can see that there are some elements that would have to disappear before being able to lemmatise the text correctly (HTML remains, line breaks, punctuation, …) I used the replace method with a regular expression pattern to do so (for example, &lt;.*&gt; would be the regex pattern to delete all the remaining HTML elements like &lt;div&gt;or &lt;em&gt;. Here is the complete code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/52ad39715b6c28389984a9fb2cb4a73e/href">https://medium.com/media/52ad39715b6c28389984a9fb2cb4a73e/href</a></iframe><p>I had to add the 178 missing songs manually. However, I limited myself to the songs that were in the top 300 since I was mainly interested in the ones that are popular. It was principally songs from <a href="https://www.youtube.com/channel/UCXF0YCBWewAj3RytJUAivGA">Stromae</a>, <a href="https://www.youtube.com/channel/UCCB1Byx5yTbLpQaV-rlfmtA">Gims </a>and <a href="https://www.youtube.com/channel/UCzmPKJcdeMKGiy-93Jn4pZA">Jacques Brel</a>. I as well added the genre corresponding to each artist. Also, by looking at some of the songs I quickly noticed that some of them weren’t in French. This isn’t dramatic since they would simply be at the bottom of the ranking but I still wanted to see if a Python library could tell me the language of the text. I was happy to discover the <a href="https://pypi.org/project/langdetect/">Langdetect </a>library which allows you to do just this. Thanks to langdetect, I created a function that returns True if the song is in French and False if it’s in another language. This allows me to create a new column on my df that stores this. The next step is simply to remove from my df all rows whose value for this French column is False.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c0013be01e79706e02d1a2625417187/href">https://medium.com/media/4c0013be01e79706e02d1a2625417187/href</a></iframe><p>Before moving on to lemmatisation, I also wanted to create a final column that contained the number of words in each song. This would be useful to better understand my data and to get the percentage of words in each level.</p><p>The next step is lemmatising my text, but <strong>what is lemmatising?</strong></p><blockquote>The action […] of giving (a word) the canonical neutral form that it has, for example, in a dictionary (<em>Le Robert</em>)</blockquote><blockquote>Component for assigning base forms to tokens using rules based on part-of-speech tags, or lookup tables. (<em>Spacy</em>)</blockquote><p>Indeed, to avoid our classifier counting ‘bon’ (good, masculine singular), ‘bons’ (good, masculine plural), ‘bonnes’ (good, feminine plural) as different words, it seems more coherent to keep only the neutral form. Of course, this creates some problems, such as the fact that a student may know the indicative form ‘vouloir’ but not its subjunctive ‘veuille’. However, I think the positive impacts outweigh the negatives.</p><p>In order to be able to lemmatise each of the song lyrics, I used <a href="https://spacy.io/api/lemmatizer">Spacy’s lemmatizer</a> which offers nice performances in French and I created a function to add a new column called ‘lemmatised ’ to my data frame.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/69a6b7cea6726889f540d4c37bb22771/href">https://medium.com/media/69a6b7cea6726889f540d4c37bb22771/href</a></iframe><p>To give a concrete example, the first words from the song ‘La vie en rose’ by Edith Piaf go from “Des yeux qui font baisser les miens un rire qui se perd sur sa bouche” to “un, oeil, qui, faire, baisser, le, mien, un, rire, qui, se, perdre, sur, son, bouche”. After all this preliminary work, my data frame is ready for analysis. Here is what it looks like after this first part. Now we have <strong>4632 songs</strong> (after dropping the nan) distributed among these 7 columns:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-4NBi_5MWEqOTWsNhH5qvA.png" /></figure><h3>Understanding the data</h3><p>Before starting the analysis of the levels per song, let’s try to understand our corpus a little better. First, we can look at the most used words in our list. To do this I used a <a href="https://www.geeksforgeeks.org/generating-word-cloud-python/"><strong>word cloud</strong> </a>and removed from the list the so-called <strong>stop words</strong>, i.e. words that are used frequently in the corpus and don’t add any meaning. I used the stop-word list given by Spacy to which I appended a few words that were high in the ranking but didn’t add weight to it (‘j’, ‘c’est’, …) I ended up with this words cloud.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zJGAR6iyELS_4xRp5DdaBQ.png" /></figure><p>We can see that words such as ‘amour’, ‘aime’ (‘love’), ‘vie’ (‘life’), temps (‘time’), ‘veux’(‘want’) are very prominent in the songs.</p><p>I then created a bar chart ranking the artists by the number of songs they had in the corpus (Note that technically Jacques Brel is in the lead with more than 100 songs, but since many of his songs weren’t ranked in the top 300, I didn’t add them to the corpus and therefore removed them from the data frame before lemmatisation).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d13rG_AcXzXtx5NlOEQ6lQ.png" /></figure><p>Then I tried to find out which music genre had the most words on average. We can see that it’s rap music which is largely in the lead. Indeed if we look at the mean number of words per artist, we can see that <a href="https://www.youtube.com/channel/UC9XW6KSafvrm6_jgpitJS9w">Fonky Family</a> has an average of 1186 words per song, followed by <a href="https://www.youtube.com/channel/UCjfIMz-a7tpPZCYQoD8pMEQ">Kery James</a> (1105 words) and <a href="https://www.youtube.com/channel/UCZuIi-AXxSOHuG3QdkAxyaQ">Mafia K’1 Fry</a> (1089 words), the three of them are rappers or groups of rappers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nlipM_9tlpQIFInIo0df7A.png" /></figure><h3><strong>Classification</strong></h3><p>After these first inputs that allow us to better understand our dataset, we can move on to the classification part. However, we’re still missing an important element which is the list of words per level. As noted earlier, I already have a list of 1500 words classified by the frequency of use. In addition to this list, I also have another list of 5000 of the most used words in French made by a Memrise user. But, how can I classify them by level?</p><p>After some research on the internet, I found this table which could help me:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/273/0*KBx2PKen9-avUVpc" /><figcaption>Source: <a href="http://polydog.org/index.php?threads/the-cefr-scale-and-language-level.26/">http://polydog.org/index.php?threads/the-cefr-scale-and-language-level.26/</a></figcaption></figure><p>We’re in a comprehension exercise so I will be more interested in the ‘passive vocabulary’ part and I will limit myself to levels A1, A2, B1, and B2 since I have around 5000 words. I think it’s logical to assume that for A1 and A2 levels, it’s better to know words that are widely used. I will therefore populate these first lists with the word frequency list of the French Ministry of Education. Then, after removing the words that are already present in the frequency list, I take the Memrise list and complete what is missing to reach the quotas of the different CEFR levels. As the Memrise list wasn’t made by a professional, the difference between levels B1 and B2 will be taken with a pinch of salt.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c2535a43942a2e29e95c7b5838c49b8/href">https://medium.com/media/1c2535a43942a2e29e95c7b5838c49b8/href</a></iframe><p>So now I have four lists of words which add up to 5000 words divided between all four levels as shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/580/1*r456KB9JQaWKXJKkwtpe_A.png" /></figure><p>I can finally start working on the classification.</p><p>In order to do this, I’m going to use the scikit-learn <a href="https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html">count vectorizer</a> that I discovered thanks to Frank Andrade’s posts. The count Vectorizer ‘convert a collection of text documents to a matrix of token counts’ (scikit-learn documentation).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f268efe6687c2ae849d0c162cf40bf6/href">https://medium.com/media/4f268efe6687c2ae849d0c162cf40bf6/href</a></iframe><p>Once I have this matrix (26551 rows over 4633 columns!), I add to it the level linked to each word and I get the table below. We can see, for example, that the word ‘alors’ (then) appears thrice in the song at index 3 and twice in the one at index 5 and is ranked level A1.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/477/1*J3dcB_xbgwYqhL5SwfgEMg.png" /></figure><p>Then I create a table grouping the sum of words for each category using df_dtm.groupby(by=’level&#39;).sum() and I get a list of each of the songs with the number of words per category.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/781/1*dRJNKbeTb_y-_CAXJyIzzw.png" /></figure><p>You can see in this table that the song at index 4 has 193 words from the A1 list, 17 from the A2 list, 6 from the B1 list and 4 from the B2 list. The last part consists of associating this information with that of the songs. To do this I create a dictionary which takes the index of the song as its key and a list of the four levels for each song as its value. The index allows me to link those pieces of information to the song that has the same index in the original df. I as well, divide the words per level by the total number of words in the song and get a percentage for each level.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b8d34548da526aa78fa42ea7a92d847b/href">https://medium.com/media/b8d34548da526aa78fa42ea7a92d847b/href</a></iframe><p>You can see in the code above that I have also created two new columns: one called ‘A’ which covers the lexical range for A1 and A2 and a column called ‘A+B’ which covers the vocabulary from levels A1 to B2.</p><h3>Results</h3><p>Finally, we can analyse the results! Firstly, I have created a graph that allows us to see the distribution of the songs according to their level coverage, either A or A+B.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MXWiVXGPYicRdB9A9OsFZg.png" /></figure><p>In the graph below you will find the average A1 to B2 level per music genre. Not surprisingly, poetry and chanson francaise are ranked first, while rap and rai have fewer words covered by the vocabulary lists created. This can be explained for rai (an Algerian musical genre) because many Arabic words are used in the lyrics. As for rap, this can be attributed to the use of many slang words, neologisms or words of foreign origin.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xgbTgAkWi9ofccyHA1J-dg.png" /></figure><p>Then I created three lists of songs: one with the highest percentage of known words for A1 level, then for A2 level and finally for B2 level. To do this, I collected the songs that ranked highest in terms of the level chosen, and from A2 level onwards I also removed the songs that were already in the previous lists. I thus obtained these three lists.</p><p><strong>Top 10 best songs to learn French if you’re at A1 level</strong></p><ul><li>‘Il faut manger’ by Manu Chao (genre = pop)</li><li>‘Qu’avons-nous fait de vous?’ by Le Roi Soleil (genre = comedie musicale/film)</li><li>‘La poupée qui fait non’ by Mylène Farmer (genre = pop, chanson francaise)</li><li>‘Elle’ by Melissa M (genre = R&amp;B)</li><li>‘Tu me manques’ by Mia Martina (genre = pop)</li><li>‘Reste-là’ by Keren Ann (genre = pop,chanson francaise)</li><li>‘Tu te reconnaîtras’ by Anne-Marie David( genre = pop)</li><li>‘Attendre ’ by Céline Dion (genre = pop, chanson francaise)</li><li>‘Que sont devenues les fleurs’ by Dalida (genre = pop)</li></ul><p>I as well created a <a href="https://open.spotify.com/playlist/4AzvFz5fEpRkK2XA4LeuYp?si=d08a12d4f6f84ac2"><strong>playlist on Spotify with a selection of A1 level songs</strong></a><strong>.</strong></p><p><strong>Top 10 best songs to learn French if you’re at A2 level</strong></p><ul><li>‘Je te laisserai des mots’ by Patrick Watson (genre = pop,classique)</li><li>‘Pas avec toi’ by Plastiscines (genre = pop)</li><li>‘Pour une fois’ by Marie-Mai (genre = pop)</li><li>‘L’intranquilité ’ by Louise Attaque (genre = pop,rock,chanson francaise)</li><li>‘Te passe pas de moi lyrics’ by Judith (genre = pop)</li><li>‘Tu me manques’ by Sheryfa Luna (genre = pop)</li><li>‘Le temps des fleurs lyrics’ by Vicky Leandros (genre = pop)</li><li>‘Tes yeux noirs’ by Indochine (genre = pop,rock,chanson francaise)</li><li>‘Fais ce que tu voudras lyrics’ by Céline Dion( genre = pop,chanson francaise)</li><li>‘Sous le vent’ by Garou (genre = pop,chanson francaise)</li></ul><p>Here is the <a href="https://open.spotify.com/playlist/3SlzKQIfXU87bvADOn1MCz?si=aa83177e52ad4610"><strong>Spotify playlist for the level A2</strong></a>.</p><p><strong>Top 10 best songs to learn French if you’re at B2 level</strong></p><ul><li>‘Ne partez pas sans moi lyrics’ by Céline Dion (genre = pop,chanson francaise)</li><li>‘Si la vie est cadeau ’ by Corinne Hermès (genre = pop,chanson francaise)</li><li>‘Mon Dieu’ by Édith Piaf (genre = chanson francaise)</li><li>‘La taille de mon âme’ by Daniel Darc (genre = rock)</li><li>‘Maman me dit’ by Angélina (genre = pop)</li><li>‘Un ange est tombé’ by Lara Fabian (genre = pop)</li><li>‘Ce que je sais’ by Johnny Hallyday (genre = pop,rock)</li><li>‘Pourquoi tu vis et où tu vas’ by Jeanette (genre = pop)</li><li>‘Ma référence’ by Jena Lee (genre = pop)</li><li>‘Le verger aux petits’ by Bastien Lallemant (genre = chanson francaise)</li></ul><p>And the <a href="https://open.spotify.com/playlist/76nJUFO3jFlL16rRQ97Ejv?si=071f3277f25544f4"><strong>final playlist</strong></a><strong>.</strong></p><p>If you rather want to search by yourself according to your preferences, you can use the table below to browse the whole corpus</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fdatawrapper.dwcdn.net%2F6Q7LS%2F5%2F&amp;display_name=Datawrapper&amp;url=https%3A%2F%2Fdatawrapper.dwcdn.net%2F6Q7LS%2F5%2F&amp;image=https%3A%2F%2Fdatawrapper.dwcdn.net%2F6Q7LS%2Fplain-s.png%3Fv%3D5&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=dwcdn" width="513" height="1425" frameborder="0" scrolling="no"><a href="https://medium.com/media/55743ffc6e9de39a4e8379ba0307dd53/href">https://medium.com/media/55743ffc6e9de39a4e8379ba0307dd53/href</a></iframe><p>I’m quite happy with the result. However, there are a few things to consider that could improve this list. Firstly, to rate the level of a song only on the lexicon is rather reductive. It could be interesting to add grammar points, and verbal tenses into the criteria to evaluate the level of a song. Secondly, pronunciation is an important element that has been overlooked. Finally, ideally, it would be interesting to be able to classify the songs by theme. If we’re working on the theme of ecology, having a few songs that correspond to both the level of the learner and the topic being addressed would be an invaluable tool.</p><p>You can find the complete code on my Github: <a href="https://github.com/StMaCre/french_song_level_analysis">https://github.com/StMaCre/french_song_level_analysis</a>. Thank you for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a1efdc4dc8fb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/how-can-nlp-help-french-learners-find-songs-that-match-their-current-level-a1efdc4dc8fb">How can NLP help French learners find songs that match their current level?</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use web scraping tools to gain insight into a specific sector?]]></title>
            <link>https://medium.com/geekculture/how-to-use-web-scraping-tools-to-gain-insight-into-a-specific-sector-68f3f4bfb1f9?source=rss-2115e892c1d4------2</link>
            <guid isPermaLink="false">https://medium.com/p/68f3f4bfb1f9</guid>
            <category><![CDATA[books]]></category>
            <category><![CDATA[exploratory-data-analysis]]></category>
            <category><![CDATA[web-scraping]]></category>
            <category><![CDATA[data-analysis]]></category>
            <dc:creator><![CDATA[Stéphanie Crêteur]]></dc:creator>
            <pubDate>Wed, 20 Apr 2022 10:03:00 GMT</pubDate>
            <atom:updated>2022-04-20T10:03:00.596Z</atom:updated>
            <content:encoded><![CDATA[<h4>An analysis of the children’s literature sector in Lithuania</h4><p>For my work, I needed concrete data on the children’s literature sector in Lithuania. However, despite some research on the net, apart from a few articles (available in the sources of this document), I could not find any precise figures.</p><p>I am also training in data analysis with Python and specifically wanted to learn more about web scraping. I could therefore get around this lack of resources while developing my understanding of <strong>beautiful soup</strong> (a Python library for parsing HTML) and <strong>selenium </strong>(a tool for controlling web browsers).</p><p>In writing this article, I want to show a concrete case of web scraping and how it can help us to obtain data that is otherwise difficult to acquire. Those data being the basis for developing a relevant analysis. Clearly, my topic was very specific and I could not limit myself to a generic idea of the field.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xbCAkP_fxVDowF9K" /><figcaption>Photo by <a href="https://unsplash.com/@porkbellysteve?utm_source=medium&amp;utm_medium=referral">Stephen Andrews</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>I had concrete questions I wanted to answer: what is the average price of a children’s book, how many categories exist, which books are the most popular, and what is the proportion of Lithuanian authors in the selected books? In addition, I wanted to know if people tended to buy more children’s books during the Covid crisis. Since parents had to stay at home with their children during the quarantine, it is likely that they would purchase more books to find activities to do with their children.</p><p>To obtain this information I decided to retrieve the data available on the website <strong>knygos.lt</strong> (a Lithuanian version of Amazon). Indeed, on a single page, we can find almost 200 books for children and teenagers divided into 11 categories as well as a lot of other relevant information for our analysis.</p><h4>1. Scraping the data</h4><p>The first step is to check that the site can indeed be scraped by checking the <strong>robots.txt file</strong>. Once this is confirmed, I can start the actual scraping. I’ll begin with importing the needed libraries and creating the soup object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a5d7930cf630fa8184523922508720cf/href">https://medium.com/media/a5d7930cf630fa8184523922508720cf/href</a></iframe><p>Looking at the HTML file from the website, you can see that the class for the properties of the books is called “book-properties” divided into “.book-author”, “.book-title” and “.book-price”. To limit the selection to the grid containing youth literature, I need to select the class “.col-12” (otherwise we would include the promotions that are not related to our topic).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/727/1*BuUCpuLwybBHEziyCLyuHA.png" /><figcaption>The Information Available Thanks to the Inspect Element Tool</figcaption></figure><p>There is a star rating system for each book (going from 0 to 5). However, those evaluations are not very diverse (between 4 and 5 stars for the vast majority). In order to analyse the popularity of a book, the number of reviews given seems more relevant. This is available under the class “.badge-secondary”.</p><p>For data storage, I used a dictionary whose key is the index and the value is a list containing the name of the author, the title, the number of reviews, and the price.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/349cdcc059460c414e5b4044dcb5d431/href">https://medium.com/media/349cdcc059460c414e5b4044dcb5d431/href</a></iframe><p>The books are as well divided into 11 categories: Knygos mažiausiems (books for toddlers), Knygos vaikams (books for children), Knygos paaugliams (books for teenagers), Pažintinė literatūra vaikams (Educational literature for children), Pasakos (Fairy tales), Kakė Makė (a popular Lithuanian children’s series featuring the character “Nelly Jelly”), Lavinamosios, užduočių knygelės (Educational and activity books), Veiklos knygelės (Workbooks), Kalėdinės knygelės (Christmas books), Mokiniams rekomenduojamos knygos (Books recommended by schools), Smagioji edukacija (Fun Education).</p><p>On this web page, for each category there are 16 books, so we can easily add those categories to the dictionary we created earlier.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aba68e895b78f97c1e0bf8eb7d0cf1c4/href">https://medium.com/media/aba68e895b78f97c1e0bf8eb7d0cf1c4/href</a></iframe><p>Great, we now have everything to create our DataFrame! However, we need first to clean the data a bit (fill in the missing reviews with “0” and change the data type to float).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e898f5d8512ad13a429b4c1567ff6682/href">https://medium.com/media/e898f5d8512ad13a429b4c1567ff6682/href</a></iframe><p>We now are left with this DataFrame which contains 176 rows and 5 columns.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZjyjiZBuNc7g72UiKENzbA.png" /></figure><h4>2. Analysing the data</h4><p>Using the <strong>describe()</strong> function will help us obtain some solid information regarding our quantitative data (reviews and price).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/261/1*fkQ7YVawA2Z-XIDJJIJe2g.jpeg" /></figure><p><strong>2.1. Analysing the reviews</strong></p><p>Let’s check what books and what categories are the most reviewed in our selection.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c39bf4e5a2274bc64c7ff80a0286a2eb/href">https://medium.com/media/c39bf4e5a2274bc64c7ff80a0286a2eb/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EEI6XHvuvqcBfuepV8o73Q.png" /></figure><p>We can see that the most reviewed book is <strong><em>Between Shades of Gray </em></strong>by American-Lithuanian author, Ruta Sepetys. The categories receiving the most reviews are the ones for toddlers and the ones recommended for school.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f6cP0-4M3jS78gGpsRHmPA.png" /></figure><p><strong>2.2. Analysing the price</strong></p><p>The next part of our analysis will look at the average price of a book according to its category and which books are the most expensive.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3f870653bc4d40a8392e8dff58c09aea/href">https://medium.com/media/3f870653bc4d40a8392e8dff58c09aea/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lCIufwWeJr9k0yfcbF__fg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FaTa_lrh8ub9IN9J9qFPBg.png" /></figure><p>The most expensive category is fairy tales (pasakos), and logically the most expensive book is also in this category. However, it should be noted that this book is actually a collection of volumes, hence the high price.</p><p><strong>2.3. Correlation between price and reviews</strong></p><p>I’ve noticed that the more expensive books don’t seem to get a lot of ratings. So I would like to see if there is a correlation between the two with df_lithuania_no_outliers.plot.scatter(x=”price”, y=”review”, c=”DarkBlue”). Before that, I removed the collection of volumes which was a clear outlier with df_lithuania_no_outliers = df_lithuania.drop([73]).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HRMHNU-NXqLE3069-9MVvw.png" /></figure><p>We can see that the most reviewed books are<strong> between the 5 and 15 euros</strong> <strong>price range</strong>. However, as we have noticed with the describe() function, almost 50% of our books are in this range. It is still interesting, though, that the books that do not fall into this interval receive almost no reviews.</p><h4>3. Nationality of the author</h4><p>One question that interested me at the beginning of the analysis was to know the <strong>proportion of Lithuanian authors</strong> in this corpus. This seems to be a bit complex, without having to track the Lithuanian authors one by one. However, we can try to get around this by using one of the “quirks” of the Lithuanian language which is its pretty unique diacritical marks (“ąčęėįšųūž”). These may indeed help me to note which authors are likely to be Lithuanian (or of Lithuanian descent). I used the regular expression module (import re) to classify the authors into two groups.</p><p>I noticed that the search did indeed seem to admit mainly Lithuanians although at least two persons whose nationality is not Lithuanian were included in the selection (Pavla Hanáčková and Ester Dobiášová, both of Czech origin). However, I kept this approach as it gave me a good approximation. I removed Mrs Hanáčková and Dobiášová with the .remove() function.</p><p>The last change to the list is the addition of some common names particular to Lithuania (Vytautas, Linas) and finally the addition of Ruta Sepetys (author of <strong><em>Between Shades of Gray</em></strong>) whose dual nationality is perhaps responsible for the absence of “ū”.</p><p>Despite the fact that she lives in the United States, the general theme of her book is directly related to Lithuania. Therefore, it seems logical to me to include her among the Lithuanian authors. Here is the complete code :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d6b038f19bd34afe3cc1eabecf5d2c7e/href">https://medium.com/media/d6b038f19bd34afe3cc1eabecf5d2c7e/href</a></iframe><p>Thanks to this list, we now know that <strong>the percentage of Lithuanian authors in our corpus is 19,32%</strong>. The next step would be to add a new column in our DataFrame which would have a “Y” if the author is Lithuanian and “N” otherwise. This new column allows us to see if Lithuanian authors tend to receive more reviews than non-Lithuanians.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eec56aed25039b1520465058eb845ea2/href">https://medium.com/media/eec56aed25039b1520465058eb845ea2/href</a></iframe><p>With this calculation we see that books written by Lithuanians receive on average <strong>9.56 reviews </strong>were non-Lithuanians receive only <strong>4.39 reviews</strong>. However, we do know that there is an outlier: the book <strong><em>Between Shades of Gray </em></strong>which has 118 reviews. Let’s see how it changes if we take it out of our corpus.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55f34f885132635a830796b94ec97ad6/href">https://medium.com/media/55f34f885132635a830796b94ec97ad6/href</a></iframe><p>Without Sepetys’ book, the average drops to<strong> 6.27 reviews </strong>which is still higher than the average for foreign authors.</p><h4>4. <strong>Comparing the top seller&#39;s books from 2019 to the ones from 2021</strong></h4><p>On knygos.lt, you can see that a fairly large number of children&#39;s literature books are among the top-selling books of this year. I would like to know if the percentage has changed over the years and more specifically if the covid crisis has had any impact. However, our site does not give the top 100 from previous years. So we have to turn to another website <a href="http://www.knyguklubas.lt/">www.knyguklubas.lt</a>. This site requires JavaScript to be enabled, which Beautiful Soup does not permit. So we have to turn to another python library: <strong>Selenium</strong>.</p><p>To compare 2019 to 2021, I decided to get a list of children’s authors from this site and then analyse the percentage of authors in the top sales of 2019 and 2021.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5acde06ae6f1d85c6560158b3d21419c/href">https://medium.com/media/5acde06ae6f1d85c6560158b3d21419c/href</a></iframe><p>So I went to the page dedicated to children’s literature (set to 96 books sorted by popularity). Then I scraped the authors from the first two pages, which gave me a list of 192 popular authors in the field of children’s literature. I got rid of the “Nėra Autoriaus” (no author) with a list comprehension which gave me a final list of 172 authors.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9a5d9d357910e82d685c547d7a976bcd/href">https://medium.com/media/9a5d9d357910e82d685c547d7a976bcd/href</a></iframe><p>I then went to the page giving the most popular books of 2019 and added all the authors to a list and did the same for 2021.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/86b4517d35ebd87cacdb4053e31e2f5a/href">https://medium.com/media/86b4517d35ebd87cacdb4053e31e2f5a/href</a></iframe><p>Finally, I’m checking to see if there are any children’s authors in 2019 or 2021.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d49ee9081689f64d70ccb7562d3b22f6/href">https://medium.com/media/d49ee9081689f64d70ccb7562d3b22f6/href</a></iframe><p>So, drum roll: out of a total of 95 books for 2019, there are no children’s authors present, whereas, out of 97 books, there are <strong>18 books written by children’s authors in the list of best-selling books in 2021</strong>.</p><p>To be honest, this part with Selenium was quite time-consuming, and, to be <em>completely </em>frank, the result is obvious from a quick glance at the two lists on the website. However, this process allowed me to discover and get to grips with Selenium, which is still a positive point.</p><p>This brings us to the end of the analysis. I am quite happy with the result. Thanks to these web-scraping tools, I got data that was otherwise unavailable to me.</p><h3>Sources</h3><ul><li><a href="https://www.knygos.lt/lt/knygos/zanras/literatura-vaikams-ir-jaunimui/">Literatūra vaikams ir jaunimui</a></li><li><a href="https://www.15min.lt/kultura/naujiena/literatura/isaugo-knygu-pardavimas-internetu-daugiausia-vaiku-literaturos-286-1304822">Išaugo knygų pardavimas internetu, daugiausia - vaikų literatūros</a></li></ul><p><a href="https://www.knyguklubas.lt/literatura-vaikams">https://www.knyguklubas.lt/literatura-vaikams</a></p><p>Here is the code on Github :</p><p><a href="https://github.com/StMaCre/web_scrapping_youth_literature_lithuania">GitHub - StMaCre/web_scrapping_youth_literature_lithuania</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68f3f4bfb1f9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/geekculture/how-to-use-web-scraping-tools-to-gain-insight-into-a-specific-sector-68f3f4bfb1f9">How to use web scraping tools to gain insight into a specific sector?</a> was originally published in <a href="https://medium.com/geekculture">Geek Culture</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>