<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def expected_number_of_transactions_in_first_n_periods(self, n):
 r""" Return expected number of transactions in first n n_periods. Expected number of transactions occurring across first n transaction opportunities. Used by Fader and Hardie to assess in-sample fit. .. math:: Pr(X(n) = x| \alpha, \beta, \gamma, \delta) See (7) in Fader & Hardie 2010. Parameters n: float number of transaction opportunities Returns ------- DataFrame: Predicted values, indexed by x """

        params = self._unload_params("alpha", "beta", "gamma", "delta")
        alpha, beta, gamma, delta = params

        x_counts = self.data.groupby("frequency")["weights"].sum()
        x = np.asarray(x_counts.index)

        p1 = binom(n, x) * exp(
            betaln(alpha + x, beta + n - x) - betaln(alpha, beta) + betaln(gamma, delta + n) - betaln(gamma, delta)
        )

        I = np.arange(x.min(), n)

        @np.vectorize
        def p2(j, x):
            i = I[int(j) :]
            return np.sum(
                binom(i, x)
                * exp(
                    betaln(alpha + x, beta + i - x)
                    - betaln(alpha, beta)
                    + betaln(gamma + 1, delta + i)
                    - betaln(gamma, delta)
                )
            )

        p1 += np.fromfunction(p2, (x.shape[0],), x=x)

        idx = pd.Index(x, name="frequency")
        return DataFrame(p1 * x_counts.sum(), index=idx, columns=["model"])