Пример #1
0
    def test_correlation_with_properties_raises_validation_error(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "properties",
            # "funnel_correlation_names": ["$browser"], missing value
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        _create_person(distinct_ids=[f"user_1"],
                       team_id=self.team.pk,
                       properties={"$browser": "Positive"})
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_1",
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="rick",
            distinct_id=f"user_1",
            timestamp="2020-01-03T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="paid",
            distinct_id=f"user_1",
            timestamp="2020-01-04T14:00:00Z",
        )

        with self.assertRaises(ValidationError):
            correlation._run()

        filter = filter.with_data(
            {"funnel_correlation_type": "event_with_properties"})
        # missing "funnel_correlation_event_names": ["rick"],
        with self.assertRaises(ValidationError):
            FunnelCorrelation(filter, self.team)._run()
Пример #2
0
    def test_funnel_correlation_with_event_properties(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "event_with_properties",
            "funnel_correlation_event_names":
            ["positively_related", "negatively_related"],
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="positively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                    properties={
                        "signup_source": "facebook" if i % 4 == 0 else "email",
                        "blah": "value_bleh"
                    },
                )
                # source: email occurs only twice, so would be discarded from result set
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(10, 20):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                    properties={
                        "signup_source": "shazam" if i % 6 == 0 else "email"
                    },
                )
                # source: shazam occurs only once, so would be discarded from result set

        result = correlation._run()[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore
        expected_odds_ratios = [11, 5.5, 2 / 11]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": "positively_related::blah::value_bleh",
                    "success_count": 5,
                    "failure_count": 0,
                    # "odds_ratio": 11.0,
                    "correlation_type": "success",
                },
                {
                    "event": "positively_related::signup_source::facebook",
                    "success_count": 3,
                    "failure_count": 0,
                    # "odds_ratio": 5.5,
                    "correlation_type": "success",
                },
                {
                    "event": "negatively_related::signup_source::email",
                    "success_count": 0,
                    "failure_count": 3,
                    # "odds_ratio": 0.18181818181818182,
                    "correlation_type": "failure",
                },
            ],
        )

        self.assertEqual(
            len(
                self._get_people_for_event(filter, "positively_related",
                                           {"blah": "value_bleh"})), 5)
        self.assertEqual(
            len(
                self._get_people_for_event(filter, "positively_related",
                                           {"signup_source": "facebook"})), 3)
        self.assertEqual(
            len(
                self._get_people_for_event(filter, "positively_related",
                                           {"signup_source": "facebook"},
                                           False)), 0)
        self.assertEqual(
            len(
                self._get_people_for_event(filter, "negatively_related",
                                           {"signup_source": "email"}, False)),
            3)
