# Interest ranking

Interest weights help customize the ranking to users' interests. If you want to create a ranking expression that relies on interest weights, use `interest` type ranking.

```go label="Go"
response, err := client.Feeds().CreateFeedGroup(context.Background(), &getstream.CreateFeedGroupRequest{
  ID: "myid",
  ActivitySelectors: getstream.PtrTo([]getstream.ActivitySelectorConfig{
    {
      Type: getstream.PtrTo("following"),
    },
  }),
  Ranking: &getstream.RankingConfig{
    Type:  getstream.PtrTo("interest"),
    Score: getstream.PtrTo("interest_score * popularity"),
  },
})

if err != nil {
  log.Fatal(err)
}
```

`interest_score` is computed by combining activity topics and the specific user's interests. Each of the activity's `interest_tags` that matches one of the user's interests adds half of that interest's weight, and the total is clamped to between -1 and 1. A single matching tag with weight `1.0` gives `0.5`, and tags with a weight of `0` or below pull the score down. The score is `0` when the activity has no `interest_tags` or none of them match. `interest_score` is only computed with `interest` type ranking; with `expression` ranking it is always `0`.

## Activity topics

The topic of an activity can be computed automatically using [activity processors](https://getstream.io/activity-feeds/docs/go-golang/activity-processors/) or by [setting the `interest_tags` field](https://getstream.io/activity-feeds/docs/go-golang/activities/#overview-of-all-activity-fields) via the Stream API.

## User interests

A user's interests are computed automatically by the Stream API from the `interest_tags` on activities the user has reacted to, directly or through a comment. Recent reactions count more: each reaction's contribution halves every 30 days. The user's strongest computed tag has weight `1.0`, and the other computed tags get a proportional weight between 0 and 1. When ranking with `interest` type, the top five tags with a positive weight are used, plus every tag with a weight of `0` or below as a penalty. You can also seed and manage a user's interests yourself, see the [User interests](https://getstream.io/activity-feeds/docs/go-golang/user-interests/) guide.

You can also pass `interest_weights` when reading the feed. These weights are **merged** with the user's stored interests (computed and manual) rather than replacing them:

- Tags that appear only in the stored interests or only in `interest_weights` both contribute to `interest_score`.
- If the same tag appears in both, the value from `interest_weights` is used (an explicit override for that tag).
- If you omit `interest_weights` or pass an empty map, ranking uses only the user's stored interests.
- Set `overwrite_interest_weights: true` to replace the stored interests with `interest_weights` for that request instead of merging. The flag has no effect when `interest_weights` is empty.

```go label="Go"
ctx := context.Background()
timeline := client.Feeds().Feed("timeline", "john")
timelineResponse, err := timeline.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
  InterestWeights: getstream.PtrTo(map[string]float64{
    "travel":   1.0,
    "food":     0.5,
    "exercise": -1.0,
  }),
  UserID: getstream.PtrTo("john"),
})

if err != nil {
  log.Fatal(err)
}
```

Use interest weights between -1 and 1, where 1 means a user is very interested in a topic and -1 means they dislike it. Values outside this range are not rejected, but `interest_score` is still clamped to between -1 and 1.

## Preference score

`preference_score` reflects how much an activity matches the user's preferences based on [activity feedback](https://getstream.io/activity-feeds/docs/go-golang/activity-feedback/) (show more/less). For each of the activity's `interest_tags`, it counts the user's show-more votes minus show-less votes on that tag, divides the total by 3 and clamps it to between -1 and 1. It is `0` when the activity has no `interest_tags` or the user has given no feedback on them.

In the `foryou` feed group, activities whose `interest_tags` have collected strong negative feedback are also removed from the feed: at least 3 show-less votes on the activity's tags with more show-less than show-more votes, or a net of 3 or more show-less votes. Other feed groups don't remove activities based on show more/less feedback, but can still use `preference_score`.

You can use `preference_score` in your ranking expressions with both `expression` and `interest` type ranking to boost activities that match user preferences:

```go label="Go"
// Using preference_score with expression type
response, err := client.Feeds().CreateFeedGroup(context.Background(), &getstream.CreateFeedGroupRequest{
  ID: "myid",
  ActivitySelectors: getstream.PtrTo([]getstream.ActivitySelectorConfig{
    {
      Type: getstream.PtrTo("following"),
    },
  }),
  Ranking: &getstream.RankingConfig{
    Type:  getstream.PtrTo("expression"),
    Score: getstream.PtrTo("preference_score * popularity"),
  },
})

// Using preference_score with interest type
response, err = client.Feeds().CreateFeedGroup(context.Background(), &getstream.CreateFeedGroupRequest{
  ID: "myid_interest",
  ActivitySelectors: getstream.PtrTo([]getstream.ActivitySelectorConfig{
    {
      Type: getstream.PtrTo("following"),
    },
  }),
  Ranking: &getstream.RankingConfig{
    Type:  getstream.PtrTo("interest"),
    Score: getstream.PtrTo("preference_score * interest_score * popularity"),
  },
})

if err != nil {
  log.Fatal(err)
}
```

See [Activity feedback](https://getstream.io/activity-feeds/docs/go-golang/activity-feedback/) for more information on how users can provide feedback that affects `preference_score`.

---

For the most recent version of this documentation, visit [https://getstream.io/activity-feeds/docs/go-golang/interest-ranking/](https://getstream.io/activity-feeds/docs/go-golang/interest-ranking/).