Begin slow migration to Hugo...

This commit is contained in:
Chris Hodapp 2020-01-31 17:46:38 -05:00
parent f12c4b3773
commit 921b0e88fc
180 changed files with 2084 additions and 285 deletions

View File

@ -1,42 +0,0 @@
#+TITLE: Dataflow paradigm (working title)
#+AUTHOR: Chris Hodapp
#+DATE: December 12, 2017
#+TAGS: technobabble
I don't know if there's actually anything to write here.
There is a sort of parallel between the declarative nature of
computational graphs in TensorFlow, and functional programming
(possibly function-level - think of the J language and how important
rank is to its computations).
Apache Spark and TensorFlow are very similar in a lot of ways. The
key difference I see is that Spark handles different types of data
internally that are more suited to databases, reords, tables, and
generally relational data, while TensorFlow is, well, tensors
(arbitrary-dimensional arrays).
The interesting part to me with both of these is how they've moved
"bulk" computations into first-class objects (ish) and permitted some
level of introspection into them before they run, as they run, and
after they run. Like I noted in Notes - Paper, 2016-11-13, "One
interesting (to me) facet is how the computation process has been
split out and instrumented enough to allow some meaningful
introspection with it. It hasn't precisely made it a first-class
construct, but still, this feature pervades all of Spark's major
abstractions (RDD, DataFrame, Dataset)."
# Show Tensorboard example here
# Screenshots may be a good idea too
Spark does this with a database. TensorFlow does it with numerical
calculations. Node-RED does it with irregular, asynchronous data.
- [[https://mxnet.incubator.apache.org/how_to/visualize_graph.html][mxnet: How to visualize Neural Networks as computation graph]]
- [[https://medium.com/intuitionmachine/pytorch-dynamic-computational-graphs-and-modular-deep-learning-7e7f89f18d1][PyTorch, Dynamic Computational Graphs and Modular Deep Learning]]
- [[https://github.com/WarBean/hyperboard][HyperBoard: A web-based dashboard for Deep Learning]]
- [[https://www.postgresql.org/docs/current/static/sql-explain.html][EXPLAIN in PostgreSQL]]
- http://tatiyants.com/postgres-query-plan-visualization/
- https://en.wikipedia.org/wiki/Dataflow_programming
- Pure Data!
- [[https://en.wikipedia.org/wiki/Orange_(software)][Orange]]?

View File

@ -1,193 +0,0 @@
---
title: Collaborative Filtering with Slope One Predictors
author: Chris Hodapp
date: January 30, 2018
tags: technobabble, machine learning
---
# Needs a brief intro
# Needs a summary at the end
Suppose you have a large number of users, and a large number of
movies. Users have watched movies, and they've provided ratings for
some of them (perhaps just simple numerical ratings, 1 to 10 stars).
However, they've all watched different movies, and for any given user,
it's only a tiny fraction of the total movies.
Now, you want to predict how some user will rate some movie they
haven't rated, based on what they (and other users) have rated.
That's a common problem, especially when generalized from 'movies' to
anything else, and one with many approaches. (To put some technical
terms to it, this is the [[https://en.wikipedia.org/wiki/Collaborative_filtering][collaborative filtering]] approach to
[[https://en.wikipedia.org/wiki/Recommender_system][recommender systems]]. [[http://www.mmds.org/][Mining of Massive Datasets]] is an excellent free
text in which to read more in depth on this, particularly chapter 9.)
Slope One Predictors are one such approach to collaborative filtering,
described in the paper [[https://arxiv.org/pdf/cs/0702144v1.pdf][Slope One Predictors for Online Rating-Based
Collaborative Filtering]]. Despite the complex-sounding name, they are
wonderfully simple to understand and implement, and very fast.
I'll give a contrived example below to explain them.
Consider a user Bob. Bob is enthusiastic, but has rather simple
tastes: he mostly just watches Clint Eastwood movies. In fact, he's
watched and rated nearly all of them, and basically nothing else.
Now, suppose we want to predict how much Bob will like something
completely different and unheard of (to him at least), like... I don't
know... /Citizen Kane/.
Here's Slope One in a nutshell:
1. First, find the users who rated both /Citizen Kane/ *and* any of
the Clint Eastwood movies that Bob rated.
2. Now, for each movie that comes up above, compute a *deviation*
which tells us: On average, how differently (i.e. how much higher
or lower) did users rate Citizen Kane compared to this movie? (For
instance, we'll have a number for how /Citizen Kane/ was rated
compared to /Dirty Harry/, and perhaps it's +0.6 - meaning that on
average, users who rated both movies rated /Citizen Kane/ about 0.6
stars above /Dirty Harry/. We'd have another deviation for
/Citizen Kane/ compared to /Gran Torino/, another for /Citizen
Kane/ compared to /The Good, the Bad and the Ugly/, and so on - for
every movie that Bob rated, provided that other users who rated
/Citizen Kane/ also rated the movie.)
3. If that deviation between /Citizen Kane/ and /Dirty Harry/ was
+0.6, it's reasonable that adding 0.6 from Bob's rating on /Dirty
Harry/ would give one prediction of how Bob might rate /Citizen
Kane/. We can then generate more predictions based on the ratings
he gave the other movies - anything for which we could compute a
deviation.
4. To turn this to a single prediction, we could just average all
those predictions together.
One variant, Weighted Slope One, is nearly identical. The only
difference is in how we average those predictions in step #4. In
Slope One, every deviation counts equally, no matter how many users
had differences in ratings averaged together to produce it. In
Weighted Slope One, deviations that came from larger numbers of users
count for more (because, presumably, they are better estimates).
Or, in other words: If only one person rated both /Citizen Kane/ and
the lesser-known Eastwood classic /Revenge of the Creature/, and they
happened to think that /Revenge of the Creature/ deserved at least 3
more stars, then with Slope One, this deviation of -3 would carry
exactly as much weight as thousands of people rating /Citizen Kane/ as
about 0.5 stars below /The Good, the Bad and the Ugly/. In Weighted
Slope One, that latter deviation would count for thousands of times as
much. The example makes it sound a bit more drastic than it is.
The Python library [[http://surpriselib.com/][Surprise]] (a [[https://www.scipy.org/scikits.html][scikit]]) has an implementation of this
algorithm, and the Benchmarks section of that page shows its
performance compared to some other methods.
/TODO/: Show a simple Python implementation of this (Jupyter
notebook?)
* Linear Algebra Tricks
Those who aren't familiar with matrix methods or algebra can probably
skip this section. Everything I've described above, you can compute
given just some data to work with ([[https://grouplens.org/datasets/movielens/100k/][movielens 100k]], perhaps?) and some
basic arithmetic. You don't need any complicated numerical methods.
However, the entire Slope One method can be implemented in a very fast
and simple way with a couple matrix operations.
First, we need to have our data encoded as a *utility matrix*. In a
utility matrix, each row represents one user, each column represents
one item (a movie, in our case), and each element represents a user's
rating of an item. If we have $n$ users and $m$ movies, then this a
$n \times m$ matrix $U$ for which $U_{k,i}$ is user $k$'s rating for
movie $i$ - assuming we've numbered our users and our movies.
Users have typically rated only a fraction of movies, and so most of
the elements of this matrix are unknown. We can represent this with
another $n \times m$ matrix (specifically a binary matrix), a 'mask'
$M$ in which $M_{k,i}$ is 1 if user $k$ supplied a rating for movie
$i$, and otherwise 0.
I mentioned *deviation* above and gave an informal definition of it.
The paper gaves a formal but rather terse definition below of the
average deviation of item $i$ with respect to item $j$:
$$\textrm{dev}_{j,i} = \sum_{u \in S_{j,i}(\chi)} \frac{u_j - u_i}{card(S_{j,i}(\chi))}$$
where:
- $u_j$ and $u_i$ mean: user $u$'s ratings for movies $i$ and $j$, respectively
- $u \in S_{j,i}(\chi)$ means: all users $u$ who, in the dataset we're
training on, provided a rating for both movie $i$ and movie $j$
- $card$ is the cardinality of that set, i.e. for
${card(S_{j,i}(\chi))}$ it is just how many users rated both $i$ and
$j$.
That denominator does depend on $i$ and $j$, but doesn't depend on the
summation term, so it can be pulled out, and also, we can split up the
summation as long as it is kept over the same terms:
$$\textrm{dev}_{j,i} = \frac{1}{card(S_{j,i}(\chi))} \sum_{u \in
S_{j,i}(\chi)} u_j - u_i = \frac{1}{card(S_{j,i}(\chi))}\left(\sum_{u
\in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i\right)$$
# TODO: These need some actual matrices to illustrate
Let's start with computing ${card(S_{j,i}(\chi))}$, the number of
users who rated both movie $i$ and movie $j$. Consider column $i$ of
the mask $M$. For each value in this column, it equals 1 if the
respective user rated movie $i$, or 0 if they did not. Clearly,
simply summing up column $i$ would tell us how many users rated movie
$i$, and the same applies to column $j$ for movie $j$.
Now, suppose we take element-wise logical AND of columns $i$ and $j$.
The resultant column has a 1 only where both corresponding elements
were 1 - where a user rated both $i$ and $j$. If we sum up this
column, we have exactly the number we need: the number of users who
rated both $i$ and $j$.
Some might notice that "elementwise logical AND" is just "elementwise
multiplication", thus "sum of elementwise logical AND" is just "sum of
elementwise multiplication", which is: dot product. That is,
${card(S_{j,i}(\chi))}=M_j \bullet M_i$ if we use $M_i$ and $M_j$ for
columns $i$ and $j$ of $M$.
However, we'd like to compute deviation as a matrix for all $i$ and
$j$, so we'll likewise need ${card(S_{j,i}(\chi))}$ for every single
combination of $i$ and $j$ - that is, we need a dot product between
every single pair of columns from $M$. Incidentally, "dot product of
every pair of columns" happens to be almost exactly matrix
multiplication; note that for matrices $A$ and $B$, element $(x,y)$ of
the matrix product $AB$ is just the dot product of /row/ $x$ of $A$
and /column/ $y$ of $B$ - and that matrix product as a whole has this
dot product between every row of $A$ and every column of $B$.
We wanted the dot product of every column of $M$ with every column of
$M$, which is easy: just transpose $M$ for one operand. Then, we can
compute our count matrix like this:
$$C=M^\top M$$
Thus $C_{i,j}$ is the dot product of column $i$ of $M$ and column $j$
of $M$ - or, the number of users who rated both movies $i$ and $j$.
That was the first half of what we needed for $\textrm{dev}_{j,i}$.
We still need the other half:
$$\sum_{u \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i$$
We can apply a similar trick here. Consider first what $\sum_{u \in
S_{j,i}(\chi)} u_j$ means: It is the sum of only those ratings of
movie $j$ that were done by a user who also rated movie $i$.
Likewise, $\sum_{u \in S_{j,i}(\chi)} u_j$ is the sum of only those
ratings of movie $i$ that were done by a user who also rated movie
$j$. (Note the symmetry: it's over the same set of users, because
it's always the users who rated both $i$ and $j$.)
# TODO: Finish that section (mostly translate from code notes)
* Implementation
#+BEGIN_SRC python
print("foo")
#+END_SRC

View File

@ -1,30 +0,0 @@
#+TITLE: Untitled rant on machine learning hype
#+AUTHOR: Chris Hodapp
#+DATE: February 24, 2018
#+TAGS: technobabble
The present state in machine learning feels like an arms-race for
techniques that perfomr better, faster, more efficient, or whatever on
a handful of problems, and not much in terms of killer applications
that actually need this.
We've all been hearing for a few years about the demand here but
mostly there seems a dearth of companies that actually have any sort
of sustained vision for actual uses of machine learning. Plenty exist
that have grand promises, and plenty of large companies keep trying to
acquire all talent to further that arms race, but that's about it.
Certainly this will change as machine learning "gets better" but in
order for a lot of improvement to occur there must be at the same time
some actual compelling ideas and applications to drive it.
In that sense I don't believe that crrent advancements will be that
fruitful on their own. We don't need optimizations, we need
applications.
Of course this is not the first time a entire industry was imagined
and hyped based on neat technology and little else...
Right now I feel as though the work is going to those who can actually
articulate the "why" in specific terms, not those with some good
knowledge primarily on the "how".

33
hugo_blag/.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
# Created by https://www.gitignore.io/api/macos
# Edit at https://www.gitignore.io/?templates=macos
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# End of https://www.gitignore.io/api/macos

View File

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

4
hugo_blag/config.toml Normal file
View File

@ -0,0 +1,4 @@
baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"
theme = "indigo"

View File

@ -2,7 +2,8 @@
title: Fun with NX stuff title: Fun with NX stuff
date: October 15, 2009 date: October 15, 2009
author: Chris Hodapp author: Chris Hodapp
tags: Technobabble tags:
- Technobabble
--- ---
So, I was trying out various NX servers because I'd had very good luck So, I was trying out various NX servers because I'd had very good luck

View File

@ -2,7 +2,8 @@
title: "Processing: DLA, quadtrees" title: "Processing: DLA, quadtrees"
date: July 4th, 2010 date: July 4th, 2010
author: Chris Hodapp author: Chris Hodapp
tags: processing tags:
- processing
--- ---
I first dabbled with I first dabbled with

View File

@ -2,7 +2,9 @@
title: Blender from a recovering POV-Ray user title: Blender from a recovering POV-Ray user
date: February 7, 2011 date: February 7, 2011
author: Chris Hodapp author: Chris Hodapp
tags: CG, blender tags:
- CG
- blender
--- ---
This is about the tenth time I've tried to learn This is about the tenth time I've tried to learn

View File

@ -2,7 +2,9 @@
title: I can never win that context back title: I can never win that context back
date: June 10, 2011 date: June 10, 2011
author: Chris Hodapp author: Chris Hodapp
tags: Journal, rant tags:
- Journal
- rant
--- ---
I stumbled upon this: I stumbled upon this:

View File

@ -2,7 +2,9 @@
title: OpenFrameworks, try 1... title: OpenFrameworks, try 1...
date: June 13, 2011 date: June 13, 2011
author: Chris Hodapp author: Chris Hodapp
tags: Technobabble, rant tags:
- Technobabble
- rant
--- ---
My attempts at doing things with My attempts at doing things with

View File

@ -1,7 +1,10 @@
--- ---
title: My experiences with Apache Axis2/C title: My experiences with Apache Axis2/C
date: July 15, 2011 date: July 15, 2011
tags: Project, rant, Technobabble tags:
- Project
- rant
- Technobabble
author: Chris Hodapp author: Chris Hodapp
--- ---

View File

@ -1,8 +1,11 @@
--- ---
title: Isolated-pixel-pushing title: Isolated-pixel-pushing
tags: CG, Project, Technobabble
date: August 27, 2011 date: August 27, 2011
author: Chris Hodapp author: Chris Hodapp
tags:
- CG
- Project
- Technobabble
--- ---
After finally deciding to look around for some projects on GitHub, I After finally deciding to look around for some projects on GitHub, I

View File

@ -1,8 +1,11 @@
--- ---
title: Context Free title: Context Free
date: August 29, 2011 date: August 29, 2011
tags: CG, Project, Technobabble
author: Chris Hodapp author: Chris Hodapp
tags:
- CG
- Project
- Technobabble
--- ---
My [last post](./2011-08-27-isolated-pixel-pushing.html) mentioned a My [last post](./2011-08-27-isolated-pixel-pushing.html) mentioned a

View File

@ -1,8 +1,10 @@
--- ---
title: "QMake hackery: Dependencies & external preprocessing" title: "QMake hackery: Dependencies & external preprocessing"
tags: Project, Technobabble
date: November 13, 2011 date: November 13, 2011
author: Chris Hodapp author: Chris Hodapp
tags:
- Project
- Technobabble
--- ---
* TODO: Put the code here into a Gist? * TODO: Put the code here into a Gist?

View File

@ -2,7 +2,10 @@
title: Obscure features of JPEG title: Obscure features of JPEG
author: Chris Hodapp author: Chris Hodapp
date: November 24, 2011 date: November 24, 2011
tags: Technobabble, jpeg, image_compression tags:
- Technobabble
- jpeg
- image_compression
--- ---
*(This is a modified version of what I wrote up at work when I saw *(This is a modified version of what I wrote up at work when I saw

View File

@ -1,10 +1,12 @@
--- ---
layout: post layout: post
title: Thoughts on tools, design, and feedback loops title: Thoughts on tools, design, and feedback loops
tags: rant, Technobabble
status: publish status: publish
type: post type: post
published: true published: true
tags:
- rant
- Technobabble
--- ---
I just watched [Inventing on Principle](https://vimeo.com/36579366) from Bret Victor and found this entire talk incredibly interesting. Chris Granger's [post](http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/) on Light Table led me to this, and shortly after, I found the redesigned [Khan Academy CS course](http://ejohn.org/blog/introducing-khan-cs) which this inspired. Bret touched on something that basically anyone who's attempted to design anything has implicitly understood: **This feedback loop is the most essential part of the process.** I just watched [Inventing on Principle](https://vimeo.com/36579366) from Bret Victor and found this entire talk incredibly interesting. Chris Granger's [post](http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/) on Light Table led me to this, and shortly after, I found the redesigned [Khan Academy CS course](http://ejohn.org/blog/introducing-khan-cs) which this inspired. Bret touched on something that basically anyone who's attempted to design anything has implicitly understood: **This feedback loop is the most essential part of the process.**

View File

@ -2,7 +2,9 @@
title: "Catalogue of My Stupidity: My Haskell 'GenericStruct' Nonsense" title: "Catalogue of My Stupidity: My Haskell 'GenericStruct' Nonsense"
author: Chris Hodapp author: Chris Hodapp
date: June 23, 2015 date: June 23, 2015
tags: stupidity, Technobabble tags:
- stupidity
- Technobabble
--- ---
*(A note: I took these notes during my time at Urbanalta, intending *(A note: I took these notes during my time at Urbanalta, intending

View File

@ -2,7 +2,9 @@
title: Post at HaskellEmbedded - Introducing Ion title: Post at HaskellEmbedded - Introducing Ion
author: Chris Hodapp author: Chris Hodapp
date: September 23, 2016 date: September 23, 2016
tags: haskell, haskellembedded tags:
- haskell
- haskellembedded
--- ---
Just a quick note: I finally released my Ion library (it was long Just a quick note: I finally released my Ion library (it was long

View File

@ -2,7 +2,10 @@
title: "Pi pan-tilt for huge images, part 1: introduction" title: "Pi pan-tilt for huge images, part 1: introduction"
author: Chris Hodapp author: Chris Hodapp
date: September 23, 2016 date: September 23, 2016
tags: photography, electronics, raspberrypi tags:
- photography
- electronics
- raspberrypi
--- ---
Earlier this year I was turning around ideas in my head - perhaps Earlier this year I was turning around ideas in my head - perhaps

View File

@ -2,7 +2,10 @@
title: "Pi pan-tilt for huge images, part 2: Hugin & PanoTools integration" title: "Pi pan-tilt for huge images, part 2: Hugin & PanoTools integration"
author: Chris Hodapp author: Chris Hodapp
date: October 4, 2016 date: October 4, 2016
tags: photography, electronics, raspberrypi tags:
- photography
- electronics
- raspberrypi
--- ---
In my [last post](./2016-09-25-pi-pan-tilt-1.html) I introduced some In my [last post](./2016-09-25-pi-pan-tilt-1.html) I introduced some

View File

@ -2,7 +2,10 @@
title: "Pi pan-tilt for huge images, part 3: ArduCam & raw images" title: "Pi pan-tilt for huge images, part 3: ArduCam & raw images"
author: Chris Hodapp author: Chris Hodapp
date: October 12, 2016 date: October 12, 2016
tags: photography, electronics, raspberrypi tags:
- photography
- electronics
- raspberrypi
--- ---
This is the third part in this series, continuing on from This is the third part in this series, continuing on from

View File

@ -2,7 +2,8 @@
title: "CincyFP presentation: R & Feature Transformation" title: "CincyFP presentation: R & Feature Transformation"
author: Chris Hodapp author: Chris Hodapp
date: December 13, 2016 date: December 13, 2016
tags: r, cincyfp tags:
- r, cincyfp
--- ---
Another cross-post (sort of): The slides and notebooks from my Another cross-post (sort of): The slides and notebooks from my

View File

@ -2,7 +2,8 @@
title: Some Python asyncio disambiguation title: Some Python asyncio disambiguation
author: Chris Hodapp author: Chris Hodapp
date: March 9, 2018 date: March 9, 2018
tags: technobabble tags:
- technobabble
--- ---
# TODO: Generators? Is it accurate that prior to all this, coroutines # TODO: Generators? Is it accurate that prior to all this, coroutines

View File

@ -2,7 +2,11 @@
title: "Recommender Systems, Part 1 (Collaborative Filtering)" title: "Recommender Systems, Part 1 (Collaborative Filtering)"
author: Chris Hodapp author: Chris Hodapp
date: May 6, 2018 date: May 6, 2018
tags: machine_learning, technobabble, notebook, literate tags:
- machine_learning
- technobabble
- notebook
- literate
--- ---
This is an exported version of the Jupyter notebook available at my This is an exported version of the Jupyter notebook available at my
@ -845,18 +849,22 @@ eyes glaze over, you can probably just skip this section.
Let $U$ be the utility matrix. Let $M$ be a binary matrix for which $M_{i,j}=1$ if user $i$ rated movie $j$, otherwise 0. Compute the model's matrices with: Let $U$ be the utility matrix. Let $M$ be a binary matrix for which $M_{i,j}=1$ if user $i$ rated movie $j$, otherwise 0. Compute the model's matrices with:
<div>
$$ $$
\begin{align} \begin{align}
C & =M^\top M \\ C & =M^\top M \\
D &= \left(M^\top U - (M^\top U)^\top\right) /\ \textrm{max}(1, M^\top M) D &= \left(M^\top U - (M^\top U)^\top\right) /\ \textrm{max}(1, M^\top M)
\end{align} \end{align}
$$ $$
</div>
where $/$ is Hadamard (i.e. elementwise) division, and $\textrm{max}$ is elementwise maximum with 1. Then, the below gives the prediction for how user $u$ will rate movie $j$: where $/$ is Hadamard (i.e. elementwise) division, and $\textrm{max}$ is elementwise maximum with 1. Then, the below gives the prediction for how user $u$ will rate movie $j$:
<div>
$$ $$
P(u)_j = \frac{[M_u \odot (C_j > 0)] \cdot (D_j + U_u) - U_{u,j}}{M_u \cdot (C_j > 0)} P(u)_j = \frac{[M_u \odot (C_j > 0)] \cdot (D_j + U_u) - U_{u,j}}{M_u \cdot (C_j > 0)}
$$ $$
</div>
$D_j$ and $C_j$ are row $j$ of $D$ and $C$, respectively. $M_u$ and $U_u$ are column $u$ of $M$ and $U$, respectively. $\odot$ is elementwise multiplication. $D_j$ and $C_j$ are row $j$ of $D$ and $C$, respectively. $M_u$ and $U_u$ are column $u$ of $M$ and $U$, respectively. $\odot$ is elementwise multiplication.
@ -878,6 +886,7 @@ The paper gaves a formal but rather terse definition below of the
average deviation of item $i$ with respect to item $j$, and I average deviation of item $i$ with respect to item $j$, and I
then separate out the summation a little: then separate out the summation a little:
<div>
$$ $$
\begin{split} \begin{split}
\textrm{dev}_{j,i} &= \sum_{u \in S_{j,i}(\chi)} \frac{u_j - u_i}{card(S_{j,i}(\chi))} \\ \textrm{dev}_{j,i} &= \sum_{u \in S_{j,i}(\chi)} \frac{u_j - u_i}{card(S_{j,i}(\chi))} \\
@ -886,6 +895,7 @@ S_{j,i}(\chi)} u_j - u_i = \frac{1}{card(S_{j,i}(\chi))}\left(\sum_{u
\in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i\right) \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i\right)
\end{split} \end{split}
$$ $$
</div>
where: where:
@ -922,7 +932,9 @@ combination of $i$ and $j$ - that is, we need a dot product between
every single pair of columns from $M$. This is incidentally just every single pair of columns from $M$. This is incidentally just
matrix multiplication: matrix multiplication:
<div>
$$C=M^\top M$$ $$C=M^\top M$$
</div>
since $C_{i,j}=card(S_{j,i}(\chi))$ is the dot product of row $i$ of $M^T$ - which is column since $C_{i,j}=card(S_{j,i}(\chi))$ is the dot product of row $i$ of $M^T$ - which is column
$i$ of $M$ - and column $j$ of $M$. $i$ of $M$ - and column $j$ of $M$.
@ -930,7 +942,9 @@ $i$ of $M$ - and column $j$ of $M$.
That was the first half of what we needed for $\textrm{dev}_{j,i}$. That was the first half of what we needed for $\textrm{dev}_{j,i}$.
We still need the other half: We still need the other half:
<div>
$$\sum_{u \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i$$ $$\sum_{u \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i$$
</div>
We can apply a similar trick here. Consider first what $\sum_{u \in We can apply a similar trick here. Consider first what $\sum_{u \in
S_{j,i}(\chi)} u_j$ means: It is the sum of only those ratings of S_{j,i}(\chi)} u_j$ means: It is the sum of only those ratings of
@ -946,18 +960,24 @@ of movie $i$, but we want only the sum of the ratings done by a user
who also rated movie $j$. Like before, the dot product of $U_i$ and who also rated movie $j$. Like before, the dot product of $U_i$ and
$M_j$ (consider the definition of $M_j$) computes this, and so: $M_j$ (consider the definition of $M_j$) computes this, and so:
<div>
$$\sum_{u \in S_{j,i}(\chi)} u_j = M_i \cdot U_j$$ $$\sum_{u \in S_{j,i}(\chi)} u_j = M_i \cdot U_j$$
</div>
and as with $C$, since we want every pairwise dot product, this summation just and as with $C$, since we want every pairwise dot product, this summation just
equals element $(i,j)$ of $M^\top U$. The other half of the summation, equals element $(i,j)$ of $M^\top U$. The other half of the summation,
$\sum_{u \in S_{j,i}(\chi)} u_i$, equals $M_j \cdot U_i$, which is just $\sum_{u \in S_{j,i}(\chi)} u_i$, equals $M_j \cdot U_i$, which is just
the transpose of this matrix: the transpose of this matrix:
<div>
$$\sum_{u \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i = M^\top U - (M^\top U)^\top = M^\top U - U^\top M$$ $$\sum_{u \in S_{j,i}(\chi)} u_j - \sum_{u \in S_{j,i}(\chi)} u_i = M^\top U - (M^\top U)^\top = M^\top U - U^\top M$$
</div>
So, finally, we can compute an entire deviation matrix at once like: So, finally, we can compute an entire deviation matrix at once like:
<div>
$$D = \left(M^\top U - (M^\top U)^\top\right) /\ M^\top M$$ $$D = \left(M^\top U - (M^\top U)^\top\right) /\ M^\top M$$
</div>
where $/$ is Hadamard (i.e. elementwise) division, and $D_{j,i} = \textrm{dev}_{j,i}$. where $/$ is Hadamard (i.e. elementwise) division, and $D_{j,i} = \textrm{dev}_{j,i}$.
@ -967,21 +987,27 @@ By convention and to avoid division by zero, we treat the case where the denomin
Finally, the paper gives the formula to predict how user $u$ will rate movie $j$, and I write this in terms of our matrices: Finally, the paper gives the formula to predict how user $u$ will rate movie $j$, and I write this in terms of our matrices:
<div>
$$ $$
P(u)_j = \frac{1}{card(R_j)}\sum_{i\in R_j} \left(\textrm{dev}_{j,i}+u_i\right) = \frac{1}{card(R_j)}\sum_{i\in R_j} \left(D_{j,i} + U_{u,j} \right) P(u)_j = \frac{1}{card(R_j)}\sum_{i\in R_j} \left(\textrm{dev}_{j,i}+u_i\right) = \frac{1}{card(R_j)}\sum_{i\in R_j} \left(D_{j,i} + U_{u,j} \right)
$$ $$
</div>
where $R_j = \{i | i \in S(u), i \ne j, card(S_{j,i}(\chi)) > 0\}$, and $S(u)$ is the set of movies that user $u$ has rated. To unpack the paper's somewhat dense notation, the summation is over every movie $i$ that user $u$ rated and that at least one other user rated, except movie $j$. where $R_j = \{i | i \in S(u), i \ne j, card(S_{j,i}(\chi)) > 0\}$, and $S(u)$ is the set of movies that user $u$ has rated. To unpack the paper's somewhat dense notation, the summation is over every movie $i$ that user $u$ rated and that at least one other user rated, except movie $j$.
We can apply the usual trick yet one more time with a little effort. The summation already goes across a row of $U$ and $D$ (that is, user $u$ is held constant), but covers only certain elements. This is equivalent to a dot product with a mask representing $R_j$. $M_u$, row $u$ of the mask, already represents $S(u)$, and $R_j$ is just $S(u)$ with some more elements removed - which we can mostly represent with $M_u \odot (C_j > 0)$ where $\odot$ is elementwise product (i.e. Hadamard), $C_j$ is column/row $j$ of $C$ (it's symmetric), and where we abuse some notation to say that $C_j > 0$ is a binary vector. Likewise, $D_j$ is row $j$ of $D$. The one correction still required is that we subtract $u_j$ to cover for the $i \ne j$ part of $R_j$. To abuse some more notation: We can apply the usual trick yet one more time with a little effort. The summation already goes across a row of $U$ and $D$ (that is, user $u$ is held constant), but covers only certain elements. This is equivalent to a dot product with a mask representing $R_j$. $M_u$, row $u$ of the mask, already represents $S(u)$, and $R_j$ is just $S(u)$ with some more elements removed - which we can mostly represent with $M_u \odot (C_j > 0)$ where $\odot$ is elementwise product (i.e. Hadamard), $C_j$ is column/row $j$ of $C$ (it's symmetric), and where we abuse some notation to say that $C_j > 0$ is a binary vector. Likewise, $D_j$ is row $j$ of $D$. The one correction still required is that we subtract $u_j$ to cover for the $i \ne j$ part of $R_j$. To abuse some more notation:
<div>
$$P(u)_j = \frac{[M_u \odot (C_j > 0)] \cdot (D_j + U_u) - U_{u,j}}{M_u \cdot (C_j > 0)}$$ $$P(u)_j = \frac{[M_u \odot (C_j > 0)] \cdot (D_j + U_u) - U_{u,j}}{M_u \cdot (C_j > 0)}$$
</div>
#### 5.2.2.4. Approximation #### 5.2.2.4. Approximation
The paper also gives a formula that is a suitable approximation for larger data sets: The paper also gives a formula that is a suitable approximation for larger data sets:
<div>
$$p^{S1}(u)_j = \bar{u} + \frac{1}{card(R_j)}\sum_{i\in R_j} \textrm{dev}_{j,i}$$ $$p^{S1}(u)_j = \bar{u} + \frac{1}{card(R_j)}\sum_{i\in R_j} \textrm{dev}_{j,i}$$
</div>
where $\bar{u}$ is user $u$'s average rating. This doesn't change the formula much; we can compute $\bar{u}$ simply as column means of $U$. where $\bar{u}$ is user $u$'s average rating. This doesn't change the formula much; we can compute $\bar{u}$ simply as column means of $U$.
@ -1145,13 +1171,17 @@ Matrices $Q$ and $P$ have some other neat properties too. Note that $Q$ has $m$
In that sense, $P$ and $Q$ give us a model in which ratings are an interaction between properties of a movie, and a user's preferences. If we're using $U=P^\top Q$ as our model, then every element of $U$ is just the dot product of the feature vectors of the respective movie and user. That is, if $p_u$ is column $u$ of $P$ and $q_i$ is column $i$ of $Q$: In that sense, $P$ and $Q$ give us a model in which ratings are an interaction between properties of a movie, and a user's preferences. If we're using $U=P^\top Q$ as our model, then every element of $U$ is just the dot product of the feature vectors of the respective movie and user. That is, if $p_u$ is column $u$ of $P$ and $q_i$ is column $i$ of $Q$:
<div>
$$\hat{r}_{ui}=q_i^\top p_u$$ $$\hat{r}_{ui}=q_i^\top p_u$$
</div>
However, some things aren't really interactions. Some movies are just (per the ratings) overall better or worse. Some users just tend to rate everything higher or lower. We need some sort of bias built into the model to comprehend this. However, some things aren't really interactions. Some movies are just (per the ratings) overall better or worse. Some users just tend to rate everything higher or lower. We need some sort of bias built into the model to comprehend this.
Let's call $b_i$ the bias for movie $i$, $b_u$ the bias for user $u$, and $\mu$ the overall average rating. We can just add these into the model: Let's call $b_i$ the bias for movie $i$, $b_u$ the bias for user $u$, and $\mu$ the overall average rating. We can just add these into the model:
<div>
$$\hat{r}_{ui}=\mu + b_i + b_u + q_i^\top p_u$$ $$\hat{r}_{ui}=\mu + b_i + b_u + q_i^\top p_u$$
</div>
This is the basic model we'll implement, and the same one described in the references at the top. This is the basic model we'll implement, and the same one described in the references at the top.
@ -1159,7 +1189,9 @@ This is the basic model we'll implement, and the same one described in the refer
More formally, the prediction model is: More formally, the prediction model is:
<div>
$$\hat{r}_{ui}=\mu + b_i + b_u + q_i^\top p_u$$ $$\hat{r}_{ui}=\mu + b_i + b_u + q_i^\top p_u$$
</div>
where: where:
@ -1179,6 +1211,7 @@ $$E=\sum_{r_{ui} \in R_{\textrm{train}}} \left(r_{ui} - \hat{r}_{ui}\right)^2 +
This error function is easily differentiable with respect to model parameters $b_i$, $b_u$, $q_i$, and $p_u$, so a normal approach for minimizing it is gradient-descent. Finding gradient with respect to $b_i$ is straightforward: This error function is easily differentiable with respect to model parameters $b_i$, $b_u$, $q_i$, and $p_u$, so a normal approach for minimizing it is gradient-descent. Finding gradient with respect to $b_i$ is straightforward:
<div>
$$ $$
\begin{split} \begin{split}
\frac{\partial E}{\partial b_i} &= \sum_{r_{ui}} \frac{\partial}{\partial b_i} \left(r_{ui} - (\mu + b_i + b_u + q_i^\top p_u)\right)^2 + \frac{\partial}{\partial b_i}\lambda\left(b_i^2+b_u^2 + \lvert\lvert q_i\rvert\rvert^2 + \lvert\lvert p_u\rvert\rvert^2\right) \\ \frac{\partial E}{\partial b_i} &= \sum_{r_{ui}} \frac{\partial}{\partial b_i} \left(r_{ui} - (\mu + b_i + b_u + q_i^\top p_u)\right)^2 + \frac{\partial}{\partial b_i}\lambda\left(b_i^2+b_u^2 + \lvert\lvert q_i\rvert\rvert^2 + \lvert\lvert p_u\rvert\rvert^2\right) \\
@ -1186,9 +1219,11 @@ $$
\frac{\partial E}{\partial b_i} &= 2 \sum_{r_{ui}} \left(\lambda b_i + r_{ui} - \hat{r}_{ui}\right) \frac{\partial E}{\partial b_i} &= 2 \sum_{r_{ui}} \left(\lambda b_i + r_{ui} - \hat{r}_{ui}\right)
\end{split} \end{split}
$$ $$
</div>
Gradient with respect to $p_u$ proceeds similarly: Gradient with respect to $p_u$ proceeds similarly:
<div>
$$ $$
\begin{split} \begin{split}
\frac{\partial E}{\partial p_u} &= \sum_{r_{ui}} \frac{\partial}{\partial p_u} \left(r_{ui} - (\mu + b_i + b_u + q_i^\top p_u)\right)^2 + \frac{\partial}{\partial p_u}\lambda\left(b_i^2+b_u^2 + \lvert\lvert q_i\rvert\rvert^2 + \lvert\lvert p_u\rvert\rvert^2\right) \\ \frac{\partial E}{\partial p_u} &= \sum_{r_{ui}} \frac{\partial}{\partial p_u} \left(r_{ui} - (\mu + b_i + b_u + q_i^\top p_u)\right)^2 + \frac{\partial}{\partial p_u}\lambda\left(b_i^2+b_u^2 + \lvert\lvert q_i\rvert\rvert^2 + \lvert\lvert p_u\rvert\rvert^2\right) \\
@ -1198,9 +1233,11 @@ p_u}q_i^\top p_u \right) + 2 \lambda p_u \\
\frac{\partial E}{\partial p_u} &= 2 \sum_{r_{ui}} \lambda p_u - \left(r_{ui} - \hat{r}_{ui}\right)q_i^\top \frac{\partial E}{\partial p_u} &= 2 \sum_{r_{ui}} \lambda p_u - \left(r_{ui} - \hat{r}_{ui}\right)q_i^\top
\end{split} \end{split}
$$ $$
</div>
Gradient with respect to $b_u$ is identical form to $b_i$, and gradient with respect to $q_i$ is identical form to $p_u$, except that the variables switch places. The full gradients then have the standard form for gradient descent, i.e. a summation of a gradient term for each individual data point, so they turn easily into update rules for each parameter (which match the ones in the Surprise link) after absorbing the leading 2 into learning rate $\gamma$ and separating out the summation over each data point. That's given below, with $e_{ui}=r_{ui} - \hat{r}_{ui}$: Gradient with respect to $b_u$ is identical form to $b_i$, and gradient with respect to $q_i$ is identical form to $p_u$, except that the variables switch places. The full gradients then have the standard form for gradient descent, i.e. a summation of a gradient term for each individual data point, so they turn easily into update rules for each parameter (which match the ones in the Surprise link) after absorbing the leading 2 into learning rate $\gamma$ and separating out the summation over each data point. That's given below, with $e_{ui}=r_{ui} - \hat{r}_{ui}$:
<div>
$$ $$
\begin{split} \begin{split}
\frac{\partial E}{\partial b_i} &= 2 \sum_{r_{ui}} \left(\lambda b_i + e_{ui}\right)\ \ \ &\longrightarrow b_i' &= b_i - \gamma\frac{\partial E}{\partial b_i} &= b_i + \gamma\left(e_{ui} - \lambda b_u \right) \\ \frac{\partial E}{\partial b_i} &= 2 \sum_{r_{ui}} \left(\lambda b_i + e_{ui}\right)\ \ \ &\longrightarrow b_i' &= b_i - \gamma\frac{\partial E}{\partial b_i} &= b_i + \gamma\left(e_{ui} - \lambda b_u \right) \\
@ -1209,6 +1246,7 @@ $$
\frac{\partial E}{\partial q_i} &= 2 \sum_{r_{ui}} \lambda q_i - e_{ui}p_u^\top\ \ \ &\longrightarrow q_i' &= q_i - \gamma\frac{\partial E}{\partial q_i} &= q_i + \gamma\left(e_{ui}p_u - \lambda q_i \right) \\ \frac{\partial E}{\partial q_i} &= 2 \sum_{r_{ui}} \lambda q_i - e_{ui}p_u^\top\ \ \ &\longrightarrow q_i' &= q_i - \gamma\frac{\partial E}{\partial q_i} &= q_i + \gamma\left(e_{ui}p_u - \lambda q_i \right) \\
\end{split} \end{split}
$$ $$
</div>
The code below is a direct implementation of this by simply iteratively applying the above equations for each data point - in other words, stochastic gradient descent. The code below is a direct implementation of this by simply iteratively applying the above equations for each data point - in other words, stochastic gradient descent.

View File

@ -2,7 +2,10 @@
title: "Go programming language: my totally unprompted opinions" title: "Go programming language: my totally unprompted opinions"
author: Chris Hodapp author: Chris Hodapp
date: April 13, 2018 date: April 13, 2018
tags: technobabble, go, golang tags:
- technobabble
- go
- golang
--- ---
# TODO: Link to my asyncio post # TODO: Link to my asyncio post

5
hugo_blag/notes.txt Normal file
View File

@ -0,0 +1,5 @@
- themes/indigo is from https://github.com/AngeloStavrow/indigo.git
circa 2020-01-31. I didn't feel like forking the repo to my github
in order to modify some things, so I just cloned it. Yeah, I know
that is bad practice, but I needed MathJax working and I'll
probably just end up messing around with the theme anyway.

View File

@ -0,0 +1,138 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Added entrypoints config section as described in [#73](https://github.com/AngeloStavrow/indigo/issues/73)
## [1.3.2] - 2019-10-17
### Added
- A _Support and Maintenance_ section has been added to the README, per [#64](https://github.com/AngeloStavrow/indigo/issues/64)
### Changed
- Updated the Hugo minimum version to 0.58.3
## [1.3.1] - 2019-10-03
### Fixed
- Taxonomy-based lists (e.g., lists of tags or categories) now only show posts within the selected taxonomy per [#56](https://github.com/AngeloStavrow/indigo/issues/56)
## [1.3.0] - 2019-09-30
### Added
- Adds a `mainSection` configuration parameter to set preferred content name per [#56](https://github.com/AngeloStavrow/indigo/issues/56)
### Changed
- Updated **CONTRIBUTING.md** to reflect new contributions process per [#28](https://github.com/AngeloStavrow/indigo/issues/28)
- Bumped the minimum Hugo version requirement to 0.58 to account for [#52](https://github.com/AngeloStavrow/indigo/issues/52)
### Fixed
- As part of an audit of the theme's code per [#57](https://github.com/AngeloStavrow/indigo/issues/57)
- Removed forward slashes (`/`) in URLs for better compatibility with sites that don't live at a domain root
- Fixed the location from which the theme's fonts are loaded
### Removed
- GitHub issue and pull request templates removed from the repo per [#28](https://github.com/AngeloStavrow/indigo/issues/28)
## [1.2.0] - 2019-08-31
### Added
- You can now import custom CSS from `<YOUR_HUGO_SITE>/static/css/custom.css` per [#48](https://github.com/AngeloStavrow/indigo/issues/48)
## [1.1.0] - 2019-08-28
### Changed
- Metadata now shows page title and description per [#50](https://github.com/AngeloStavrow/indigo/issues/50), thanks to [@infominer33](https://github.com/infominer33)!
### Fixed
- Breaking changes in article lists introduced in Hugo 0.57 per [#52](https://github.com/AngeloStavrow/indigo/issues/52)
- Newer/Older links in article footers now work as expected in Hugo 0.50 and later per [#54](https://github.com/AngeloStavrow/indigo/issues/54)
## [1.0.6] - 2019-06-24
### Fixed
- Fixed some copy/paste errors in CSS `font-family` definitions per [#38](https://github.com/AngeloStavrow/indigo/issues/38)
- Fixed `<h1>` font-sizing per [#41](https://github.com/AngeloStavrow/indigo/issues/41)
## [1.0.5] - 2019-06-05
### Fixed
- Cleaned up some errant whitespace thanks to [@dixonge](https://github.com/dixonge)!
## [1.0.4] - 2019-10-25
### Added
- Users can now add their Medium and LinkedIn accounts as social networks, thanks to [@RicardoBelchior](https://github.com/RicardoBelchior)!
### Changed
- Clearer process for contributing to the project ([#28](https://github.com/AngeloStavrow/indigo/issues/28))
### Fixed
- Better instructions for users that prefer a little more YAML in their lives, thanks to [@zwbetz-gh](https://github.com/zwbetz-gh)!
- Fix for broken content div in 404.html ([#21](https://github.com/AngeloStavrow/indigo/issues/21))
- The `src` URL for the site logo had an extra `/`, and now it doesn't, thanks to [@michimani](https://github.com/michimani)!
## [1.0.3] - 2019-10-21
### Added
- Users can now add their Reddit account as a social network, thanks to [@sauerj](https://github.com/sauerj)!
### Fixed
- The 404.html page now properly links back to the homepage, thanks to [@sauerj](https://github.com/sauerj)!
- Custom fonts are now loaded correctly, hopefully speeding up rendering ([#23](https://github.com/AngeloStavrow/indigo/issues/23))
- The site expected fonts to load from the site root, even if your site was installed to a subdirectory. Now they don't. ([#27](https://github.com/AngeloStavrow/indigo/issues/27))
## [1.0.2] - 2019-10-15
### Fixed
- Broken link to compare v1.0.1 against v1.0 in this change log.
- Updated example site theme name.
## [1.0.1] - 2018-10-14
### Fixed
- The Fira Code font is now part of the theme download, rather than downloading from rawgit ([#17](https://github.com/AngeloStavrow/indigo/issues/17)).
## 1.0.0 - 2018-09-30
### Added
- The first public release of the indigo theme for Hugo, along with related project documentation (including this changelog).
<!-- [Unreleased]: https://github.com/AngeloStavrow/indigo/compare/v1.3.0...HEAD -->
[1.3.2]: https://github.com/AngeloStavrow/indigo/compare/v1.3.1...v1.3.2
[1.3.1]: https://github.com/AngeloStavrow/indigo/compare/v1.3.0...v1.3.1
[1.3.0]: https://github.com/AngeloStavrow/indigo/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/AngeloStavrow/indigo/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/AngeloStavrow/indigo/compare/v1.0.6...v1.1.0
[1.0.6]: https://github.com/AngeloStavrow/indigo/compare/v1.0.5...v1.0.6
[1.0.5]: https://github.com/AngeloStavrow/indigo/compare/v1.0.4...v1.0.5
[1.0.4]: https://github.com/AngeloStavrow/indigo/compare/v1.0.3...v1.0.4
[1.0.3]: https://github.com/AngeloStavrow/indigo/compare/v1.0.2...v1.0.3
[1.0.2]: https://github.com/AngeloStavrow/indigo/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/AngeloStavrow/indigo/compare/v1.0...v1.0.1

View File

@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@angelostavrow.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -0,0 +1,18 @@
# Contributing
When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
Please note we have a code of conduct; please follow it in all your interactions with the project. You can find it [here](https://github.com/AngeloStavrow/indigo/blob/master/CODE_OF_CONDUCT.md)
## Bug Reports and Feature Requests
1. [Check GitHub](https://github.com/AngeloStavrow/indigo/issues/) for existing issues similar your report/request. If you find one, add any extra detail you might think is helpful. It's also helpful to just see how many folks are affected by the bug. That's it!
2. If you don't find an existing report for the bug you've come across, add [a new issue](https://github.com/AngeloStavrow/indigo/issues/new) outlining steps to reproduce, the expected outcome, and the actual outcome. Thoughts on how to implement the fix are welcome!
3. Project owners (right now, me) will triage these incoming reports/requests and label them appropriately. Everything will be added to the new [Theme Work kanban board](https://github.com/AngeloStavrow/indigo/projects/1).
## Pull Request Process
1. If one doesn't already exist, please start by [opening an issue](https://github.com/AngeloStavrow/indigo/issues/new) describing what you'd like to change. Remember to search first, to avoid having it closed as a duplicate.
2. Make the changes discussed. Ensure that the theme builds and continues to function as expected; you can also try building the [theme gallery to test further](https://github.com/gohugoio/hugoThemes/blob/master/README.md). Place high value on page-load speed and responsive design.
3. Update the README with any new site/page parameters as necessary. If you've added new dependencies, make sure to list them too.
4. Open a pull request and include the issue you opened in step 1 as part of the PR. Changes will be tested and, when everything's good to go, will be merged in by the project owners.

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 Angelo Stavrow
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,129 @@
# Indigo Theme
Indigo is a lightweight, responsive, typography-first theme for Hugo, marked up with [microformats2](http://microformats.org) for extra [IndieWeb](https://indieweb.org) goodness, including [IndieAuth](https://indieauth.com).
## Getting Started
These instructions will get you a copy of the project up and running on your local machine for setup and testing purposes. See deployment for notes on how to deploy the project on a live system.
### Prerequisites
This theme is built and tested against the latest version of Hugo and currently requires a minimum version of 0.58. You can check what version you're running with
```
$ hugo version
```
Follow the [upgrade instructions on the Hugo website](https://gohugo.io/getting-started/installing/#upgrade-hugo) if necessary.
### Installing
Follow the [Hugo Quickstart](https://gohugo.io/getting-started/quick-start/)'s instructions on how to add a theme; the URL you'll want to use is
```
https://github.com/AngeloStavrow/indigo.git
```
### Setup
There's a sample config.toml file in the root of the indigo theme directory (`config.toml.example`); copy it to the root of your Hugo site, and rename it to `config.toml` _after_ you've made a backup of your current config.toml file (if any).
Set up the parameters in the config file, especially those in the social and `params.indieWeb` section. Social identifiers that you leave out will not be added to the footer of the site. If you prefer to use a content type other than `post`, be sure to change the `mainSections` parameter in the config file as well. For example, if you want content of type `posts` and `updates` to show up in lists:
```toml
[params]
...
mainSections = ["posts", "updates"]
```
You can configure the theme to show info about the author; by default, this information is shown; if you'd prefer to leave it out, set `ShowBio` to `false`.
### Customization
Indigo will look for custom CSS in `<YOUR_HUGO_SITE>/static/css/custom.css`. This will let you add/override styling to your heart's content, while making it easy to keep Indigo up-to-date. See it in action on [angelostavrow.com](https://angelostavrow.com).
## Deployment
You can add a line to your `config.toml` file to set this theme as the default:
```toml
theme = "indigo"
```
Or, if you use `config.yaml`:
```yaml
theme: indigo
```
## Support and Maintenance
### Support Committment
Support is provided for the latest stable release of the theme on the latest stable release of Hugo. If something doesn't seem to be working right, please make sure you're using the latest version of both.
You can check what version of Hugo you're using by running the `hugo version` command; visit [the Hugo website](https://gohugo.io) for upgrade instructions.
To ensure you're building the latest version of Indigo, do the following from the command line:
```bash
# Go to the /themes/indigo folder
cd /path/to/themes/indigo
# Make sure you're on the 'master' branch, then pull in any changes
git checkout master
git pull
```
If everything is up to date and things still don't seem to be working correctly, please [open an issue](https://github.com/AngeloStavrow/indigo/issues/) and describe what's not working as expected.
Going forward, this support committment will be enforced by the `minVersion` property in **theme.toml**.
### Maintenance Process
Authors whose themes are included in the [Hugo showcase gallery](https://themes.gohugo.io) will be required to keep their theme working with the latest version of Hugo. To prepare for this, the following process will be instituted:
1. With every new release of Hugo, _once the_ `brew`_/_`chocolatey` _package is available_, the development system will be updated, and the [demo site](https://hello-indigo.glitch.me/) and the [theme gallery](https://github.com/gohugoio/hugoThemes/blob/master/README.md#testing-a-theme-with-the-hugo-themes-website-build-script) will be built locally.
2. If everything looks good, a short update will be posted to the demo site to confirm compatibility, with links to the release announcements for those versions Indigo and Hugo, as well as a link to this maintenance process documentation.
3. If either site doesn't build successfully, the problem will be fixed.
There are a few definitions and open questions that need to be considered here.
- New releases of Hugo are [announced](https://gohugo.io/news/) and can be subscribed to via RSS. The release date _may_ be estimated by the due date of [Hugo milestones](https://github.com/gohugoio/hugo/milestones).
- "Build successfully" means that the demo site renders as intended, and that the theme works as expected in the theme gallery. The gallery builds a standard site that shows off some common features of Hugo, and the demo site is meant to test and showcase features of Indigo.
## Indigo IndieWeb Features
A thorough writeup of the theme has been graciously written by @infominer33.
- [Indigo IndieWeb Features](https://web-work.tools/indieweb/indigo-indieweb-features/)
## Contributing
Please read [CONTRIBUTING.md](https://github.com/AngeloStavrow/indigo/blob/master/CONTRIBUTING.md) for details on the code of conduct, and the process for submitting bug reports, feature requests, and having your changes merged into the project.
## Versioning
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/AngeloStavrow/indigo/tags).
## Authors
- **Angelo Stavrow** - _Initial work_ - [AngeloStavrow](https://github.com/AngeloStavrow) on GitHub
See also the list of [contributors](https://github.com/AngeloStavrow/indigo/contributors) who participated in this project.
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
## Acknowledgments
The following open fonts are used in this theme:
- [Fira Sans](https://bboxtype.com/typefaces/FiraSans/#!layout=specimen) for heading text
- [Charter](https://practicaltypography.com/charter.html) for body text
- [Fira Code](https://github.com/tonsky/FiraCode) for monospaced text
Licenses are included in the themes `static/fonts` folder.
Most icons in the social footer are from [Font Awesome](https://fontawesome.com/). Some come directly from the service itself (e.g., Micro.blog and Glitch).

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1,54 @@
baseURL = "https://example.com/"
title = "Site Title"
copyright = "Copyright © 2018, Copyright Owner Name"
languageCode = "en-US"
theme = "indigo"
[params]
Author = "Site Author Name"
Description = "Description of website for head meta tag"
Subtitle = "A subtitle for your site"
Avatar = "images/site-logo.svg"
Biography = "A short description, a few sentences describing the author. Set the 'ShowBio' parameter to false to hide this."
ShowBio = true
PermalinkText = "🔗"
mainSections = ["post"]
# Contact/social-network identifiers for social icons
EmailAddress = "email.address@example.com"
FacebookUser = "FacebookUserName"
FlickrUser = "FlickrUserName"
GitHubUser = "GitHubUserName"
GitLabUser = "GitLabUserName"
GlitchUser = "GlitchUserName"
KeybaseUser = "KeybaseUserName"
LinkedInUser = "LinkedInUserName"
MediumUser = "MediumUserName"
MicroBlogUser = "MicroBlogUserName"
RedditUser = "RedditUserName"
StackOverflowUser = "StackOverflowUserName"
TumblrUser = "TumblrUserName"
TwitterUser = "TwitterUserName"
# These are parameters used for indieweb identity. You should set these along
# with the above email/social network parameters.
[params.indieWeb]
EmailAddress = "email.address@example.com"
FlickrUser = "FlickrUserName"
GitHubUser = "GitHubUserName"
TwitterUser = "TwitterUserName"
MicroBlogUser = "MicroBlogUserName"
Country = "CountryName"
City = "CityName"
[params.endpoints]
Auth = "https://indieauth.com/auth"
Token = "https://tokens.indieauth.com/token"
# To get webmention support, just register at webmention.io and paste the link for endpoint here.
#Webmention = "https://webmention.io/<yourusername>/webmention"
# To get micropub support, you'll need to install a Micropub endpoint at your site and put its link there.
# To get an endpoint with Hugo support, use nanopub: https://github.com/dg01d/nanopub
# It will probably require some PHP hackery though, as it's fairly basic.
#Micropub = ""
# To get microsub support, you can use Aperture from p3k. Either go to https://aperture.p3k.io or self-host it (it's open source!)
#Microsub = ""

View File

@ -0,0 +1,5 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

View File

@ -0,0 +1,42 @@
baseURL = "https://example.com/"
title = "Indigo Theme"
copyright = "Copyright © 2018, Author Name"
languageCode = "en-US"
theme = "indigo"
paginate = 3
[params]
Author = "Author Name"
Description = "Description of website for head meta tag"
Subtitle = "A subtitle for your site"
Avatar = "images/site-logo.svg"
Biography = "A short description, a few sentences describing the author. Set the 'ShowBio' parameter to false to hide this."
ShowBio = true
PermalinkText = "🔗"
# Contact/social-network identifiers for social icons
EmailAddress = "email.address@example.com"
FacebookUser = "FacebookUserName"
FlickrUser = "FlickrUserName"
GitHubUser = "GitHubUserName"
GitLabUser = "GitLabUserName"
GlitchUser = "GlitchUserName"
KeybaseUser = "KeybaseUserName"
LinkedInUser = "LinkedInUserName"
MediumUser = "MediumUserName"
MicroBlogUser = "MicroBlogUserName"
RedditUser = "RedditUserName"
StackOverflowUser = "StackOverflowUserName"
TumblrUser = "TumblrUserName"
TwitterUser = "TwitterUserName"
# These are parameters used for indieweb identity. You should set these along
# with the above email/social network parameters.
[params.indieWeb]
EmailAddress = "email.address@example.com"
FlickrUser = "FlickrUserName"
GitHubUser = "GitHubUserName"
TwitterUser = "TwitterUserName"
MicroBlogUser = "MicroBlogUserName"
Country = "CountryName"
City = "CityName"

View File

@ -0,0 +1,13 @@
---
title: "About The Theme"
menu: "main"
draft: false
---
Indigo is a lightweight theme for [Hugo][hugo] with [IndieWeb][indieweb] features baked in. It's great for longer-form blogging, placing its focus on distraction-free reading and beautiful typefaces.
Read more about the theme [here][intro].
[hugo]: https://gohugo.io
[indieweb]: https://indieweb.org/
[intro]: /post/introducing-indigo

View File

@ -0,0 +1,9 @@
---
title: "Adding Page Items"
menu: "main"
draft: false
---
Indigo supports adding a simple navigation-style menu items across the top of the site. To do so, simply add a `menu: "main"` entry in your page's front matter (TOML format shown).
If no date is included in the front matter, then the published date won't be shown (as in this page).

View File

@ -0,0 +1,57 @@
---
title: "Author Bios"
date: 2018-10-01T08:00:00-04:00
draft: false
categories: ["meta"]
tags: ["options"]
---
The bottom of every page in the theme can optionally show a short biography of the site author, including a profile picture, email link, and location.
<!--more-->
## Setting up the author bio
A set of configuration options are used for displaying the biography.
```
[params]
Author = "Author Name"
Avatar = "images/site-logo.svg"
Biography = "A short description, a few sentences describing the author. Set
the 'ShowBio' parameter to false to hide this."
ShowBio = true
[params.indieWeb]
EmailAddress = "email.address@example.com"
Country = "CountryName"
City = "CityName"
```
Specifics on each setting item are as follows:
- `Author`: Your name; this is the site author name.
- `Avatar`: The path to your profile picture. By default, it will show the theme's logo (`/static/images/site-logo.svg`).
- `Biography`: Hopefully the placeholder text here is self-explanatory; add a couple of short sentences about yourself here.
- `ShowBio`: If you prefer not to show the author bio, set this to `false`. By default, it's set to `true`.
- `EmailAddress`: The email address at which you can be contacted.
- `Country`: The name of the country in which you live.
- `City`: The name of the city in which you live.
## IndieWeb features
The following classes are used to mark up the author bio for [IndieWeb][indieweb] parsing:
| Element | Class |
| :-------------- | :-------------------------- |
| The author card | `h-card` |
| Profile picture | `u-photo` |
| Author URL* | `p-name`, `u-url`, `rel=me` |
| City | `p-locality` |
| Country | `p-country-name` |
| Email address | `u-email` |
| Biography | `p-note` |
*Author URL is set to the site's base URL.
[indieweb]: https://indieweb.org

View File

@ -0,0 +1,53 @@
---
title: "Featured Typefaces"
date: 2018-10-01T08:30:00-04:00
draft: false
categories: ["meta"]
tags: ["typography"]
---
Indigo uses a combination of three beautiful typefaces to render your words.
<!--more-->
- [Fira Sans][fira-sans] for heading text
- [Charter][charter] for body text
- [Fira Code][fira-code] for monospaced text
Licenses are included in the themes `static/fonts` folder.
Have a look at a couple of paragraphs of placeholder text using the wonderfully readable Charter:
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer eleifend nulla ac elit venenatis posuere. Sed id aliquam arcu, et malesuada lectus. **Donec et dignissim massa. Pellentesque in laoreet nibh. Pellentesque sagittis, libero quis vestibulum aliquam, ante risus imperdiet magna, at ornare dolor libero quis nunc.** Donec quis tempus purus. Cras ornare magna ac facilisis tristique. Nulla aliquet purus quis massa rutrum interdum ac at magna. Cras fermentum magna id orci viverra facilisis. Ut vitae lobortis nisl.
Sed interdum tincidunt venenatis. Sed hendrerit dictum nisi, at dignissim orci consectetur quis. Aenean sed nisl et nisl placerat euismod. Proin hendrerit nulla at rhoncus molestie. Cras eu gravida erat, vestibulum ornare diam. _Praesent nunc arcu, ultrices et risus sed, dictum mattis dui. Maecenas vitae nisl at massa porta pellentesque_. Donec eget urna eget nisl imperdiet scelerisque eget a mauris. Nam fringilla sem id vehicula rhoncus. Curabitur tincidunt massa mauris, facilisis placerat odio eleifend sit amet. Etiam nec vehicula sapien, at dignissim risus. Sed elit erat, lacinia eu vulputate at, semper eu nulla. Quisque a urna sed nulla viverra egestas nec quis nunc. Curabitur iaculis elit in orci sollicitudin suscipit.
---
And code snippets look great with Fira Code:
```
<article>
<header>
{{ if .Title }}
<h2 class="list-title"><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
{{ end }}
<p class="list-post-date">
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}">
{{ .PublishDate.Format "2 January, 2006 at 15:04 MST" }}
</time>
</p>
</header>
<div>
{{ .Summary | plainify | safeHTML }}
</div>
{{ if .Truncated }}
<p><a class="read-more" href="{{ .Permalink }}">Read more &rarr;</a></p>
{{ end }}
</article>
```
[fira-sans]: https://bboxtype.com/typefaces/FiraSans/#!layout=specimen
[charter]: https://practicaltypography.com/charter.html
[fira-code]: https://github.com/tonsky/FiraCode

View File

@ -0,0 +1,85 @@
---
title: "Introducing Indigo"
date: 2018-10-01T09:00:00-04:00
draft: false
categories: ["meta"]
tags: ["typography", "indieweb"]
---
Indigo is a lightweight theme for [Hugo][hugo] with [IndieWeb][indieweb] features baked in. It's great for longer-form blogging, placing its focus on distraction-free reading and beautiful typefaces.
<!--more-->
## IndieWeb features
A key feature of this theme is its support for IndieWeb features, including microformats and web sign-in.
### Web sign-in
Indigo handles web sign-in by setting the `authorization_endpoint` to [IndieAuth.com][indieauth]:
> IndieAuth.com is part of the [IndieWeb movement][why] to take back control of your online identity. Instead of logging in to websites as "you on Twitter" or "you on Facebook", **you should be able to log in as just "you"**.
This allows you to sign in to certain services simply by providing your site's domain name.
### microformats
Indigo marks up content with appropriate [microformats][mf2], which provides semantic definitions of your content to other software. Posts are marked up with `h-entry` classes, like `p-name`, `p-author`, and `e-content`, while the author bio is marked up with `h-card` classes, including `u-photo`, `u-url`, `p-locality`/`p-country-name`, and `p-note`.
## Open typefaces
Indigo uses a combination of three beautiful typefaces to render your words.
- [Fira Sans][fira-sans] for heading text
- [Charter][charter] for body text
- [Fira Code][fira-code] for monospaced text
Licenses are included in the themes `static/fonts` folder.
Have a look at a couple of paragraphs of placeholder text using the wonderfully readable Charter:
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer eleifend nulla ac elit venenatis posuere. Sed id aliquam arcu, et malesuada lectus. **Donec et dignissim massa. Pellentesque in laoreet nibh. Pellentesque sagittis, libero quis vestibulum aliquam, ante risus imperdiet magna, at ornare dolor libero quis nunc.** Donec quis tempus purus. Cras ornare magna ac facilisis tristique. Nulla aliquet purus quis massa rutrum interdum ac at magna. Cras fermentum magna id orci viverra facilisis. Ut vitae lobortis nisl.
Sed interdum tincidunt venenatis. Sed hendrerit dictum nisi, at dignissim orci consectetur quis. Aenean sed nisl et nisl placerat euismod. Proin hendrerit nulla at rhoncus molestie. Cras eu gravida erat, vestibulum ornare diam. _Praesent nunc arcu, ultrices et risus sed, dictum mattis dui. Maecenas vitae nisl at massa porta pellentesque_. Donec eget urna eget nisl imperdiet scelerisque eget a mauris. Nam fringilla sem id vehicula rhoncus. Curabitur tincidunt massa mauris, facilisis placerat odio eleifend sit amet. Etiam nec vehicula sapien, at dignissim risus. Sed elit erat, lacinia eu vulputate at, semper eu nulla. Quisque a urna sed nulla viverra egestas nec quis nunc. Curabitur iaculis elit in orci sollicitudin suscipit.
---
And code snippets look great with Fira Code:
```
<article>
<header>
{{ if .Title }}
<h2 class="list-title"><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
{{ end }}
<p class="list-post-date">
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}">
{{ .PublishDate.Format "2 January, 2006 at 15:04 MST" }}
</time>
</p>
</header>
<div>
{{ .Summary | plainify | safeHTML }}
</div>
{{ if .Truncated }}
<p><a class="read-more" href="{{ .Permalink }}">Read more &rarr;</a></p>
{{ end }}
</article>
```
## Contributions welcome
Indigo is distributed under the [MIT license][license], so feel free to fork the repository and make it your own! If you've got ideas on how to improve the theme, let me know by [opening an issue in GitHub](issue) — but please be sure to review the documentation on [contributing][contributing].
[hugo]: https://gohugo.io
[indieweb]: https://indieweb.org
[indieauth]: https://indieauth.com
[why]: https://indieweb.org/why
[mf2]: http://microformats.org
[fira-sans]: https://bboxtype.com/typefaces/FiraSans/#!layout=specimen
[charter]: https://practicaltypography.com/charter.html
[fira-code]: https://github.com/tonsky/FiraCode
[license]: https://github.com/AngeloStavrow/indigo/blob/master/LICENSE.md
[issue]: https://github.com/AngeloStavrow/indigo/issues
[contributing]: https://github.com/AngeloStavrow/indigo/blob/master/CONTRIBUTING.md

Some files were not shown because too many files have changed in this diff Show More