Пример #3
0
    def test_events_within_conversion_window_for_correlation(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "funnel_window_interval":
            "10",
            "funnel_window_interval_unit":
            "minute",
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "events",
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        _create_person(distinct_ids=["user_successful"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id="user_successful",
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="positively_related",
            distinct_id="user_successful",
            timestamp="2020-01-02T14:02:00Z",
        )
        _create_event(
            team=self.team,
            event="paid",
            distinct_id="user_successful",
            timestamp="2020-01-02T14:06:00Z",
        )

        _create_person(distinct_ids=["user_dropoff"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id="user_dropoff",
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="NOT_negatively_related",
            distinct_id="user_dropoff",
            timestamp=
            "2020-01-02T14:15:00Z",  # event happened outside conversion window
        )

        result = correlation._run()[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore
        expected_odds_ratios = [4]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": "positively_related",
                    "success_count": 1,
                    "failure_count": 0,
                    # "odds_ratio": 4.0,
                    "correlation_type": "success",
                },
            ],
        )
Пример #4
0
    def test_discarding_insignificant_events(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "events",
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="positively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )
            if i % 10 == 0:
                _create_event(
                    team=self.team,
                    event="low_sig_positively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:20:00Z",
                )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(10, 20):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )
            if i % 5 == 0:
                _create_event(
                    team=self.team,
                    event="low_sig_negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )

        #  Total 10 positive, 10 negative
        # low sig count = 1 and 2, high sig count >= 5
        # Thus, to discard the low sig count, % needs to be >= 10%, or count >= 2

        # Discard both due to %
        FunnelCorrelation.MIN_PERSON_PERCENTAGE = 0.11
        FunnelCorrelation.MIN_PERSON_COUNT = 25
        result = correlation._run()[0]
        self.assertEqual(len(result), 2)
Пример #5
0
    def test_correlation_with_multiple_properties(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "properties",
            "funnel_correlation_names": ["$browser", "$nice"],
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        #  5 successful people with both properties
        for i in range(5):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={
                               "$browser": "Positive",
                               "$nice": "very"
                           })
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        #  10 successful people with some different properties
        for i in range(5, 15):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={
                               "$browser": "Positive",
                               "$nice": "not"
                           })
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        # 5 Unsuccessful people with some common properties
        for i in range(15, 20):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={
                               "$browser": "Negative",
                               "$nice": "smh"
                           })
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )

        # One Positive with failure, no $nice property
        _create_person(distinct_ids=[f"user_fail"],
                       team_id=self.team.pk,
                       properties={"$browser": "Positive"})
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_fail",
            timestamp="2020-01-02T14:00:00Z",
        )

        # One Negative with success, no $nice property
        _create_person(distinct_ids=[f"user_succ"],
                       team_id=self.team.pk,
                       properties={"$browser": "Negative"})
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_succ",
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="paid",
            distinct_id=f"user_succ",
            timestamp="2020-01-04T14:00:00Z",
        )

        result = correlation._run()[0]

        # Success Total = 5 + 10 + 1 = 16
        # Failure Total = 5 + 1 = 6
        # Add 1 for priors

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore
        expected_odds_ratios = [
            (16 / 2) * ((7 - 1) / (17 - 15)),
            (11 / 1) * ((7 - 0) / (17 - 10)),
            (6 / 1) * ((7 - 0) / (17 - 5)),
            (1 / 6) * ((7 - 5) / (17 - 0)),
            (2 / 6) * ((7 - 5) / (17 - 1)),
            (2 / 2) * ((7 - 1) / (17 - 1)),
        ]
        # (success + 1) / (failure + 1)

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        expected_result = [
            {
                "event": "$browser::Positive",
                "success_count": 15,
                "failure_count": 1,
                # "odds_ratio": 24,
                "correlation_type": "success",
            },
            {
                "event": "$nice::not",
                "success_count": 10,
                "failure_count": 0,
                # "odds_ratio": 11,
                "correlation_type": "success",
            },
            {
                "event": "$nice::very",
                "success_count": 5,
                "failure_count": 0,
                # "odds_ratio": 3.5,
                "correlation_type": "success",
            },
            {
                "event": "$nice::smh",
                "success_count": 0,
                "failure_count": 5,
                # "odds_ratio": 0.0196078431372549,
                "correlation_type": "failure",
            },
            {
                "event": "$browser::Negative",
                "success_count": 1,
                "failure_count": 5,
                # "odds_ratio": 0.041666666666666664,
                "correlation_type": "failure",
            },
            {
                "event": "$nice::",
                "success_count": 1,
                "failure_count": 1,
                # "odds_ratio": 0.375,
                "correlation_type": "failure",
            },
        ]

        self.assertEqual(result, expected_result)

        # _run property correlation with filter on all properties
        filter = filter.with_data({"funnel_correlation_names": ["$all"]})
        correlation = FunnelCorrelation(filter, self.team)

        new_result = correlation._run()[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in new_result]  # type: ignore

        new_expected_odds_ratios = expected_odds_ratios[:-1]
        new_expected_result = expected_result[:-1]
        # When querying all properties, we don't consider properties that don't exist for part of the data
        # since users aren't explicitly asking for that property. Thus,
        # We discard $nice:: because it's an empty result set

        for odds, expected_odds in zip(odds_ratios, new_expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(new_result, new_expected_result)

        filter = filter.with_data(
            {"funnel_correlation_exclude_names": ["$browser"]})
        # search for $all but exclude $browser
        correlation = FunnelCorrelation(filter, self.team)

        new_result = correlation._run()[0]
        odds_ratios = [item.pop("odds_ratio")
                       for item in new_result]  # type: ignore

        new_expected_odds_ratios = expected_odds_ratios[
            1:4]  # choosing the $nice property values
        new_expected_result = expected_result[1:4]

        for odds, expected_odds in zip(odds_ratios, new_expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(new_result, new_expected_result)
Пример #6
0
    def test_basic_funnel_correlation_with_events(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "events",
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="positively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(10, 20):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )

        result = correlation._run()[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore
        expected_odds_ratios = [11, 1 / 11]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": "positively_related",
                    "success_count": 5,
                    "failure_count": 0,
                    # "odds_ratio": 11.0,
                    "correlation_type": "success",
                },
                {
                    "event": "negatively_related",
                    "success_count": 0,
                    "failure_count": 5,
                    # "odds_ratio": 1 / 11,
                    "correlation_type": "failure",
                },
            ],
        )

        self.assertEqual(
            len(self._get_people_for_event(filter, "positively_related")), 5)
        self.assertEqual(
            len(
                self._get_people_for_event(filter,
                                           "positively_related",
                                           success=False)), 0)
        self.assertEqual(
            len(
                self._get_people_for_event(filter,
                                           "negatively_related",
                                           success=False)), 5)
        self.assertEqual(
            len(self._get_people_for_event(filter, "negatively_related")), 0)

        # Now exclude positively_related
        filter = filter.with_data(
            {"funnel_correlation_exclude_event_names": ["positively_related"]})
        correlation = FunnelCorrelation(filter, self.team)

        result = correlation._run()[0]

        odds_ratio = result[0].pop("odds_ratio")  # type: ignore
        expected_odds_ratio = 1 / 11

        self.assertAlmostEqual(odds_ratio, expected_odds_ratio)

        self.assertEqual(
            result,
            [
                {
                    "event": "negatively_related",
                    "success_count": 0,
                    "failure_count": 5,
                    # "odds_ratio": 1 / 11,
                    "correlation_type": "failure",
                },
            ],
        )
        # Getting specific people isn't affected by exclude_events
        self.assertEqual(
            len(self._get_people_for_event(filter, "positively_related")), 5)
        self.assertEqual(
            len(
                self._get_people_for_event(filter,
                                           "positively_related",
                                           success=False)), 0)
        self.assertEqual(
            len(
                self._get_people_for_event(filter,
                                           "negatively_related",
                                           success=False)), 5)
        self.assertEqual(
            len(self._get_people_for_event(filter, "negatively_related")), 0)
Пример #7
0
    def test_no_divide_by_zero_errors(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        for i in range(2):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Positive"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            # failure count for this event is 0
            _create_event(
                team=self.team,
                event="positive",
                distinct_id=f"user_{i}",
                timestamp="2020-01-03T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(2, 4):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Negative"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                # success count for this event is 0
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )

        results = correlation._run()
        self.assertFalse(results[1])

        result = results[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore
        expected_odds_ratios = [9, 1 / 3]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": "positive",
                    "success_count": 2,
                    "failure_count": 0,
                    # "odds_ratio": 9.0,
                    "correlation_type": "success",
                },
                {
                    "event": "negatively_related",
                    "success_count": 0,
                    "failure_count": 1,
                    # "odds_ratio": 1 / 3,
                    "correlation_type": "failure",
                },
            ],
        )
Пример #8
0
    def test_basic_funnel_correlation_with_properties(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "properties",
            "funnel_correlation_names": ["$browser"],
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Positive"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(10, 20):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Negative"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )

        # One Positive with failure
        _create_person(distinct_ids=[f"user_fail"],
                       team_id=self.team.pk,
                       properties={"$browser": "Positive"})
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_fail",
            timestamp="2020-01-02T14:00:00Z",
        )

        # One Negative with success
        _create_person(distinct_ids=[f"user_succ"],
                       team_id=self.team.pk,
                       properties={"$browser": "Negative"})
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_succ",
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="paid",
            distinct_id=f"user_succ",
            timestamp="2020-01-04T14:00:00Z",
        )

        result = correlation._run()[0]

        odds_ratios = [item.pop("odds_ratio")
                       for item in result]  # type: ignore

        # Success Total = 11, Failure Total = 11
        #
        # Browser::Positive
        # Success: 10
        # Failure: 1

        # Browser::Negative
        # Success: 1
        # Failure: 10

        prior_count = 1
        expected_odds_ratios = [
            ((10 + prior_count) / (1 + prior_count)) *
            ((11 - 1 + prior_count) / (11 - 10 + prior_count)),
            ((1 + prior_count) / (10 + prior_count)) *
            ((11 - 10 + prior_count) / (11 - 1 + prior_count)),
        ]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": "$browser::Positive",
                    "success_count": 10,
                    "failure_count": 1,
                    # "odds_ratio": 121/4,
                    "correlation_type": "success",
                },
                {
                    "event": "$browser::Negative",
                    "success_count": 1,
                    "failure_count": 10,
                    # "odds_ratio": 4/121,
                    "correlation_type": "failure",
                },
            ],
        )
Пример #9
0
    def test_funnel_correlation_with_event_properties_autocapture(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "event_with_properties",
            "funnel_correlation_event_names": ["$autocapture"],
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        # Need a minimum of 3 hits to get a correlation result
        for i in range(6):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="$autocapture",
                distinct_id=f"user_{i}",
                elements=[
                    Element(nth_of_type=1,
                            nth_child=0,
                            tag_name="a",
                            href="/movie")
                ],
                timestamp="2020-01-03T14:00:00Z",
                properties={
                    "signup_source": "email",
                    "$event_type": "click"
                },
            )
            # Test two different types of autocapture elements, with different counts, so we can accurately test results
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="$autocapture",
                    distinct_id=f"user_{i}",
                    elements=[
                        Element(nth_of_type=1,
                                nth_child=0,
                                tag_name="button",
                                text="Pay $10")
                    ],
                    timestamp="2020-01-03T14:00:00Z",
                    properties={
                        "signup_source": "facebook",
                        "$event_type": "submit"
                    },
                )

            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        # Atleast one person that fails, to ensure we get results
        _create_person(distinct_ids=[f"user_fail"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_fail",
            timestamp="2020-01-02T14:00:00Z",
        )

        result = correlation._run()[0]

        # $autocapture results only return elements chain
        self.assertEqual(
            result,
            [
                {
                    "event":
                    '$autocapture::elements_chain::click__~~__a:href="/movie"nth-child="0"nth-of-type="1"',
                    "success_count": 6,
                    "failure_count": 0,
                    "odds_ratio": 14.0,
                    "correlation_type": "success",
                },
                {
                    "event":
                    '$autocapture::elements_chain::submit__~~__button:nth-child="0"nth-of-type="1"text="Pay $10"',
                    "success_count": 3,
                    "failure_count": 0,
                    "odds_ratio": 2.0,
                    "correlation_type": "success",
                },
            ],
        )

        self.assertEqual(
            len(
                self._get_people_for_event(filter, "$autocapture",
                                           {"signup_source": "facebook"})), 3)
        self.assertEqual(
            len(
                self._get_people_for_event(filter, "$autocapture",
                                           {"$event_type": "click"})), 6)
        self.assertEqual(
            len(
                self._get_people_for_event(
                    filter,
                    "$autocapture",
                    [
                        {
                            "key": "tag_name",
                            "operator": "exact",
                            "type": "element",
                            "value": "button"
                        },
                        {
                            "key": "text",
                            "operator": "exact",
                            "type": "element",
                            "value": "Pay $10"
                        },
                    ],
                )),
            3,
        )
        self.assertEqual(
            len(
                self._get_people_for_event(
                    filter,
                    "$autocapture",
                    [
                        {
                            "key": "tag_name",
                            "operator": "exact",
                            "type": "element",
                            "value": "a"
                        },
                        {
                            "key": "href",
                            "operator": "exact",
                            "type": "element",
                            "value": "/movie"
                        },
                    ],
                )),
            6,
        )
Пример #10
0
    def test_funnel_correlation_with_event_properties_exclusions(self):
        filters = {
            "events": [
                {
                    "id": "user signed up",
                    "type": "events",
                    "order": 0
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "funnel_correlation_type":
            "event_with_properties",
            "funnel_correlation_event_names": ["positively_related"],
            "funnel_correlation_event_exclude_property_names":
            ["signup_source"],
        }

        filter = Filter(data=filters)
        correlation = FunnelCorrelation(filter, self.team)

        # Need more than 2 events to get a correlation
        for i in range(3):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="positively_related",
                distinct_id=f"user_{i}",
                timestamp="2020-01-03T14:00:00Z",
                properties={
                    "signup_source": "facebook",
                    "blah": "value_bleh"
                },
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        # Atleast one person that fails, to ensure we get results
        _create_person(distinct_ids=[f"user_fail"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_fail",
            timestamp="2020-01-02T14:00:00Z",
        )

        result = correlation._run()[0]
        self.assertEqual(
            result,
            [
                {
                    "event": "positively_related::blah::value_bleh",
                    "success_count": 3,
                    "failure_count": 0,
                    "odds_ratio": 8,
                    "correlation_type": "success",
                },
                #  missing signup_source, as expected
            ],
        )

        self.assertEqual(
            len(
                self._get_people_for_event(filter, "positively_related",
                                           {"blah": "value_bleh"})), 3)

        # If you search for persons with a specific property, even if excluded earlier, you should get them
        self.assertEqual(
            len(
                self._get_people_for_event(filter, "positively_related",
                                           {"signup_source": "facebook"})), 3)